mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-22 10:39:41 +00:00
Merge branch 'master' of gitlab.com:openmw/openmw into fix_global_iteration
This commit is contained in:
commit
c8eaa5976a
60 changed files with 7909 additions and 443 deletions
|
@ -172,6 +172,20 @@ Clang_Format:
|
|||
- CI/check_file_names.sh
|
||||
- CI/check_clang_format.sh
|
||||
|
||||
Lupdate:
|
||||
extends: .Ubuntu_Image
|
||||
stage: checks
|
||||
cache:
|
||||
key: Ubuntu_lupdate.ubuntu_22.04.v1
|
||||
paths:
|
||||
- apt-cache/
|
||||
variables:
|
||||
LUPDATE: lupdate
|
||||
before_script:
|
||||
- CI/install_debian_deps.sh openmw-qt-translations
|
||||
script:
|
||||
- CI/check_qt_translations.sh
|
||||
|
||||
Teal:
|
||||
stage: checks
|
||||
extends: .Ubuntu_Image
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
Bug #5129: Stuttering animation on Centurion Archer
|
||||
Bug #5280: Unskinned shapes in skinned equipment are rendered in the wrong place
|
||||
Bug #5371: Keyframe animation tracks are used for any file that begins with an X
|
||||
Bug #5413: Enemies do a battlecry everytime the player summons a creature
|
||||
Bug #5714: Touch spells cast using ExplodeSpell don't always explode
|
||||
Bug #5849: Paralysis breaks landing
|
||||
Bug #5870: Disposing of actors who were selected in the console doesn't deselect them like vanilla
|
||||
|
@ -37,6 +38,7 @@
|
|||
Bug #6402: The sound of a thunderstorm does not stop playing after entering the premises
|
||||
Bug #6427: Enemy health bar disappears before damaging effect ends
|
||||
Bug #6550: Cloned body parts don't inherit texture effects
|
||||
Bug #6574: Crash at far away from world origin coordinates
|
||||
Bug #6645: Enemy block sounds align with animation instead of blocked hits
|
||||
Bug #6657: Distant terrain tiles become black when using FWIW mod
|
||||
Bug #6661: Saved games that have no preview screenshot cause issues or crashes
|
||||
|
@ -132,6 +134,7 @@
|
|||
Bug #7758: Water walking is not taken into account to compute path cost on the water
|
||||
Bug #7761: Rain and ambient loop sounds are mutually exclusive
|
||||
Bug #7765: OpenMW-CS: Touch Record option is broken
|
||||
Bug #7769: Sword of the Perithia: Broken NPCs
|
||||
Bug #7770: Sword of the Perithia: Script execution failure
|
||||
Bug #7780: Non-ASCII texture paths in NIF files don't work
|
||||
Bug #7785: OpenMW-CS initialising Skill and Attribute fields to 0 instead of -1 on non-FortifyStat spells
|
||||
|
@ -143,6 +146,7 @@
|
|||
Feature #6149: Dehardcode Lua API_REVISION
|
||||
Feature #6152: Playing music via lua scripts
|
||||
Feature #6188: Specular lighting from point light sources
|
||||
Feature #6411: Support translations in openmw-launcher
|
||||
Feature #6447: Add LOD support to Object Paging
|
||||
Feature #6491: Add support for Qt6
|
||||
Feature #6556: Lua API for sounds
|
||||
|
|
11
CI/check_qt_translations.sh
Executable file
11
CI/check_qt_translations.sh
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/bin/bash -ex
|
||||
|
||||
set -o pipefail
|
||||
|
||||
LUPDATE="${LUPDATE:-lupdate}"
|
||||
|
||||
${LUPDATE:?} apps/wizard -ts files/lang/wizard_*.ts
|
||||
${LUPDATE:?} apps/launcher -ts files/lang/launcher_*.ts
|
||||
${LUPDATE:?} components/contentselector components/process -ts files/lang/components_*.ts
|
||||
|
||||
! (git diff --name-only | grep -q "^") || (echo -e "\033[0;31mBuild a 'translations' CMake target to update Qt localization for these files:\033[0;0m"; git diff --name-only | xargs -i echo -e "\033[0;31m{}\033[0;0m"; exit -1)
|
|
@ -33,9 +33,10 @@ declare -rA GROUPED_DEPS=(
|
|||
libboost-system-dev libboost-iostreams-dev
|
||||
|
||||
libavcodec-dev libavformat-dev libavutil-dev libswscale-dev libswresample-dev
|
||||
libsdl2-dev libqt5opengl5-dev libopenal-dev libunshield-dev libtinyxml-dev
|
||||
libbullet-dev liblz4-dev libpng-dev libjpeg-dev libluajit-5.1-dev
|
||||
librecast-dev libsqlite3-dev ca-certificates libicu-dev libyaml-cpp-dev
|
||||
libsdl2-dev libqt5opengl5-dev qttools5-dev qttools5-dev-tools libopenal-dev
|
||||
libunshield-dev libtinyxml-dev libbullet-dev liblz4-dev libpng-dev libjpeg-dev
|
||||
libluajit-5.1-dev librecast-dev libsqlite3-dev ca-certificates libicu-dev
|
||||
libyaml-cpp-dev
|
||||
"
|
||||
|
||||
# These dependencies can alternatively be built and linked statically.
|
||||
|
@ -99,6 +100,12 @@ declare -rA GROUPED_DEPS=(
|
|||
clang-format-14
|
||||
git-core
|
||||
"
|
||||
|
||||
[openmw-qt-translations]="
|
||||
qttools5-dev
|
||||
qttools5-dev-tools
|
||||
git-core
|
||||
"
|
||||
)
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
|
|
|
@ -224,9 +224,9 @@ find_package(LZ4 REQUIRED)
|
|||
if (USE_QT)
|
||||
find_package(QT REQUIRED COMPONENTS Core NAMES Qt6 Qt5)
|
||||
if (QT_VERSION_MAJOR VERSION_EQUAL 5)
|
||||
find_package(Qt5 5.15 COMPONENTS Core Widgets Network OpenGL REQUIRED)
|
||||
find_package(Qt5 5.15 COMPONENTS Core Widgets Network OpenGL LinguistTools REQUIRED)
|
||||
else()
|
||||
find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets REQUIRED)
|
||||
find_package(Qt6 COMPONENTS Core Widgets Network OpenGL OpenGLWidgets LinguistTools REQUIRED)
|
||||
endif()
|
||||
message(STATUS "Using Qt${QT_VERSION}")
|
||||
endif()
|
||||
|
@ -1074,3 +1074,57 @@ if (DOXYGEN_FOUND)
|
|||
WORKING_DIRECTORY ${OpenMW_BINARY_DIR}
|
||||
COMMENT "Generating documentation for the github-pages at ${DOXYGEN_PAGES_OUTPUT_DIR}" VERBATIM)
|
||||
endif ()
|
||||
|
||||
# Qt localization
|
||||
if (USE_QT)
|
||||
file(GLOB LAUNCHER_TS_FILES ${CMAKE_SOURCE_DIR}/files/lang/launcher_*.ts)
|
||||
file(GLOB WIZARD_TS_FILES ${CMAKE_SOURCE_DIR}/files/lang/wizard_*.ts)
|
||||
file(GLOB COMPONENTS_TS_FILES ${CMAKE_SOURCE_DIR}/files/lang/components_*.ts)
|
||||
get_target_property(QT_LUPDATE_EXECUTABLE Qt::lupdate IMPORTED_LOCATION)
|
||||
add_custom_target(translations
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/components/contentselector ${CMAKE_SOURCE_DIR}/components/process -ts ${COMPONENTS_TS_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/components
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/apps/wizard -ts ${WIZARD_TS_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/wizard
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS
|
||||
|
||||
COMMAND ${QT_LUPDATE_EXECUTABLE} ${CMAKE_SOURCE_DIR}/apps/launcher -ts ${LAUNCHER_TS_FILES}
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/apps/launcher
|
||||
VERBATIM
|
||||
COMMAND_EXPAND_LISTS)
|
||||
|
||||
if (BUILD_LAUNCHER OR BUILD_WIZARD)
|
||||
if (APPLE)
|
||||
set(QT_TRANSLATIONS_PATH "${APP_BUNDLE_DIR}/Contents/Resources/resources/translations")
|
||||
else ()
|
||||
get_generator_is_multi_config(multi_config)
|
||||
if (multi_config)
|
||||
set(QT_TRANSLATIONS_PATH "${OpenMW_BINARY_DIR}/$<CONFIG>/resources/translations")
|
||||
else ()
|
||||
set(QT_TRANSLATIONS_PATH "${OpenMW_BINARY_DIR}/resources/translations")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
file(GLOB TS_FILES ${COMPONENTS_TS_FILES})
|
||||
|
||||
if (BUILD_LAUNCHER)
|
||||
set(TS_FILES ${TS_FILES} ${LAUNCHER_TS_FILES})
|
||||
endif ()
|
||||
|
||||
if (BUILD_WIZARD)
|
||||
set(TS_FILES ${TS_FILES} ${WIZARD_TS_FILES})
|
||||
endif ()
|
||||
|
||||
qt_add_translation(QM_FILES ${TS_FILES} OPTIONS -silent)
|
||||
|
||||
add_custom_target(qm-files
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${QT_TRANSLATIONS_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QM_FILES} ${QT_TRANSLATIONS_PATH}
|
||||
DEPENDS ${QM_FILES}
|
||||
COMMENT "Copy *.qm files to resources folder")
|
||||
endif ()
|
||||
endif()
|
||||
|
|
|
@ -76,10 +76,6 @@ namespace
|
|||
bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive")->multitoken()->composing(),
|
||||
"set fallback BSA archives (later archives have higher priority)");
|
||||
|
||||
addOption("resources",
|
||||
bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"),
|
||||
"set resources directory");
|
||||
|
||||
addOption("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")->multitoken()->composing(),
|
||||
"content file(s): esm/esp, or omwgame/omwaddon/omwscripts");
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ openmw_add_executable(openmw-launcher
|
|||
${UI_HDRS}
|
||||
)
|
||||
|
||||
add_dependencies(openmw-launcher qm-files)
|
||||
|
||||
if (WIN32)
|
||||
INSTALL(TARGETS openmw-launcher RUNTIME DESTINATION ".")
|
||||
endif (WIN32)
|
||||
|
|
|
@ -308,7 +308,7 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
|||
// Display new content with custom formatting
|
||||
if (mNewDataDirs.contains(canonicalDirPath))
|
||||
{
|
||||
tooltip += "Will be added to the current profile\n";
|
||||
tooltip += tr("Will be added to the current profile");
|
||||
QFont font = item->font();
|
||||
font.setBold(true);
|
||||
font.setItalic(true);
|
||||
|
@ -326,7 +326,10 @@ void Launcher::DataFilesPage::populateFileViews(const QString& contentModelName)
|
|||
if (mSelector->containsDataFiles(currentDir))
|
||||
{
|
||||
item->setIcon(QIcon(":/images/openmw-plugin.png"));
|
||||
tooltip += "Contains content file(s)";
|
||||
if (!tooltip.isEmpty())
|
||||
tooltip += "\n";
|
||||
|
||||
tooltip += tr("Contains content file(s)");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <components/debug/debugging.hpp>
|
||||
#include <components/files/configurationmanager.hpp>
|
||||
#include <components/files/qtconversion.hpp>
|
||||
#include <components/platform/platform.hpp>
|
||||
|
||||
#ifdef MAC_OS_X_VERSION_MIN_REQUIRED
|
||||
|
@ -34,13 +35,23 @@ int runLauncher(int argc, char* argv[])
|
|||
{
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QString resourcesPath(".");
|
||||
if (!variables["resources"].empty())
|
||||
{
|
||||
resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string());
|
||||
}
|
||||
|
||||
// Internationalization
|
||||
QString locale = QLocale::system().name().section('_', 0, 0);
|
||||
|
||||
QTranslator appTranslator;
|
||||
appTranslator.load(":/translations/" + locale + ".qm");
|
||||
appTranslator.load(resourcesPath + "/translations/launcher_" + locale + ".qm");
|
||||
app.installTranslator(&appTranslator);
|
||||
|
||||
QTranslator componentsAppTranslator;
|
||||
componentsAppTranslator.load(resourcesPath + "/translations/components_" + locale + ".qm");
|
||||
app.installTranslator(&componentsAppTranslator);
|
||||
|
||||
Launcher::MainDialog mainWin(configurationManager);
|
||||
|
||||
Launcher::FirstRunDialogResult result = mainWin.showFirstRunDialog();
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>720</width>
|
||||
<width>750</width>
|
||||
<height>635</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>720</width>
|
||||
<width>750</width>
|
||||
<height>635</height>
|
||||
</size>
|
||||
</property>
|
||||
|
@ -148,7 +148,7 @@ QToolButton {
|
|||
<string>Display</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Allows to change graphics settings</string>
|
||||
<string>Allows to change display settings</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="settingsAction">
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="allowNPCToFollowOverWaterSurfaceCheckBox">
|
||||
<property name="toolTip">
|
||||
<string>Give actors an ability to swim over the water surface when they follow other actor independently from their ability to swim. Has effect only when nav mesh building is enabled.</string>
|
||||
<string><html><head/><body><p>Give actors an ability to swim over the water surface when they follow other actor independently from their ability to swim. Has effect only when nav mesh building is enabled.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Always allow actors to follow over water</string>
|
||||
|
@ -206,7 +206,7 @@
|
|||
<item row="5" column="1">
|
||||
<widget class="QCheckBox" name="classicReflectedAbsorbSpellsCheckBox">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Effects of reflected Absorb spells are not mirrored -- like in Morrowind.</p></body></html></string>
|
||||
<string><html><head/><body><p>Effects of reflected Absorb spells are not mirrored - like in Morrowind.</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Classic reflected Absorb spells behavior</string>
|
||||
|
|
|
@ -88,10 +88,6 @@ namespace NavMeshTool
|
|||
->composing(),
|
||||
"set fallback BSA archives (later archives have higher priority)");
|
||||
|
||||
addOption("resources",
|
||||
bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"),
|
||||
"set resources directory");
|
||||
|
||||
addOption("content",
|
||||
bpo::value<StringsVector>()->default_value(StringsVector(), "")->multitoken()->composing(),
|
||||
"content file(s): esm/esp, or omwgame/omwaddon/omwscripts");
|
||||
|
|
|
@ -119,8 +119,6 @@ boost::program_options::variables_map CS::Editor::readConfiguration()
|
|||
boost::program_options::value<Files::MaybeQuotedPathContainer::value_type>()->default_value(
|
||||
Files::MaybeQuotedPathContainer::value_type(), ""));
|
||||
addOption("encoding", boost::program_options::value<std::string>()->default_value("win1252"));
|
||||
addOption("resources",
|
||||
boost::program_options::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"));
|
||||
addOption("fallback-archive",
|
||||
boost::program_options::value<std::vector<std::string>>()
|
||||
->default_value(std::vector<std::string>(), "fallback-archive")
|
||||
|
|
|
@ -56,6 +56,7 @@ namespace MWBase
|
|||
virtual void newGameStarted() = 0;
|
||||
virtual void gameLoaded() = 0;
|
||||
virtual void gameEnded() = 0;
|
||||
virtual void noGame() = 0;
|
||||
virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void objectRemovedFromScene(const MWWorld::Ptr& ptr) = 0;
|
||||
virtual void objectTeleported(const MWWorld::Ptr& ptr) = 0;
|
||||
|
|
|
@ -110,7 +110,9 @@ namespace MWBase
|
|||
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;
|
||||
virtual void startCombat(
|
||||
const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, const std::set<MWWorld::Ptr>* targetAllies)
|
||||
= 0;
|
||||
|
||||
/// Removes an actor and its allies from combat with the actor's targets.
|
||||
virtual void stopCombat(const MWWorld::Ptr& ptr) = 0;
|
||||
|
|
|
@ -375,12 +375,18 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
|
|||
return mChoice;
|
||||
|
||||
case SelectWrapper::Function_AiSetting:
|
||||
{
|
||||
int argument = select.getArgument();
|
||||
if (argument < 0 || argument > 3)
|
||||
{
|
||||
throw std::runtime_error("AiSetting index is out of range");
|
||||
}
|
||||
|
||||
return mActor.getClass()
|
||||
.getCreatureStats(mActor)
|
||||
.getAiSetting((MWMechanics::AiSetting)select.getArgument())
|
||||
.getAiSetting(static_cast<MWMechanics::AiSetting>(argument))
|
||||
.getModified(false);
|
||||
|
||||
}
|
||||
case SelectWrapper::Function_PcAttribute:
|
||||
{
|
||||
ESM::RefId attribute = ESM::Attribute::indexToRefId(select.getArgument());
|
||||
|
|
|
@ -344,18 +344,19 @@ namespace MWLua
|
|||
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos) {
|
||||
auto model = getStaticModelOrThrow(staticOrID);
|
||||
context.mLuaManager->addAction(
|
||||
[world, model, worldPos]() { world->spawnEffect(model, "", worldPos); }, "openmw.vfx.spawn");
|
||||
[world, model = std::move(model), worldPos]() { world->spawnEffect(model, "", worldPos); },
|
||||
"openmw.vfx.spawn");
|
||||
},
|
||||
[world, context](const sol::object& staticOrID, const osg::Vec3f& worldPos, const sol::table& options) {
|
||||
auto model = getStaticModelOrThrow(staticOrID);
|
||||
|
||||
bool magicVfx = options.get_or("mwMagicVfx", true);
|
||||
std::string textureOverride = options.get_or<std::string>("particleTextureOverride", "");
|
||||
std::string texture = options.get_or<std::string>("particleTextureOverride", "");
|
||||
float scale = options.get_or("scale", 1.f);
|
||||
|
||||
context.mLuaManager->addAction(
|
||||
[world, model, textureOverride, worldPos, scale, magicVfx]() {
|
||||
world->spawnEffect(model, textureOverride, worldPos, scale, magicVfx);
|
||||
[world, model = std::move(model), texture = std::move(texture), worldPos, scale, magicVfx]() {
|
||||
world->spawnEffect(model, texture, worldPos, scale, magicVfx);
|
||||
},
|
||||
"openmw.vfx.spawn");
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "corebindings.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm3/loadfact.hpp>
|
||||
|
@ -133,7 +134,14 @@ namespace MWLua
|
|||
sol::table api(context.mLua->sol(), sol::create);
|
||||
for (auto& [k, v] : LuaUtil::getMutableFromReadOnly(initCorePackage(context)))
|
||||
api[k] = v;
|
||||
api["sendGlobalEvent"] = sol::nil;
|
||||
api["sendGlobalEvent"] = [context](std::string eventName, const sol::object& eventData) {
|
||||
if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame)
|
||||
{
|
||||
throw std::logic_error("Can't send global events when no game is loaded");
|
||||
}
|
||||
context.mLuaEvents->addGlobalEvent(
|
||||
{ std::move(eventName), LuaUtil::serialize(eventData, context.mSerializer) });
|
||||
};
|
||||
api["sound"] = sol::nil;
|
||||
api["vfx"] = sol::nil;
|
||||
return LuaUtil::makeReadOnly(api);
|
||||
|
|
|
@ -42,7 +42,7 @@ namespace MWLua
|
|||
ObjectVariant mObject;
|
||||
|
||||
public:
|
||||
ItemData(ObjectVariant object)
|
||||
ItemData(const ObjectVariant& object)
|
||||
: mObject(object)
|
||||
{
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ namespace MWLua
|
|||
item["itemData"] = [](const sol::object& object) -> sol::optional<ItemData> {
|
||||
ObjectVariant o(object);
|
||||
if (o.ptr().getClass().isItem(o.ptr()) || o.ptr().mRef->getType() == ESM::REC_LIGH)
|
||||
return ItemData(std::move(o));
|
||||
return ItemData(o);
|
||||
return {};
|
||||
};
|
||||
|
||||
|
|
|
@ -379,6 +379,12 @@ namespace MWLua
|
|||
mMenuScripts.stateChanged();
|
||||
}
|
||||
|
||||
void LuaManager::noGame()
|
||||
{
|
||||
clear();
|
||||
mMenuScripts.stateChanged();
|
||||
}
|
||||
|
||||
void LuaManager::uiModeChanged(const MWWorld::Ptr& arg)
|
||||
{
|
||||
if (mPlayer.isEmpty())
|
||||
|
@ -643,7 +649,7 @@ namespace MWLua
|
|||
scripts->setSavedDataDeserializer(mLocalSerializer.get());
|
||||
ESM::LuaScripts data;
|
||||
scripts->save(data);
|
||||
localData[id] = data;
|
||||
localData[id] = std::move(data);
|
||||
}
|
||||
|
||||
mMenuScripts.removeAllScripts();
|
||||
|
|
|
@ -70,6 +70,7 @@ namespace MWLua
|
|||
void newGameStarted() override;
|
||||
void gameLoaded() override;
|
||||
void gameEnded() override;
|
||||
void noGame() override;
|
||||
void objectAddedToScene(const MWWorld::Ptr& ptr) override;
|
||||
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
|
||||
void inputEvent(const InputEvent& event) override;
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace MWLua
|
|||
}
|
||||
|
||||
context.mLuaManager->addAction(
|
||||
[=] {
|
||||
[shader, name, values = std::move(values)] {
|
||||
MWBase::Environment::get().getWorld()->getPostProcessor()->setUniform(shader.mShader, name, values);
|
||||
},
|
||||
"SetUniformShaderAction");
|
||||
|
|
|
@ -274,7 +274,8 @@ namespace MWLua
|
|||
{
|
||||
ei = LuaUtil::cast<std::string>(item);
|
||||
}
|
||||
context.mLuaManager->addAction([obj = Object(ptr), ei = ei] { setSelectedEnchantedItem(obj.ptr(), ei); },
|
||||
context.mLuaManager->addAction(
|
||||
[obj = Object(ptr), ei = std::move(ei)] { setSelectedEnchantedItem(obj.ptr(), ei); },
|
||||
"setSelectedEnchantedItemAction");
|
||||
};
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ namespace MWLua
|
|||
// The journal mwscript function has a try function here, we will make the lua function throw an
|
||||
// error. However, the addAction will cause it to error outside of this function.
|
||||
context.mLuaManager->addAction(
|
||||
[actor, q, stage] {
|
||||
[actor = std::move(actor), q, stage] {
|
||||
MWWorld::Ptr actorPtr;
|
||||
if (actor)
|
||||
actorPtr = actor->ptr();
|
||||
|
|
|
@ -241,7 +241,7 @@ namespace MWLua
|
|||
for (unsigned i = 0; i < newStack.size(); ++i)
|
||||
newStack[i] = nameToMode.at(LuaUtil::cast<std::string_view>(modes[i + 1]));
|
||||
luaManager->addAction(
|
||||
[windowManager, newStack, arg]() {
|
||||
[windowManager, newStack = std::move(newStack), arg]() {
|
||||
MWWorld::Ptr ptr;
|
||||
if (arg.has_value())
|
||||
ptr = arg->ptr();
|
||||
|
@ -319,7 +319,7 @@ namespace MWLua
|
|||
};
|
||||
|
||||
auto uiLayer = context.mLua->sol().new_usertype<LuaUi::Layer>("UiLayer");
|
||||
uiLayer["name"] = sol::readonly_property([](LuaUi::Layer& self) { return self.name(); });
|
||||
uiLayer["name"] = sol::readonly_property([](LuaUi::Layer& self) -> std::string_view { return self.name(); });
|
||||
uiLayer["size"] = sol::readonly_property([](LuaUi::Layer& self) { return self.size(); });
|
||||
uiLayer[sol::meta_function::to_string]
|
||||
= [](LuaUi::Layer& self) { return Misc::StringUtils::format("UiLayer(%s)", self.name()); };
|
||||
|
|
|
@ -577,8 +577,8 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void Actors::engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2,
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>& cachedAllies, bool againstPlayer) const
|
||||
void Actors::engageCombat(
|
||||
const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, SidingCache& cachedAllies, bool againstPlayer) const
|
||||
{
|
||||
// No combat for totally static creatures
|
||||
if (!actor1.getClass().isMobile(actor1))
|
||||
|
@ -606,9 +606,7 @@ namespace MWMechanics
|
|||
|
||||
// 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<MWWorld::Ptr> allies1;
|
||||
|
||||
getActorsSidingWith(actor1, allies1, cachedAllies);
|
||||
const std::set<MWWorld::Ptr>& allies1 = cachedAllies.getActorsSidingWith(actor1);
|
||||
|
||||
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
|
||||
|
@ -620,7 +618,7 @@ namespace MWMechanics
|
|||
|
||||
if (creatureStats2.matchesActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId()))
|
||||
{
|
||||
mechanicsManager->startCombat(actor1, actor2);
|
||||
mechanicsManager->startCombat(actor1, actor2, &cachedAllies.getActorsSidingWith(actor2));
|
||||
// Also set the same hit attempt actor. Otherwise, if fighting the player, they may stop combat
|
||||
// if the player gets out of reach, while the ally would continue combat with the player
|
||||
creatureStats1.setHitAttemptActorId(ally.getClass().getCreatureStats(ally).getHitAttemptActorId());
|
||||
|
@ -633,9 +631,8 @@ namespace MWMechanics
|
|||
aggressive = true;
|
||||
}
|
||||
|
||||
std::set<MWWorld::Ptr> playerAllies;
|
||||
MWWorld::Ptr player = MWMechanics::getPlayer();
|
||||
getActorsSidingWith(player, playerAllies, cachedAllies);
|
||||
const std::set<MWWorld::Ptr>& playerAllies = cachedAllies.getActorsSidingWith(player);
|
||||
|
||||
bool isPlayerFollowerOrEscorter = playerAllies.find(actor1) != playerAllies.end();
|
||||
|
||||
|
@ -646,20 +643,17 @@ namespace MWMechanics
|
|||
// Check that actor2 is in combat with actor1
|
||||
if (creatureStats2.getAiSequence().isInCombat(actor1))
|
||||
{
|
||||
std::set<MWWorld::Ptr> allies2;
|
||||
|
||||
getActorsSidingWith(actor2, allies2, cachedAllies);
|
||||
|
||||
const std::set<MWWorld::Ptr>& allies2 = cachedAllies.getActorsSidingWith(actor2);
|
||||
// Check that an ally of actor2 is also in combat with actor1
|
||||
for (const MWWorld::Ptr& ally2 : allies2)
|
||||
{
|
||||
if (ally2 != actor2 && ally2.getClass().getCreatureStats(ally2).getAiSequence().isInCombat(actor1))
|
||||
{
|
||||
mechanicsManager->startCombat(actor1, actor2);
|
||||
mechanicsManager->startCombat(actor1, actor2, &allies2);
|
||||
// Also have actor1's allies start combat
|
||||
for (const MWWorld::Ptr& ally1 : allies1)
|
||||
if (ally1 != player)
|
||||
mechanicsManager->startCombat(ally1, actor2);
|
||||
mechanicsManager->startCombat(ally1, actor2, &allies2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -747,7 +741,7 @@ namespace MWMechanics
|
|||
bool LOS = world->getLOS(actor1, actor2) && mechanicsManager->awarenessCheck(actor2, actor1);
|
||||
|
||||
if (LOS)
|
||||
mechanicsManager->startCombat(actor1, actor2);
|
||||
mechanicsManager->startCombat(actor1, actor2, &cachedAllies.getActorsSidingWith(actor2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1093,7 +1087,7 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const
|
||||
void Actors::updateCrimePursuit(const MWWorld::Ptr& ptr, float duration, SidingCache& cachedAllies) const
|
||||
{
|
||||
const MWWorld::Ptr player = getPlayer();
|
||||
if (ptr == player)
|
||||
|
@ -1133,7 +1127,7 @@ namespace MWMechanics
|
|||
= esmStore.get<ESM::GameSetting>().find("iCrimeThresholdMultiplier")->mValue.getInteger();
|
||||
if (playerStats.getBounty() >= cutoff * iCrimeThresholdMultiplier)
|
||||
{
|
||||
mechanicsManager->startCombat(ptr, player);
|
||||
mechanicsManager->startCombat(ptr, player, &cachedAllies.getActorsSidingWith(player));
|
||||
creatureStats.setHitAttemptActorId(
|
||||
playerClass.getCreatureStats(player)
|
||||
.getActorId()); // Stops the guard from quitting combat if player is unreachable
|
||||
|
@ -1508,8 +1502,7 @@ namespace MWMechanics
|
|||
|
||||
/// \todo move update logic to Actor class where appropriate
|
||||
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>
|
||||
cachedAllies; // will be filled as engageCombat iterates
|
||||
SidingCache cachedAllies{ *this, true }; // will be filled as engageCombat iterates
|
||||
|
||||
const bool aiActive = MWBase::Environment::get().getMechanicsManager()->isAIActive();
|
||||
const int attackedByPlayerId = player.getClass().getCreatureStats(player).getHitAttemptActorId();
|
||||
|
@ -1597,7 +1590,7 @@ namespace MWMechanics
|
|||
updateHeadTracking(actor.getPtr(), mActors, isPlayer, ctrl);
|
||||
|
||||
if (actor.getPtr().getClass().isNpc() && !isPlayer)
|
||||
updateCrimePursuit(actor.getPtr(), duration);
|
||||
updateCrimePursuit(actor.getPtr(), duration, cachedAllies);
|
||||
|
||||
if (!isPlayer)
|
||||
{
|
||||
|
@ -2115,7 +2108,7 @@ namespace MWMechanics
|
|||
for (const auto& package : stats.getAiSequence())
|
||||
{
|
||||
if (excludeInfighting && !sameActor && package->getTypeId() == AiPackageTypeId::Combat
|
||||
&& package->getTarget() == actorPtr)
|
||||
&& package->targetIs(actorPtr))
|
||||
break;
|
||||
if (package->sideWithTarget() && !package->getTarget().isEmpty())
|
||||
{
|
||||
|
@ -2135,7 +2128,7 @@ namespace MWMechanics
|
|||
}
|
||||
list.push_back(package->getTarget());
|
||||
}
|
||||
else if (package->getTarget() == actorPtr)
|
||||
else if (package->targetIs(actorPtr))
|
||||
{
|
||||
list.push_back(iteratedActor);
|
||||
}
|
||||
|
@ -2154,7 +2147,7 @@ namespace MWMechanics
|
|||
std::vector<MWWorld::Ptr> list;
|
||||
forEachFollowingPackage(
|
||||
mActors, actorPtr, getPlayer(), [&](const Actor& actor, const std::shared_ptr<AiPackage>& package) {
|
||||
if (package->followTargetThroughDoors() && package->getTarget() == actorPtr)
|
||||
if (package->followTargetThroughDoors() && package->targetIs(actorPtr))
|
||||
list.push_back(actor.getPtr());
|
||||
else if (package->getTypeId() != AiPackageTypeId::Combat
|
||||
&& package->getTypeId() != AiPackageTypeId::Wander)
|
||||
|
@ -2181,38 +2174,12 @@ namespace MWMechanics
|
|||
getActorsSidingWith(follower, out, excludeInfighting);
|
||||
}
|
||||
|
||||
void Actors::getActorsSidingWith(const MWWorld::Ptr& actor, std::set<MWWorld::Ptr>& out,
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>& cachedAllies) const
|
||||
{
|
||||
// If we have already found actor's allies, use the cache
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>::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))
|
||||
if (out.insert(follower).second && follower != actor)
|
||||
getActorsSidingWith(follower, out, cachedAllies);
|
||||
|
||||
// Cache ptrs and their sets of allies
|
||||
cachedAllies.insert(std::make_pair(actor, out));
|
||||
for (const MWWorld::Ptr& iter : out)
|
||||
{
|
||||
if (iter == actor)
|
||||
continue;
|
||||
search = cachedAllies.find(iter);
|
||||
if (search == cachedAllies.end())
|
||||
cachedAllies.insert(std::make_pair(iter, out));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<int> Actors::getActorsFollowingIndices(const MWWorld::Ptr& actor) const
|
||||
{
|
||||
std::vector<int> list;
|
||||
forEachFollowingPackage(
|
||||
mActors, actor, getPlayer(), [&](const Actor&, const std::shared_ptr<AiPackage>& package) {
|
||||
if (package->followTargetThroughDoors() && package->getTarget() == actor)
|
||||
if (package->followTargetThroughDoors() && package->targetIs(actor))
|
||||
{
|
||||
list.push_back(static_cast<const AiFollow*>(package.get())->getFollowIndex());
|
||||
return false;
|
||||
|
@ -2230,7 +2197,7 @@ namespace MWMechanics
|
|||
std::map<int, MWWorld::Ptr> map;
|
||||
forEachFollowingPackage(
|
||||
mActors, actor, getPlayer(), [&](const Actor& otherActor, const std::shared_ptr<AiPackage>& package) {
|
||||
if (package->followTargetThroughDoors() && package->getTarget() == actor)
|
||||
if (package->followTargetThroughDoors() && package->targetIs(actor))
|
||||
{
|
||||
const int index = static_cast<const AiFollow*>(package.get())->getFollowIndex();
|
||||
map[index] = otherActor.getPtr();
|
||||
|
@ -2405,4 +2372,32 @@ namespace MWMechanics
|
|||
seq.fastForward(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
const std::set<MWWorld::Ptr>& SidingCache::getActorsSidingWith(const MWWorld::Ptr& actor)
|
||||
{
|
||||
// If we have already found actor's allies, use the cache
|
||||
auto search = mCache.find(actor);
|
||||
if (search != mCache.end())
|
||||
return search->second;
|
||||
std::set<MWWorld::Ptr>& out = mCache[actor];
|
||||
for (const MWWorld::Ptr& follower : mActors.getActorsSidingWith(actor, mExcludeInfighting))
|
||||
{
|
||||
if (out.insert(follower).second && follower != actor)
|
||||
{
|
||||
const auto& allies = getActorsSidingWith(follower);
|
||||
out.insert(allies.begin(), allies.end());
|
||||
}
|
||||
}
|
||||
|
||||
// Cache ptrs and their sets of allies
|
||||
for (const MWWorld::Ptr& iter : out)
|
||||
{
|
||||
if (iter == actor)
|
||||
continue;
|
||||
search = mCache.find(iter);
|
||||
if (search == mCache.end())
|
||||
mCache.emplace(iter, out);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace MWMechanics
|
|||
class Actor;
|
||||
class CharacterController;
|
||||
class CreatureStats;
|
||||
class SidingCache;
|
||||
|
||||
class Actors
|
||||
{
|
||||
|
@ -186,7 +187,7 @@ namespace MWMechanics
|
|||
|
||||
void calculateRestoration(const MWWorld::Ptr& ptr, float duration) const;
|
||||
|
||||
void updateCrimePursuit(const MWWorld::Ptr& ptr, float duration) const;
|
||||
void updateCrimePursuit(const MWWorld::Ptr& ptr, float duration, SidingCache& cachedAllies) const;
|
||||
|
||||
void killDeadActors();
|
||||
|
||||
|
@ -198,13 +199,25 @@ namespace MWMechanics
|
|||
@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<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>& cachedAllies, bool againstPlayer) const;
|
||||
void engageCombat(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2, SidingCache& 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<MWWorld::Ptr>& out,
|
||||
std::map<const MWWorld::Ptr, const std::set<MWWorld::Ptr>>& cachedAllies) const;
|
||||
class SidingCache
|
||||
{
|
||||
const Actors& mActors;
|
||||
const bool mExcludeInfighting;
|
||||
std::map<MWWorld::Ptr, std::set<MWWorld::Ptr>> mCache;
|
||||
|
||||
public:
|
||||
SidingCache(const Actors& actors, bool excludeInfighting)
|
||||
: mActors(actors)
|
||||
, mExcludeInfighting(excludeInfighting)
|
||||
{
|
||||
}
|
||||
|
||||
/// Recursive version of getActorsSidingWith that takes, returns a cached set of allies
|
||||
const std::set<MWWorld::Ptr>& getActorsSidingWith(const MWWorld::Ptr& actor);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -270,7 +270,15 @@ namespace MWMechanics
|
|||
{
|
||||
storage.startCombatMove(isRangedCombat, distToTarget, rangeAttack, actor, target);
|
||||
// start new attack
|
||||
storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat);
|
||||
bool canShout = true;
|
||||
ESM::RefId spellId = storage.mCurrentAction->getSpell();
|
||||
if (!spellId.empty())
|
||||
{
|
||||
const ESM::Spell* spell = MWBase::Environment::get().getESMStore()->get<ESM::Spell>().find(spellId);
|
||||
if (spell->mEffects.mList.empty() || spell->mEffects.mList[0].mRange != ESM::RT_Target)
|
||||
canShout = false;
|
||||
}
|
||||
storage.startAttackIfReady(actor, characterController, weapon, isRangedCombat, canShout);
|
||||
}
|
||||
|
||||
// If actor uses custom destination it has to try to rebuild path because environment can change
|
||||
|
@ -635,7 +643,7 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
void AiCombatStorage::startAttackIfReady(const MWWorld::Ptr& actor, CharacterController& characterController,
|
||||
const ESM::Weapon* weapon, bool distantCombat)
|
||||
const ESM::Weapon* weapon, bool distantCombat, bool canShout)
|
||||
{
|
||||
if (mReadyToAttack && characterController.readyToStartAttack())
|
||||
{
|
||||
|
@ -658,12 +666,15 @@ namespace MWMechanics
|
|||
baseDelay = store.get<ESM::GameSetting>().find("fCombatDelayNPC")->mValue.getFloat();
|
||||
}
|
||||
|
||||
// Say a provoking combat phrase
|
||||
const int iVoiceAttackOdds
|
||||
= store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->mValue.getInteger();
|
||||
if (Misc::Rng::roll0to99(prng) < iVoiceAttackOdds)
|
||||
if (canShout)
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->say(actor, ESM::RefId::stringRefId("attack"));
|
||||
// Say a provoking combat phrase
|
||||
const int iVoiceAttackOdds
|
||||
= store.get<ESM::GameSetting>().find("iVoiceAttackOdds")->mValue.getInteger();
|
||||
if (Misc::Rng::roll0to99(prng) < iVoiceAttackOdds)
|
||||
{
|
||||
MWBase::Environment::get().getDialogueManager()->say(actor, ESM::RefId::stringRefId("attack"));
|
||||
}
|
||||
}
|
||||
mAttackCooldown = std::min(baseDelay + 0.01 * Misc::Rng::roll0to99(prng), baseDelay + 0.9);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ namespace MWMechanics
|
|||
void updateCombatMove(float duration);
|
||||
void stopCombatMove();
|
||||
void startAttackIfReady(const MWWorld::Ptr& actor, CharacterController& characterController,
|
||||
const ESM::Weapon* weapon, bool distantCombat);
|
||||
const ESM::Weapon* weapon, bool distantCombat, bool canShout);
|
||||
void updateAttack(const MWWorld::Ptr& actor, CharacterController& characterController);
|
||||
void stopAttack();
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace MWMechanics
|
|||
virtual float getCombatRange(bool& isRanged) const = 0;
|
||||
virtual float getActionCooldown() const { return 0.f; }
|
||||
virtual const ESM::Weapon* getWeapon() const { return nullptr; }
|
||||
virtual ESM::RefId getSpell() const { return {}; }
|
||||
virtual bool isAttackingOrSpell() const { return true; }
|
||||
virtual bool isFleeing() const { return false; }
|
||||
};
|
||||
|
@ -43,6 +44,7 @@ namespace MWMechanics
|
|||
void prepare(const MWWorld::Ptr& actor) override;
|
||||
|
||||
float getCombatRange(bool& isRanged) const override;
|
||||
ESM::RefId getSpell() const override { return mSpellId; }
|
||||
};
|
||||
|
||||
class ActionEnchantedItem : public Action
|
||||
|
|
|
@ -98,6 +98,26 @@ MWWorld::Ptr MWMechanics::AiPackage::getTarget() const
|
|||
return mCachedTarget;
|
||||
}
|
||||
|
||||
bool MWMechanics::AiPackage::targetIs(const MWWorld::Ptr& ptr) const
|
||||
{
|
||||
if (mTargetActorId == -2)
|
||||
return ptr.isEmpty();
|
||||
else if (mTargetActorId == -1)
|
||||
{
|
||||
if (mTargetActorRefId.empty())
|
||||
{
|
||||
mTargetActorId = -2;
|
||||
return ptr.isEmpty();
|
||||
}
|
||||
if (!ptr.isEmpty() && ptr.getCellRef().getRefId() == mTargetActorRefId)
|
||||
return getTarget() == ptr;
|
||||
return false;
|
||||
}
|
||||
if (ptr.isEmpty() || !ptr.getClass().isActor())
|
||||
return false;
|
||||
return ptr.getClass().getCreatureStats(ptr).getActorId() == mTargetActorId;
|
||||
}
|
||||
|
||||
void MWMechanics::AiPackage::reset()
|
||||
{
|
||||
// reset all members
|
||||
|
|
|
@ -87,6 +87,8 @@ namespace MWMechanics
|
|||
|
||||
/// Get the target actor the AI is targeted at (not applicable to all AI packages, default return empty Ptr)
|
||||
virtual MWWorld::Ptr getTarget() const;
|
||||
/// Optimized version of getTarget() == ptr
|
||||
virtual bool targetIs(const MWWorld::Ptr& ptr) 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); }
|
||||
|
|
|
@ -176,11 +176,11 @@ namespace MWMechanics
|
|||
if (!isInCombat())
|
||||
return false;
|
||||
|
||||
for (auto it = mPackages.begin(); it != mPackages.end(); ++it)
|
||||
for (const auto& package : mPackages)
|
||||
{
|
||||
if ((*it)->getTypeId() == AiPackageTypeId::Combat)
|
||||
if (package->getTypeId() == AiPackageTypeId::Combat)
|
||||
{
|
||||
if ((*it)->getTarget() == actor)
|
||||
if (package->targetIs(actor))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,9 +132,6 @@ namespace MWMechanics
|
|||
/// Are we in combat with this particular actor?
|
||||
bool isInCombat(const MWWorld::Ptr& actor) const;
|
||||
|
||||
bool canAddTarget(const ESM::Position& actorPos, float distToTarget) const;
|
||||
///< Function assumes that actor can have only 1 target apart player
|
||||
|
||||
/// Removes all combat packages until first non-combat or stack empty.
|
||||
void stopCombat();
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "../mwbase/world.hpp"
|
||||
|
||||
#include "actor.hpp"
|
||||
#include "actors.hpp"
|
||||
#include "actorutil.hpp"
|
||||
#include "aicombat.hpp"
|
||||
#include "aipursue.hpp"
|
||||
|
@ -1192,9 +1193,9 @@ namespace MWMechanics
|
|||
&& !victim.getClass().getCreatureStats(victim).getAiSequence().hasPackage(AiPackageTypeId::Pursue))
|
||||
reported = reportCrime(player, victim, type, ESM::RefId(), arg);
|
||||
|
||||
// TODO: combat should be started with an "unaware" flag, which makes the victim flee?
|
||||
if (!reported)
|
||||
startCombat(victim,
|
||||
player); // TODO: combat should be started with an "unaware" flag, which makes the victim flee?
|
||||
startCombat(victim, player, &playerFollowers);
|
||||
}
|
||||
return crimeSeen;
|
||||
}
|
||||
|
@ -1435,7 +1436,7 @@ namespace MWMechanics
|
|||
observerStats.modCrimeDispositionModifier(dispositionModifier);
|
||||
}
|
||||
|
||||
startCombat(actor, player);
|
||||
startCombat(actor, player, &playerFollowers);
|
||||
|
||||
// Apply aggression value to the base Fight rating, so that the actor can continue fighting
|
||||
// after a Calm spell wears off
|
||||
|
@ -1486,7 +1487,7 @@ namespace MWMechanics
|
|||
// 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.
|
||||
if (!victim.getClass().getCreatureStats(victim).getAiSequence().isInPursuit())
|
||||
startCombat(victim, player);
|
||||
startCombat(victim, player, &playerFollowers);
|
||||
|
||||
// Set the crime ID, which we will use to calm down participants
|
||||
// once the bounty has been paid.
|
||||
|
@ -1531,14 +1532,14 @@ namespace MWMechanics
|
|||
|
||||
if (!peaceful)
|
||||
{
|
||||
startCombat(target, attacker);
|
||||
SidingCache cachedAllies{ mActors, false };
|
||||
const std::set<MWWorld::Ptr>& attackerAllies = cachedAllies.getActorsSidingWith(attacker);
|
||||
startCombat(target, attacker, &attackerAllies);
|
||||
// Force friendly actors into combat to prevent infighting between followers
|
||||
std::set<MWWorld::Ptr> followersTarget;
|
||||
getActorsSidingWith(target, followersTarget);
|
||||
for (const auto& follower : followersTarget)
|
||||
for (const auto& follower : cachedAllies.getActorsSidingWith(target))
|
||||
{
|
||||
if (follower != attacker && follower != player)
|
||||
startCombat(follower, attacker);
|
||||
startCombat(follower, attacker, &attackerAllies);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1687,7 +1688,8 @@ namespace MWMechanics
|
|||
}
|
||||
}
|
||||
|
||||
void MechanicsManager::startCombat(const MWWorld::Ptr& ptr, const MWWorld::Ptr& target)
|
||||
void MechanicsManager::startCombat(
|
||||
const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, const std::set<MWWorld::Ptr>* targetAllies)
|
||||
{
|
||||
CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
|
||||
|
||||
|
@ -1704,6 +1706,31 @@ namespace MWMechanics
|
|||
return;
|
||||
}
|
||||
|
||||
const bool inCombat = stats.getAiSequence().isInCombat();
|
||||
bool shout = !inCombat;
|
||||
if (inCombat)
|
||||
{
|
||||
const auto isInCombatWithOneOf = [&](const auto& allies) {
|
||||
for (const MWWorld::Ptr& ally : allies)
|
||||
{
|
||||
if (stats.getAiSequence().isInCombat(ally))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (targetAllies)
|
||||
shout = !isInCombatWithOneOf(*targetAllies);
|
||||
else
|
||||
{
|
||||
shout = stats.getAiSequence().isInCombat(target);
|
||||
if (!shout)
|
||||
{
|
||||
std::set<MWWorld::Ptr> sidingActors;
|
||||
getActorsSidingWith(target, sidingActors);
|
||||
shout = !isInCombatWithOneOf(sidingActors);
|
||||
}
|
||||
}
|
||||
}
|
||||
stats.getAiSequence().stack(MWMechanics::AiCombat(target), ptr);
|
||||
if (target == getPlayer())
|
||||
{
|
||||
|
@ -1738,7 +1765,8 @@ namespace MWMechanics
|
|||
}
|
||||
|
||||
// Must be done after the target is set up, so that CreatureTargetted dialogue filter works properly
|
||||
MWBase::Environment::get().getDialogueManager()->say(ptr, ESM::RefId::stringRefId("attack"));
|
||||
if (shout)
|
||||
MWBase::Environment::get().getDialogueManager()->say(ptr, ESM::RefId::stringRefId("attack"));
|
||||
}
|
||||
|
||||
void MechanicsManager::stopCombat(const MWWorld::Ptr& actor)
|
||||
|
|
|
@ -107,7 +107,8 @@ namespace MWMechanics
|
|||
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;
|
||||
void startCombat(
|
||||
const MWWorld::Ptr& ptr, const MWWorld::Ptr& target, const std::set<MWWorld::Ptr>* targetAllies) override;
|
||||
|
||||
void stopCombat(const MWWorld::Ptr& ptr) override;
|
||||
|
||||
|
|
|
@ -507,8 +507,9 @@ namespace MWScript
|
|||
runtime.pop();
|
||||
|
||||
MWWorld::Ptr target = MWBase::Environment::get().getWorld()->searchPtr(targetID, true, false);
|
||||
if (!target.isEmpty())
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(actor, target);
|
||||
if (!target.isEmpty() && !target.getBase()->isDeleted()
|
||||
&& !target.getClass().getCreatureStats(target).isDead())
|
||||
MWBase::Environment::get().getMechanicsManager()->startCombat(actor, target, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -62,16 +62,19 @@ void MWState::StateManager::cleanup(bool force)
|
|||
MWBase::Environment::get().getInputManager()->clear();
|
||||
MWBase::Environment::get().getMechanicsManager()->clear();
|
||||
|
||||
mState = State_NoGame;
|
||||
mCharacterManager.setCurrentCharacter(nullptr);
|
||||
mTimePlayed = 0;
|
||||
mLastSavegame.clear();
|
||||
|
||||
MWMechanics::CreatureStats::cleanup();
|
||||
|
||||
endGame();
|
||||
mState = State_NoGame;
|
||||
MWBase::Environment::get().getLuaManager()->noGame();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: do we need this cleanup?
|
||||
MWBase::Environment::get().getLuaManager()->clear();
|
||||
}
|
||||
MWBase::Environment::get().getLuaManager()->clear();
|
||||
}
|
||||
|
||||
std::map<int, int> MWState::StateManager::buildContentFileIndexMap(const ESM::ESMReader& reader) const
|
||||
|
@ -693,7 +696,8 @@ void MWState::StateManager::quickLoad()
|
|||
{
|
||||
if (currentCharacter->begin() == currentCharacter->end())
|
||||
return;
|
||||
loadGame(currentCharacter, currentCharacter->begin()->mPath); // Get newest save
|
||||
// use requestLoad, otherwise we can crash by loading during the wrong part of the frame
|
||||
requestLoad(currentCharacter->begin()->mPath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,6 @@ namespace OpenMW
|
|||
bpo::value<StringsVector>()->default_value(StringsVector(), "fallback-archive")->multitoken()->composing(),
|
||||
"set fallback BSA archives (later archives have higher priority)");
|
||||
|
||||
addOption("resources",
|
||||
bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), "resources"),
|
||||
"set resources directory");
|
||||
|
||||
addOption("start", bpo::value<std::string>()->default_value(""), "set initial cell");
|
||||
|
||||
addOption("content", bpo::value<StringsVector>()->default_value(StringsVector(), "")->multitoken()->composing(),
|
||||
|
|
|
@ -871,7 +871,7 @@ namespace
|
|||
|
||||
TEST_F(DetourNavigatorNavigatorTest, update_for_very_big_object_should_be_limited)
|
||||
{
|
||||
const float size = static_cast<float>(2 * static_cast<std::int64_t>(std::numeric_limits<int>::max()) - 1);
|
||||
const float size = static_cast<float>((1 << 22) - 1);
|
||||
CollisionShapeInstance bigBox(std::make_unique<btBoxShape>(btVector3(size, size, 1)));
|
||||
const ObjectTransform objectTransform{
|
||||
.mPosition = ESM::Position{ .pos = { 0, 0, 0 }, .rot{ 0, 0, 0 } },
|
||||
|
|
|
@ -79,6 +79,8 @@ openmw_add_executable(openmw-wizard
|
|||
${UI_HDRS}
|
||||
)
|
||||
|
||||
add_dependencies(openmw-wizard qm-files)
|
||||
|
||||
target_link_libraries(openmw-wizard
|
||||
components_qt
|
||||
)
|
||||
|
|
|
@ -37,14 +37,14 @@ void Wizard::ConclusionPage::initializePage()
|
|||
if (field(QLatin1String("installation.retailDisc")).toBool() == true)
|
||||
{
|
||||
textLabel->setText(
|
||||
tr("<html><head/><body><p>The OpenMW Wizard successfully installed Morrowind on your computer.</p>"
|
||||
"<p>Click Finish to close the Wizard.</p></body></html>"));
|
||||
tr("<html><head/><body><p>The OpenMW Wizard successfully installed Morrowind on your "
|
||||
"computer.</p></body></html>"));
|
||||
}
|
||||
else
|
||||
{
|
||||
textLabel->setText(
|
||||
tr("<html><head/><body><p>The OpenMW Wizard successfully modified your existing Morrowind "
|
||||
"installation.</p><p>Click Finish to close the Wizard.</p></body></html>"));
|
||||
"installation.</body></html>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QTranslator>
|
||||
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
#include <components/files/qtconversion.hpp>
|
||||
|
||||
#include "mainwizard.hpp"
|
||||
|
||||
|
@ -11,6 +17,11 @@
|
|||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
boost::program_options::variables_map variables;
|
||||
boost::program_options::options_description description;
|
||||
Files::ConfigurationManager configurationManager;
|
||||
configurationManager.addCommonOptions(description);
|
||||
configurationManager.readConfiguration(variables, description, true);
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
|
@ -28,6 +39,23 @@ int main(int argc, char* argv[])
|
|||
app.setLibraryPaths(libraryPaths);
|
||||
#endif
|
||||
|
||||
QString resourcesPath(".");
|
||||
if (!variables["resources"].empty())
|
||||
{
|
||||
resourcesPath = Files::pathToQString(variables["resources"].as<Files::MaybeQuotedPath>().u8string());
|
||||
}
|
||||
|
||||
// Internationalization
|
||||
QString locale = QLocale::system().name().section('_', 0, 0);
|
||||
|
||||
QTranslator appTranslator;
|
||||
appTranslator.load(resourcesPath + "/translations/wizard_" + locale + ".qm");
|
||||
app.installTranslator(&appTranslator);
|
||||
|
||||
QTranslator componentsAppTranslator;
|
||||
componentsAppTranslator.load(resourcesPath + "/translations/components_" + locale + ".qm");
|
||||
app.installTranslator(&componentsAppTranslator);
|
||||
|
||||
Wizard::MainWizard wizard;
|
||||
|
||||
wizard.show();
|
||||
|
|
|
@ -595,6 +595,10 @@ if (USE_QT)
|
|||
target_link_libraries(components_qt components Qt::Widgets Qt::Core)
|
||||
target_compile_definitions(components_qt PRIVATE OPENMW_DOC_BASEURL="${OPENMW_DOC_BASEURL}")
|
||||
|
||||
if (BUILD_LAUNCHER OR BUILD_WIZARD)
|
||||
add_dependencies(components_qt qm-files)
|
||||
endif()
|
||||
|
||||
if (BUILD_WITH_CODE_COVERAGE)
|
||||
target_compile_options(components_qt PRIVATE --coverage)
|
||||
target_link_libraries(components_qt gcov)
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <errno.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/files/conversion.hpp>
|
||||
|
||||
#include <SDL_messagebox.h>
|
||||
|
||||
|
@ -59,149 +63,214 @@ static struct
|
|||
{
|
||||
int signum;
|
||||
pid_t pid;
|
||||
int has_siginfo;
|
||||
siginfo_t siginfo;
|
||||
char buf[1024];
|
||||
std::optional<siginfo_t> siginfo;
|
||||
} crash_info;
|
||||
|
||||
static const struct
|
||||
namespace
|
||||
{
|
||||
const char* name;
|
||||
int signum;
|
||||
} signals[] = { { "Segmentation fault", SIGSEGV }, { "Illegal instruction", SIGILL }, { "FPU exception", SIGFPE },
|
||||
{ "System BUS error", SIGBUS }, { nullptr, 0 } };
|
||||
constexpr char crash_switch[] = "--cc-handle-crash";
|
||||
|
||||
static const struct
|
||||
{
|
||||
int code;
|
||||
const char* name;
|
||||
} sigill_codes[] = {
|
||||
struct SignalInfo
|
||||
{
|
||||
int mCode;
|
||||
const char* mDescription;
|
||||
const char* mName = "";
|
||||
};
|
||||
|
||||
constexpr SignalInfo signals[] = {
|
||||
{ SIGSEGV, "Segmentation fault", "SIGSEGV" },
|
||||
{ SIGILL, "Illegal instruction", "SIGILL" },
|
||||
{ SIGFPE, "FPU exception", "SIGFPE" },
|
||||
{ SIGBUS, "System BUS error", "SIGBUS" },
|
||||
{ SIGABRT, "Abnormal termination condition", "SIGABRT" },
|
||||
};
|
||||
|
||||
constexpr SignalInfo sigIllCodes[] = {
|
||||
#if !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__)
|
||||
{ ILL_ILLOPC, "Illegal opcode" }, { ILL_ILLOPN, "Illegal operand" }, { ILL_ILLADR, "Illegal addressing mode" },
|
||||
{ ILL_ILLTRP, "Illegal trap" }, { ILL_PRVOPC, "Privileged opcode" }, { ILL_PRVREG, "Privileged register" },
|
||||
{ ILL_COPROC, "Coprocessor error" }, { ILL_BADSTK, "Internal stack error" },
|
||||
{ ILL_ILLOPC, "Illegal opcode" },
|
||||
{ ILL_ILLOPN, "Illegal operand" },
|
||||
{ ILL_ILLADR, "Illegal addressing mode" },
|
||||
{ ILL_ILLTRP, "Illegal trap" },
|
||||
{ ILL_PRVOPC, "Privileged opcode" },
|
||||
{ ILL_PRVREG, "Privileged register" },
|
||||
{ ILL_COPROC, "Coprocessor error" },
|
||||
{ ILL_BADSTK, "Internal stack error" },
|
||||
#endif
|
||||
{ 0, nullptr }
|
||||
};
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
int code;
|
||||
const char* name;
|
||||
} sigfpe_codes[] = { { FPE_INTDIV, "Integer divide by zero" }, { FPE_INTOVF, "Integer overflow" },
|
||||
{ FPE_FLTDIV, "Floating point divide by zero" }, { FPE_FLTOVF, "Floating point overflow" },
|
||||
{ FPE_FLTUND, "Floating point underflow" }, { FPE_FLTRES, "Floating point inexact result" },
|
||||
{ FPE_FLTINV, "Floating point invalid operation" }, { FPE_FLTSUB, "Subscript out of range" }, { 0, nullptr } };
|
||||
constexpr SignalInfo sigFpeCodes[] = {
|
||||
{ FPE_INTDIV, "Integer divide by zero" },
|
||||
{ FPE_INTOVF, "Integer overflow" },
|
||||
{ FPE_FLTDIV, "Floating point divide by zero" },
|
||||
{ FPE_FLTOVF, "Floating point overflow" },
|
||||
{ FPE_FLTUND, "Floating point underflow" },
|
||||
{ FPE_FLTRES, "Floating point inexact result" },
|
||||
{ FPE_FLTINV, "Floating point invalid operation" },
|
||||
{ FPE_FLTSUB, "Subscript out of range" },
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
int code;
|
||||
const char* name;
|
||||
} sigsegv_codes[] = {
|
||||
constexpr SignalInfo sigSegvCodes[] = {
|
||||
#ifndef __FreeBSD__
|
||||
{ SEGV_MAPERR, "Address not mapped to object" }, { SEGV_ACCERR, "Invalid permissions for mapped object" },
|
||||
{ SEGV_MAPERR, "Address not mapped to object" },
|
||||
{ SEGV_ACCERR, "Invalid permissions for mapped object" },
|
||||
#endif
|
||||
{ 0, nullptr }
|
||||
};
|
||||
};
|
||||
|
||||
static const struct
|
||||
{
|
||||
int code;
|
||||
const char* name;
|
||||
} sigbus_codes[] = {
|
||||
constexpr SignalInfo sigBusCodes[] = {
|
||||
#ifndef __FreeBSD__
|
||||
{ BUS_ADRALN, "Invalid address alignment" }, { BUS_ADRERR, "Non-existent physical address" },
|
||||
{ BUS_OBJERR, "Object specific hardware error" },
|
||||
{ BUS_ADRALN, "Invalid address alignment" },
|
||||
{ BUS_ADRERR, "Non-existent physical address" },
|
||||
{ BUS_OBJERR, "Object specific hardware error" },
|
||||
#endif
|
||||
{ 0, nullptr }
|
||||
};
|
||||
};
|
||||
|
||||
static int (*cc_user_info)(char*, char*);
|
||||
const char* findSignalDescription(std::span<const SignalInfo> info, int code)
|
||||
{
|
||||
const auto it = std::find_if(info.begin(), info.end(), [&](const SignalInfo& v) { return v.mCode == code; });
|
||||
return it == info.end() ? "" : it->mDescription;
|
||||
}
|
||||
|
||||
static void gdb_info(pid_t pid)
|
||||
{
|
||||
char respfile[64];
|
||||
FILE* f;
|
||||
int fd;
|
||||
struct Close
|
||||
{
|
||||
void operator()(const int* value) { close(*value); }
|
||||
};
|
||||
|
||||
struct CloseFile
|
||||
{
|
||||
void operator()(FILE* value) { fclose(value); }
|
||||
};
|
||||
|
||||
struct Remove
|
||||
{
|
||||
void operator()(const char* value) { remove(value); }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
bool printDebuggerInfo(pid_t pid)
|
||||
{
|
||||
// Create a temp file to put gdb commands into.
|
||||
// Note: POSIX.1-2008 declares that the file should be already created with mode 0600 by default.
|
||||
// Modern systems implement it and suggest to do not touch masks in multithreaded applications.
|
||||
// So CoverityScan warning is valid only for ancient versions of stdlib.
|
||||
char scriptPath[64];
|
||||
|
||||
std::snprintf(scriptPath, sizeof(scriptPath), "/tmp/%s-script-XXXXXX", T::sName);
|
||||
|
||||
/*
|
||||
* Create a temp file to put gdb commands into.
|
||||
* Note: POSIX.1-2008 declares that the file should be already created with mode 0600 by default.
|
||||
* Modern systems implement it and suggest to do not touch masks in multithreaded applications.
|
||||
* So CoverityScan warning is valid only for ancient versions of stdlib.
|
||||
*/
|
||||
strcpy(respfile, "/tmp/gdb-respfile-XXXXXX");
|
||||
#ifdef __COVERITY__
|
||||
umask(0600);
|
||||
umask(0600);
|
||||
#endif
|
||||
if ((fd = mkstemp(respfile)) >= 0 && (f = fdopen(fd, "w")) != nullptr)
|
||||
{
|
||||
fprintf(f,
|
||||
"attach %d\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Loaded Libraries\"\n"
|
||||
"info sharedlibrary\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Threads\"\n"
|
||||
"info threads\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* FPU Status\"\n"
|
||||
"info float\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Registers\"\n"
|
||||
"info registers\n"
|
||||
"shell echo \"\"\n"
|
||||
"shell echo \"* Backtrace\"\n"
|
||||
"thread apply all backtrace full 1000\n"
|
||||
"detach\n"
|
||||
"quit\n",
|
||||
pid);
|
||||
fclose(f);
|
||||
|
||||
/* Run gdb and print process info. */
|
||||
char cmd_buf[128];
|
||||
snprintf(cmd_buf, sizeof(cmd_buf), "gdb --quiet --batch --command=%s", respfile);
|
||||
printf("Executing: %s\n", cmd_buf);
|
||||
fflush(stdout);
|
||||
|
||||
int ret = system(cmd_buf);
|
||||
|
||||
if (ret != 0)
|
||||
printf(
|
||||
"\nFailed to create a crash report. Please make sure that 'gdb' is installed and present in PATH then "
|
||||
"crash again."
|
||||
"\nCurrent PATH: %s\n",
|
||||
getenv("PATH"));
|
||||
fflush(stdout);
|
||||
|
||||
/* Clean up */
|
||||
if (remove(respfile) != 0)
|
||||
Log(Debug::Warning) << "Warning: can not remove file '" << respfile
|
||||
<< "': " << std::generic_category().message(errno);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Error creating temp file */
|
||||
if (fd >= 0)
|
||||
const int fd = mkstemp(scriptPath);
|
||||
if (fd == -1)
|
||||
{
|
||||
if (close(fd) != 0)
|
||||
Log(Debug::Warning) << "Warning: can not close file '" << respfile
|
||||
<< "': " << std::generic_category().message(errno);
|
||||
else if (remove(respfile) != 0)
|
||||
Log(Debug::Warning) << "Warning: can not remove file '" << respfile
|
||||
<< "': " << std::generic_category().message(errno);
|
||||
printf("Failed to call mkstemp: %s\n", std::generic_category().message(errno).c_str());
|
||||
return false;
|
||||
}
|
||||
printf("!!! Could not create gdb command file\n");
|
||||
std::unique_ptr<const char, Remove> tempFile(scriptPath);
|
||||
std::unique_ptr<const int, Close> scopedFd(&fd);
|
||||
|
||||
FILE* const file = fdopen(fd, "w");
|
||||
if (file == nullptr)
|
||||
{
|
||||
printf("Failed to open file for %s output \"%s\": %s\n", T::sName, scriptPath,
|
||||
std::generic_category().message(errno).c_str());
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<FILE, CloseFile> scopedFile(file);
|
||||
|
||||
if (fprintf(file, "%s", T::sScript) < 0)
|
||||
{
|
||||
printf("Failed to write debugger script to file \"%s\": %s\n", scriptPath,
|
||||
std::generic_category().message(errno).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
scopedFile = nullptr;
|
||||
scopedFd = nullptr;
|
||||
|
||||
char command[128];
|
||||
snprintf(command, sizeof(command), T::sCommandTemplate, pid, scriptPath);
|
||||
printf("Executing: %s\n", command);
|
||||
fflush(stdout);
|
||||
|
||||
const int ret = system(command);
|
||||
|
||||
const bool result = (ret == 0);
|
||||
|
||||
if (ret == -1)
|
||||
printf(
|
||||
"\nFailed to create a crash report: %s.\n"
|
||||
"Please make sure that '%s' is installed and present in PATH then crash again.\n"
|
||||
"Current PATH: %s\n",
|
||||
T::sName, std::generic_category().message(errno).c_str(), getenv("PATH"));
|
||||
else if (ret != 0)
|
||||
printf(
|
||||
"\nFailed to create a crash report.\n"
|
||||
"Please make sure that '%s' is installed and present in PATH then crash again.\n"
|
||||
"Current PATH: %s\n",
|
||||
T::sName, getenv("PATH"));
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct Gdb
|
||||
{
|
||||
static constexpr char sName[] = "gdb";
|
||||
static constexpr char sScript[] = R"(shell echo ""
|
||||
shell echo "* Loaded Libraries"
|
||||
info sharedlibrary
|
||||
shell echo ""
|
||||
shell echo "* Threads"
|
||||
info threads
|
||||
shell echo ""
|
||||
shell echo "* FPU Status"
|
||||
info float
|
||||
shell echo ""
|
||||
shell echo "* Registers"
|
||||
info registers
|
||||
shell echo ""
|
||||
shell echo "* Backtrace"
|
||||
thread apply all backtrace full 1000
|
||||
detach
|
||||
quit
|
||||
)";
|
||||
static constexpr char sCommandTemplate[] = "gdb --pid %d --quiet --batch --command %s";
|
||||
};
|
||||
|
||||
struct Lldb
|
||||
{
|
||||
static constexpr char sName[] = "lldb";
|
||||
static constexpr char sScript[] = R"(script print("\n* Loaded Libraries")
|
||||
image list
|
||||
script print('\n* Threads')
|
||||
thread list
|
||||
script print('\n* Registers')
|
||||
register read --all
|
||||
script print('\n* Backtrace')
|
||||
script print(''.join(f'{t}\n' + ''.join(''.join([f' {f}\n', ''.join(f' {s}\n' for s in f.statics), ''.join(f' {v}\n' for v in f.variables)]) for f in t.frames) for t in lldb.process.threads))
|
||||
detach
|
||||
quit
|
||||
)";
|
||||
static constexpr char sCommandTemplate[] = "lldb --attach-pid %d --batch --source %s";
|
||||
};
|
||||
|
||||
void printProcessInfo(pid_t pid)
|
||||
{
|
||||
if (printDebuggerInfo<Gdb>(pid))
|
||||
return;
|
||||
if (printDebuggerInfo<Lldb>(pid))
|
||||
return;
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void sys_info(void)
|
||||
static void printSystemInfo(void)
|
||||
{
|
||||
#ifdef __unix__
|
||||
struct utsname info;
|
||||
if (uname(&info))
|
||||
printf("!!! Failed to get system information\n");
|
||||
if (uname(&info) == -1)
|
||||
printf("Failed to get system information: %s\n", std::generic_category().message(errno).c_str());
|
||||
else
|
||||
printf("System: %s %s %s %s %s\n", info.sysname, info.nodename, info.release, info.version, info.machine);
|
||||
|
||||
|
@ -214,8 +283,8 @@ static size_t safe_write(int fd, const void* buf, size_t len)
|
|||
size_t ret = 0;
|
||||
while (ret < len)
|
||||
{
|
||||
ssize_t rem;
|
||||
if ((rem = write(fd, (const char*)buf + ret, len - ret)) == -1)
|
||||
const ssize_t rem = write(fd, (const char*)buf + ret, len - ret);
|
||||
if (rem == -1)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
@ -226,12 +295,8 @@ static size_t safe_write(int fd, const void* buf, size_t len)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void crash_catcher(int signum, siginfo_t* siginfo, void* context)
|
||||
static void crash_catcher(int signum, siginfo_t* siginfo, void* /*context*/)
|
||||
{
|
||||
// ucontext_t *ucontext = (ucontext_t*)context;
|
||||
pid_t dbg_pid;
|
||||
int fd[2];
|
||||
|
||||
/* Make sure the effective uid is the real uid */
|
||||
if (getuid() != geteuid())
|
||||
{
|
||||
|
@ -240,6 +305,7 @@ static void crash_catcher(int signum, siginfo_t* siginfo, void* context)
|
|||
}
|
||||
|
||||
safe_write(STDERR_FILENO, fatal_err, sizeof(fatal_err) - 1);
|
||||
int fd[2];
|
||||
if (pipe(fd) == -1)
|
||||
{
|
||||
safe_write(STDERR_FILENO, pipe_err, sizeof(pipe_err) - 1);
|
||||
|
@ -249,14 +315,14 @@ static void crash_catcher(int signum, siginfo_t* siginfo, void* context)
|
|||
|
||||
crash_info.signum = signum;
|
||||
crash_info.pid = getpid();
|
||||
crash_info.has_siginfo = !!siginfo;
|
||||
if (siginfo)
|
||||
if (siginfo == nullptr)
|
||||
crash_info.siginfo = std::nullopt;
|
||||
else
|
||||
crash_info.siginfo = *siginfo;
|
||||
if (cc_user_info)
|
||||
cc_user_info(crash_info.buf, crash_info.buf + sizeof(crash_info.buf));
|
||||
|
||||
const pid_t dbg_pid = fork();
|
||||
/* Fork off to start a crash handler */
|
||||
switch ((dbg_pid = fork()))
|
||||
switch (dbg_pid)
|
||||
{
|
||||
/* Error */
|
||||
case -1:
|
||||
|
@ -296,110 +362,68 @@ static void crash_catcher(int signum, siginfo_t* siginfo, void* context)
|
|||
}
|
||||
}
|
||||
|
||||
static void crash_handler(const char* logfile)
|
||||
[[noreturn]] static void handleCrash(const char* logfile)
|
||||
{
|
||||
const char* sigdesc = "";
|
||||
int i;
|
||||
|
||||
if (fread(&crash_info, sizeof(crash_info), 1, stdin) != 1)
|
||||
{
|
||||
fprintf(stderr, "!!! Failed to retrieve info from crashed process\n");
|
||||
fprintf(stderr, "Failed to retrieve info from crashed process: %s\n",
|
||||
std::generic_category().message(errno).c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get the signal description */
|
||||
for (i = 0; signals[i].name; ++i)
|
||||
{
|
||||
if (signals[i].signum == crash_info.signum)
|
||||
{
|
||||
sigdesc = signals[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const char* sigdesc = findSignalDescription(signals, crash_info.signum);
|
||||
|
||||
if (crash_info.has_siginfo)
|
||||
if (crash_info.siginfo.has_value())
|
||||
{
|
||||
switch (crash_info.signum)
|
||||
{
|
||||
case SIGSEGV:
|
||||
for (i = 0; sigsegv_codes[i].name; ++i)
|
||||
{
|
||||
if (sigsegv_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigsegv_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sigdesc = findSignalDescription(sigSegvCodes, crash_info.siginfo->si_code);
|
||||
break;
|
||||
|
||||
case SIGFPE:
|
||||
for (i = 0; sigfpe_codes[i].name; ++i)
|
||||
{
|
||||
if (sigfpe_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigfpe_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sigdesc = findSignalDescription(sigFpeCodes, crash_info.siginfo->si_code);
|
||||
break;
|
||||
|
||||
case SIGILL:
|
||||
for (i = 0; sigill_codes[i].name; ++i)
|
||||
{
|
||||
if (sigill_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigill_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sigdesc = findSignalDescription(sigIllCodes, crash_info.siginfo->si_code);
|
||||
break;
|
||||
|
||||
case SIGBUS:
|
||||
for (i = 0; sigbus_codes[i].name; ++i)
|
||||
{
|
||||
if (sigbus_codes[i].code == crash_info.siginfo.si_code)
|
||||
{
|
||||
sigdesc = sigbus_codes[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sigdesc = findSignalDescription(sigBusCodes, crash_info.siginfo->si_code);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "%s (signal %i)\n", sigdesc, crash_info.signum);
|
||||
if (crash_info.has_siginfo)
|
||||
fprintf(stderr, "Address: %p\n", crash_info.siginfo.si_addr);
|
||||
if (crash_info.siginfo.has_value())
|
||||
fprintf(stderr, "Address: %p\n", crash_info.siginfo->si_addr);
|
||||
fputc('\n', stderr);
|
||||
|
||||
if (logfile)
|
||||
/* Create crash log file and redirect shell output to it */
|
||||
if (freopen(logfile, "wa", stdout) != stdout)
|
||||
{
|
||||
/* Create crash log file and redirect shell output to it */
|
||||
if (freopen(logfile, "wa", stdout) != stdout)
|
||||
{
|
||||
fprintf(stderr, "!!! Could not create %s following signal\n", logfile);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
||||
|
||||
printf(
|
||||
"*** Fatal Error ***\n"
|
||||
"%s (signal %i)\n",
|
||||
sigdesc, crash_info.signum);
|
||||
if (crash_info.has_siginfo)
|
||||
printf("Address: %p\n", crash_info.siginfo.si_addr);
|
||||
fputc('\n', stdout);
|
||||
fflush(stdout);
|
||||
fprintf(stderr, "Could not create %s following signal: %s\n", logfile,
|
||||
std::generic_category().message(errno).c_str());
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "Generating %s and killing process %d, please wait... ", logfile, crash_info.pid);
|
||||
|
||||
sys_info();
|
||||
printf(
|
||||
"*** Fatal Error ***\n"
|
||||
"%s (signal %i)\n",
|
||||
sigdesc, crash_info.signum);
|
||||
if (crash_info.siginfo.has_value())
|
||||
printf("Address: %p\n", crash_info.siginfo->si_addr);
|
||||
fputc('\n', stdout);
|
||||
fflush(stdout);
|
||||
|
||||
printSystemInfo();
|
||||
|
||||
crash_info.buf[sizeof(crash_info.buf) - 1] = '\0';
|
||||
printf("%s\n", crash_info.buf);
|
||||
fflush(stdout);
|
||||
|
||||
if (crash_info.pid > 0)
|
||||
{
|
||||
gdb_info(crash_info.pid);
|
||||
printProcessInfo(crash_info.pid);
|
||||
kill(crash_info.pid, SIGKILL);
|
||||
}
|
||||
|
||||
|
@ -408,12 +432,9 @@ static void crash_handler(const char* logfile)
|
|||
// even faulty applications shouldn't be able to freeze the X server.
|
||||
usleep(100000);
|
||||
|
||||
if (logfile)
|
||||
{
|
||||
std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(logfile)
|
||||
+ "'.\n Please report this to https://gitlab.com/OpenMW/openmw/issues !";
|
||||
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
|
||||
}
|
||||
const std::string message = "OpenMW has encountered a fatal error.\nCrash log saved to '" + std::string(logfile)
|
||||
+ "'.\n Please report this to https://gitlab.com/OpenMW/openmw/issues !";
|
||||
SDL_ShowSimpleMessageBox(0, "Fatal Error", message.c_str(), nullptr);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
@ -426,13 +447,16 @@ static void getExecPath(char** argv)
|
|||
|
||||
if (sysctl(mib, 4, argv0, &size, nullptr, 0) == 0)
|
||||
return;
|
||||
|
||||
Log(Debug::Warning) << "Failed to call sysctl: " << std::generic_category().message(errno);
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (proc_pidpath(getpid(), argv0, sizeof(argv0)) > 0)
|
||||
return;
|
||||
|
||||
Log(Debug::Warning) << "Failed to call proc_pidpath: " << std::generic_category().message(errno);
|
||||
#endif
|
||||
int cwdlen;
|
||||
const char* statusPaths[] = { "/proc/self/exe", "/proc/self/file", "/proc/curproc/exe", "/proc/curproc/file" };
|
||||
memset(argv0, 0, sizeof(argv0));
|
||||
|
||||
|
@ -440,60 +464,83 @@ static void getExecPath(char** argv)
|
|||
{
|
||||
if (readlink(path, argv0, sizeof(argv0)) != -1)
|
||||
return;
|
||||
|
||||
Log(Debug::Warning) << "Failed to call readlink for \"" << path
|
||||
<< "\": " << std::generic_category().message(errno);
|
||||
}
|
||||
|
||||
if (argv[0][0] == '/')
|
||||
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
||||
else if (getcwd(argv0, sizeof(argv0)) != nullptr)
|
||||
{
|
||||
cwdlen = strlen(argv0);
|
||||
snprintf(argv0 + cwdlen, sizeof(argv0) - cwdlen, "/%s", argv[0]);
|
||||
snprintf(argv0, sizeof(argv0), "%s", argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (getcwd(argv0, sizeof(argv0)) == nullptr)
|
||||
{
|
||||
Log(Debug::Error) << "Failed to call getcwd: " << std::generic_category().message(errno);
|
||||
return;
|
||||
}
|
||||
|
||||
const int cwdlen = strlen(argv0);
|
||||
snprintf(argv0 + cwdlen, sizeof(argv0) - cwdlen, "/%s", argv[0]);
|
||||
}
|
||||
|
||||
int crashCatcherInstallHandlers(
|
||||
int argc, char** argv, int num_signals, int* signals, const char* logfile, int (*user_info)(char*, char*))
|
||||
static bool crashCatcherInstallHandlers(char** argv)
|
||||
{
|
||||
struct sigaction sa;
|
||||
stack_t altss;
|
||||
int retval;
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
||||
crash_handler(logfile);
|
||||
|
||||
cc_user_info = user_info;
|
||||
|
||||
getExecPath(argv);
|
||||
|
||||
/* Set an alternate signal stack so SIGSEGVs caused by stack overflows
|
||||
* still run */
|
||||
static char* altstack = new char[SIGSTKSZ];
|
||||
stack_t altss;
|
||||
altss.ss_sp = altstack;
|
||||
altss.ss_flags = 0;
|
||||
altss.ss_size = SIGSTKSZ;
|
||||
sigaltstack(&altss, nullptr);
|
||||
if (sigaltstack(&altss, nullptr) == -1)
|
||||
{
|
||||
Log(Debug::Error) << "Failed to call sigaltstack: " << std::generic_category().message(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
sa.sa_sigaction = crash_catcher;
|
||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER | SA_SIGINFO | SA_ONSTACK;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
|
||||
retval = 0;
|
||||
while (num_signals--)
|
||||
if (sigemptyset(&sa.sa_mask) == -1)
|
||||
{
|
||||
if ((*signals != SIGSEGV && *signals != SIGILL && *signals != SIGFPE && *signals != SIGABRT
|
||||
&& *signals != SIGBUS)
|
||||
|| sigaction(*signals, &sa, nullptr) == -1)
|
||||
{
|
||||
*signals = 0;
|
||||
retval = -1;
|
||||
}
|
||||
++signals;
|
||||
Log(Debug::Error) << "Failed to call sigemptyset: " << std::generic_category().message(errno);
|
||||
return false;
|
||||
}
|
||||
return retval;
|
||||
|
||||
for (const SignalInfo& signal : signals)
|
||||
{
|
||||
if (sigaction(signal.mCode, &sa, nullptr) == -1)
|
||||
{
|
||||
Log(Debug::Error) << "Failed to call sigaction for signal " << signal.mName << " (" << signal.mCode
|
||||
<< "): " << std::generic_category().message(errno);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool is_debugger_present()
|
||||
namespace
|
||||
{
|
||||
#if defined(__APPLE__)
|
||||
bool isDebuggerPresent(const auto& info)
|
||||
{
|
||||
return (info.kp_proc.p_flag & P_TRACED) != 0;
|
||||
}
|
||||
#elif defined(__FreeBSD__)
|
||||
bool isDebuggerPresent(const auto& info)
|
||||
{
|
||||
return (info.ki_flag & P_TRACED) != 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool isDebuggerPresent()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
std::filesystem::path procstatus = std::filesystem::path("/proc/self/status");
|
||||
|
@ -512,44 +559,23 @@ static bool is_debugger_present()
|
|||
}
|
||||
}
|
||||
return false;
|
||||
#elif defined(__APPLE__)
|
||||
int junk;
|
||||
int mib[4];
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
struct kinfo_proc info;
|
||||
size_t size;
|
||||
|
||||
// Initialize the flags so that, if sysctl fails for some bizarre
|
||||
// reason, we get a predictable result.
|
||||
|
||||
info.kp_proc.p_flag = 0;
|
||||
std::memset(&info, 0, sizeof(info));
|
||||
|
||||
// Initialize mib, which tells sysctl the info we want, in this case
|
||||
// we're looking for information about a specific process ID.
|
||||
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_PID;
|
||||
mib[3] = getpid();
|
||||
|
||||
// Call sysctl.
|
||||
|
||||
size = sizeof(info);
|
||||
junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0);
|
||||
assert(junk == 0);
|
||||
|
||||
// We're being debugged if the P_TRACED flag is set.
|
||||
|
||||
return (info.kp_proc.p_flag & P_TRACED) != 0;
|
||||
#elif defined(__FreeBSD__)
|
||||
struct kinfo_proc info;
|
||||
size_t size = sizeof(info);
|
||||
int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() };
|
||||
|
||||
if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) == 0)
|
||||
return (info.ki_flag & P_TRACED) != 0;
|
||||
else
|
||||
perror("Failed to retrieve process info");
|
||||
return false;
|
||||
size_t size = sizeof(info);
|
||||
if (sysctl(mib, std::size(mib), &info, &size, nullptr, 0) == -1)
|
||||
{
|
||||
Log(Debug::Warning) << "Failed to call sysctl, assuming no debugger: "
|
||||
<< std::generic_category().message(errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
return isDebuggerPresent(info);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
@ -557,14 +583,17 @@ static bool is_debugger_present()
|
|||
|
||||
void crashCatcherInstall(int argc, char** argv, const std::filesystem::path& crashLogPath)
|
||||
{
|
||||
if ((argc == 2 && strcmp(argv[1], crash_switch) == 0) || !is_debugger_present())
|
||||
{
|
||||
int s[5] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGABRT };
|
||||
if (crashCatcherInstallHandlers(argc, argv, 5, s, crashLogPath.c_str(), nullptr) == -1)
|
||||
{
|
||||
Log(Debug::Warning) << "Installing crash handler failed";
|
||||
}
|
||||
else
|
||||
Log(Debug::Info) << "Crash handler installed";
|
||||
}
|
||||
#if (defined(__APPLE__) || (defined(__linux) && !defined(ANDROID)) || (defined(__unix) && !defined(ANDROID)) \
|
||||
|| defined(__posix))
|
||||
if (argc == 2 && strcmp(argv[1], crash_switch) == 0)
|
||||
handleCrash(Files::pathToUnicodeString(crashLogPath).c_str());
|
||||
|
||||
if (isDebuggerPresent())
|
||||
return;
|
||||
|
||||
if (crashCatcherInstallHandlers(argv))
|
||||
Log(Debug::Info) << "Crash handler installed";
|
||||
else
|
||||
Log(Debug::Warning) << "Installing crash handler failed";
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -2,21 +2,7 @@
|
|||
#define CRASHCATCHER_H
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#if (defined(__APPLE__) || (defined(__linux) && !defined(ANDROID)) || (defined(__unix) && !defined(ANDROID)) \
|
||||
|| defined(__posix))
|
||||
#define USE_CRASH_CATCHER 1
|
||||
#else
|
||||
#define USE_CRASH_CATCHER 0
|
||||
#endif
|
||||
|
||||
constexpr char crash_switch[] = "--cc-handle-crash";
|
||||
|
||||
#if USE_CRASH_CATCHER
|
||||
extern void crashCatcherInstall(int argc, char** argv, const std::filesystem::path& crashLogPath);
|
||||
#else
|
||||
inline void crashCatcherInstall(int, char**, const std::string& crashLogPath) {}
|
||||
#endif
|
||||
void crashCatcherInstall(int argc, char** argv, const std::filesystem::path& crashLogPath);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -352,8 +352,7 @@ int wrapApplication(int (*innerApplication)(int argc, char* argv[]), int argc, c
|
|||
#else
|
||||
const std::string crashLogName = Misc::StringUtils::lowerCase(appName) + "-crash.log";
|
||||
// install the crash handler as soon as possible.
|
||||
crashCatcherInstall(
|
||||
argc, argv, Files::pathToUnicodeString(std::filesystem::temp_directory_path() / crashLogName));
|
||||
crashCatcherInstall(argc, argv, std::filesystem::temp_directory_path() / crashLogName);
|
||||
#endif
|
||||
ret = innerApplication(argc, argv);
|
||||
}
|
||||
|
|
|
@ -186,16 +186,35 @@ namespace DetourNavigator
|
|||
&context, solid, width, height, bmin.ptr(), bmax.ptr(), settings.mCellSize, settings.mCellHeight);
|
||||
}
|
||||
|
||||
bool isSupportedCoordinate(float value)
|
||||
{
|
||||
constexpr float maxVertexCoordinate = static_cast<float>(1 << 22);
|
||||
return -maxVertexCoordinate < value && value < maxVertexCoordinate;
|
||||
}
|
||||
|
||||
template <class Iterator>
|
||||
bool isSupportedCoordinates(Iterator begin, Iterator end)
|
||||
{
|
||||
return std::all_of(begin, end, isSupportedCoordinate);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool rasterizeTriangles(RecastContext& context, const Mesh& mesh, const RecastSettings& settings,
|
||||
const RecastParams& params, rcHeightfield& solid)
|
||||
{
|
||||
std::vector<unsigned char> areas(mesh.getAreaTypes().begin(), mesh.getAreaTypes().end());
|
||||
std::vector<float> vertices = mesh.getVertices();
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i += 3)
|
||||
constexpr std::size_t verticesPerTriangle = 3;
|
||||
|
||||
for (std::size_t i = 0; i < vertices.size(); i += verticesPerTriangle)
|
||||
{
|
||||
for (std::size_t j = 0; j < 3; ++j)
|
||||
vertices[i + j] = toNavMeshCoordinates(settings, vertices[i + j]);
|
||||
for (std::size_t j = 0; j < verticesPerTriangle; ++j)
|
||||
{
|
||||
const float coordinate = toNavMeshCoordinates(settings, vertices[i + j]);
|
||||
if (!isSupportedCoordinate(coordinate))
|
||||
return false;
|
||||
vertices[i + j] = coordinate;
|
||||
}
|
||||
std::swap(vertices[i + 1], vertices[i + 2]);
|
||||
}
|
||||
|
||||
|
@ -217,6 +236,9 @@ namespace DetourNavigator
|
|||
rectangle.mBounds.mMax.x(), rectangle.mHeight, rectangle.mBounds.mMin.y(), // vertex 3
|
||||
};
|
||||
|
||||
if (!isSupportedCoordinates(vertices.begin(), vertices.end()))
|
||||
return false;
|
||||
|
||||
const std::array indices{
|
||||
0, 1, 2, // triangle 0
|
||||
0, 2, 3, // triangle 1
|
||||
|
|
|
@ -194,6 +194,10 @@ namespace Files
|
|||
"instead of being appended");
|
||||
addOption("user-data", bpo::value<Files::MaybeQuotedPath>()->default_value(Files::MaybeQuotedPath(), ""),
|
||||
"set user data directory (used for saves, screenshots, etc)");
|
||||
addOption("resources",
|
||||
boost::program_options::value<Files::MaybeQuotedPath>()->default_value(
|
||||
Files::MaybeQuotedPath(), "resources"),
|
||||
"set resources directory");
|
||||
}
|
||||
|
||||
bpo::variables_map separateComposingVariables(
|
||||
|
|
|
@ -421,7 +421,6 @@ local menuGroups = {}
|
|||
local menuPages = {}
|
||||
|
||||
local function resetPlayerGroups()
|
||||
print('MENU reset player groups')
|
||||
local playerGroupsSection = storage.playerSection(common.groupSectionKey)
|
||||
for pageKey, page in pairs(groups) do
|
||||
for groupKey, group in pairs(page) do
|
||||
|
@ -503,7 +502,7 @@ return {
|
|||
if menu.getState() == menu.STATE.Running then
|
||||
updatePlayerGroups()
|
||||
updateGlobalGroups()
|
||||
else
|
||||
elseif menu.getState() == menu.STATE.NoGame then
|
||||
resetPlayerGroups()
|
||||
end
|
||||
end,
|
||||
|
|
85
files/lang/components_de.ts
Normal file
85
files/lang/components_de.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>ContentSelector</name>
|
||||
<message>
|
||||
<source>Select language used by ESM/ESP content files to allow OpenMW to detect their encoding. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::ContentModel</name>
|
||||
<message>
|
||||
<source>Unable to find dependent file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dependent file needs to be active: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This file needs to load after %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::EsmFile</name>
|
||||
<message>
|
||||
<source><b>Author:</b> %1<br/><b>Format version:</b> %2<br/><b>Modified:</b> %3<br/><b>Path:</b><br/>%4<br/><br/><b>Description:</b><br/>%5<br/><br/><b>Dependencies: </b>%6<br/></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorView::ContentSelector</name>
|
||||
<message>
|
||||
<source>&Check Selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Uncheck Selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy Path(s) to Clipboard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><No game file></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Process::ProcessInvoker</name>
|
||||
<message>
|
||||
<source>Error starting executable</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error running executable</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>
|
||||
Arguments:
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not find %1</b></p><p>The application is not found.</p><p>Please make sure OpenMW is installed correctly and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>The application is not executable.</p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>An error occurred while starting %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Executable %1 returned an error</b></p><p>An error occurred while running %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
85
files/lang/components_fr.ts
Normal file
85
files/lang/components_fr.ts
Normal file
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="fr_FR">
|
||||
<context>
|
||||
<name>ContentSelector</name>
|
||||
<message>
|
||||
<source>Select language used by ESM/ESP content files to allow OpenMW to detect their encoding. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::ContentModel</name>
|
||||
<message>
|
||||
<source>Unable to find dependent file: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dependent file needs to be active: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This file needs to load after %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::EsmFile</name>
|
||||
<message>
|
||||
<source><b>Author:</b> %1<br/><b>Format version:</b> %2<br/><b>Modified:</b> %3<br/><b>Path:</b><br/>%4<br/><br/><b>Description:</b><br/>%5<br/><br/><b>Dependencies: </b>%6<br/></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorView::ContentSelector</name>
|
||||
<message>
|
||||
<source>&Check Selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Uncheck Selected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy Path(s) to Clipboard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><No game file></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Process::ProcessInvoker</name>
|
||||
<message>
|
||||
<source>Error starting executable</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error running executable</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>
|
||||
Arguments:
|
||||
</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not find %1</b></p><p>The application is not found.</p><p>Please make sure OpenMW is installed correctly and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>The application is not executable.</p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>An error occurred while starting %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Executable %1 returned an error</b></p><p>An error occurred while running %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
87
files/lang/components_ru.ts
Normal file
87
files/lang/components_ru.ts
Normal file
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>ContentSelector</name>
|
||||
<message>
|
||||
<source>Select language used by ESM/ESP content files to allow OpenMW to detect their encoding. </source>
|
||||
<translation>Выберите язык, используемый вашими файлами данных ESM/ESP, чтобы позволить OpenMW определить их кодировку. </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::ContentModel</name>
|
||||
<message>
|
||||
<source>Unable to find dependent file: %1</source>
|
||||
<translation>Зависимый файл не найден: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Dependent file needs to be active: %1</source>
|
||||
<translation>Зависимый файл должен быть включен: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>This file needs to load after %1</source>
|
||||
<translation>Этот файл должен быть загружен после %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorModel::EsmFile</name>
|
||||
<message>
|
||||
<source><b>Author:</b> %1<br/><b>Format version:</b> %2<br/><b>Modified:</b> %3<br/><b>Path:</b><br/>%4<br/><br/><b>Description:</b><br/>%5<br/><br/><b>Dependencies: </b>%6<br/></source>
|
||||
<translation><b>Автор:</b> %1<br/><b>Версия формата данных:</b> %2<br/><b>Дата изменения:</b> %3<br/><b>Путь к файлу:</b><br/>%4<br/><br/><b>Описание:</b><br/>%5<br/><br/><b>Зависимости: </b>%6<br/></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ContentSelectorView::ContentSelector</name>
|
||||
<message>
|
||||
<source>&Check Selected</source>
|
||||
<translation>&Включить выбранное</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Uncheck Selected</source>
|
||||
<translation>&Отключить выбранное</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>&Copy Path(s) to Clipboard</source>
|
||||
<translation>&Скопировать пути в буфер обмена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><No game file></source>
|
||||
<translation><Без файла игры></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Process::ProcessInvoker</name>
|
||||
<message>
|
||||
<source>Error starting executable</source>
|
||||
<translation>Не удалось запустить исполняемый файл</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Error running executable</source>
|
||||
<translation>При исполнении приложения произошла ошибка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>
|
||||
Arguments:
|
||||
</source>
|
||||
<translation>
|
||||
Параметры:
|
||||
</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not find %1</b></p><p>The application is not found.</p><p>Please make sure OpenMW is installed correctly and try again.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось найти %1</b></p><p>Приложение не найдено.</p><p>Пожалуйста, убедитесь, что OpenMW установлен правильно, и повторите попытку.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>The application is not executable.</p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось запустить %1</b></p><p>У приложения нет прав на исполнение.</p><p>Пожалуйста, проверьте права доступа и повторите попытку.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Could not start %1</b></p><p>An error occurred while starting %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось запустить %1</b></p><p>Возникла ошибка при запуске %1.</p><p>Нажмите "Показать детали..." для получения дополнительной информации.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source><html><head/><body><p><b>Executable %1 returned an error</b></p><p>An error occurred while running %1.</p><p>Press "Show Details..." for more information.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Исполнение файла %1 завершилось с ошибкой</b></p><p>Возникла ошибка при выполнении %1.</p><p>Нажмите "Показать детали..." для получения дополнительной информации.</p></body></html></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
1451
files/lang/launcher_de.ts
Normal file
1451
files/lang/launcher_de.ts
Normal file
File diff suppressed because it is too large
Load diff
1451
files/lang/launcher_fr.ts
Normal file
1451
files/lang/launcher_fr.ts
Normal file
File diff suppressed because it is too large
Load diff
1466
files/lang/launcher_ru.ts
Normal file
1466
files/lang/launcher_ru.ts
Normal file
File diff suppressed because it is too large
Load diff
858
files/lang/wizard_de.ts
Normal file
858
files/lang/wizard_de.ts
Normal file
|
@ -0,0 +1,858 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="de_DE">
|
||||
<context>
|
||||
<name>ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="17"/>
|
||||
<source>Select Components</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="20"/>
|
||||
<source>Which components should be installed?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>Select which official Morrowind expansions should be installed. For best results, it is recommended to have both expansions installed.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to install expansions later by re-running this Wizard.<br/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="36"/>
|
||||
<source>Selected components:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="17"/>
|
||||
<source>Completing the OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="23"/>
|
||||
<source>Placeholder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="17"/>
|
||||
<source>Select Existing Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="20"/>
|
||||
<source>Select an existing installation for OpenMW to use or modify.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="26"/>
|
||||
<source>Detected installations:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="51"/>
|
||||
<source>Browse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ImportPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="17"/>
|
||||
<source>Import Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="20"/>
|
||||
<source>Import settings from the Morrowind installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>OpenMW needs to import settings from the Morrowind configuration file in order to function properly.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to import settings later by re-running this Wizard.</p><p/></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="36"/>
|
||||
<source>Import settings from Morrowind.ini</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="46"/>
|
||||
<source>Import add-on and plugin selection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="56"/>
|
||||
<source>Import bitmap fonts setup from Morrowind.ini</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="59"/>
|
||||
<source>Fonts shipped with the original engine are blurry with UI scaling and support only a small amount of characters,
|
||||
so OpenMW provides another set of fonts to avoid these issues. These fonts use TrueType technology and are quite similar
|
||||
to default Morrowind fonts. Check this box if you still prefer original fonts over OpenMW ones or if you use custom bitmap fonts.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="17"/>
|
||||
<source>Installing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="20"/>
|
||||
<source>Please wait while Morrowind is installed on your computer.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="17"/>
|
||||
<source>Select Installation Destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="20"/>
|
||||
<source>Where should Morrowind be installed?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="47"/>
|
||||
<source>Morrowind will be installed to the following location. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="64"/>
|
||||
<source>Browse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IntroPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="17"/>
|
||||
<source>Welcome to the OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="23"/>
|
||||
<source>This Wizard will help you install Morrowind and its add-ons for OpenMW to use.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="17"/>
|
||||
<source>Select Morrowind Language</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="20"/>
|
||||
<source>What is the language of the Morrowind installation?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/preferences-desktop-locale.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="47"/>
|
||||
<source>Select the language of the Morrowind installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MethodSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="17"/>
|
||||
<source>Select Installation Method</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="20"/>
|
||||
<source><html><head/><body><p>Select how you would like to install <i>The Elder Scrolls III: Morrowind</i>.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="29"/>
|
||||
<source>Retail CD/DVD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="63"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/system-installer.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="82"/>
|
||||
<source>Install from a retail disc to a new location.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="97"/>
|
||||
<source>Existing Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="128"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="141"/>
|
||||
<source>Select an existing installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="162"/>
|
||||
<source>Don't have a copy?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="195"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/dollar.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="202"/>
|
||||
<source>Buy the game</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="61"/>
|
||||
<source><br><b>Could not find Morrowind.ini</b><br><br>The Wizard needs to update settings in this file.<br><br>Press "Browse..." to specify the location manually.<br></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="65"/>
|
||||
<source>B&rowse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="72"/>
|
||||
<source>Select configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="110"/>
|
||||
<source><b>Morrowind.bsa</b> is missing!<br>Make sure your Morrowind installation is complete.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="190"/>
|
||||
<source><br><b>There may be a more recent version of Morrowind available.</b><br><br>Do you wish to continue anyway?<br></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="185"/>
|
||||
<source>Most recent Morrowind not detected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="168"/>
|
||||
<source>Select a valid %1 installation media.<br><b>Hint</b>: make sure that it contains at least one <b>.cab</b> file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="200"/>
|
||||
<source>There may be a more recent version of Morrowind available.<br><br>Do you wish to continue anyway?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="16"/>
|
||||
<source>&Install</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="46"/>
|
||||
<source>&Skip</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="83"/>
|
||||
<source>Morrowind (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="89"/>
|
||||
<source>Morrowind</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="97"/>
|
||||
<source>Tribunal (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="103"/>
|
||||
<source>Tribunal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="111"/>
|
||||
<source>Bloodmoon (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="117"/>
|
||||
<source>Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="137"/>
|
||||
<source>About to install Tribunal after Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="141"/>
|
||||
<source><html><head/><body><p><b>You are about to install Tribunal</b></p><p>Bloodmoon is already installed on your computer.</p><p>However, it is recommended that you install Tribunal before Bloodmoon.</p><p>Would you like to re-install Bloodmoon?</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="147"/>
|
||||
<source>Re-install &Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="40"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully installed Morrowind on your computer.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="46"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully modified your existing Morrowind installation.</body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="53"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard failed to install Morrowind on your computer.</p><p>Please report any bugs you might have encountered to our <a href="https://gitlab.com/OpenMW/openmw/issues">bug tracker</a>.<br/>Make sure to include the installation log.</p><br/></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="18"/>
|
||||
<source>No existing installations detected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="57"/>
|
||||
<source>Error detecting Morrowind configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="73"/>
|
||||
<source>Morrowind configuration file (*.ini)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="92"/>
|
||||
<source>Select Morrowind.esm (located in Data Files)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="93"/>
|
||||
<source>Morrowind master file (Morrowind.esm)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="106"/>
|
||||
<source>Error detecting Morrowind files</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="161"/>
|
||||
<source><p>Attempting to install component %1.</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="162"/>
|
||||
<source>Attempting to install component %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="165"/>
|
||||
<source>%1 Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="174"/>
|
||||
<source>Select %1 installation media</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="179"/>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="209"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: The installation was aborted by the user</b></span></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="194"/>
|
||||
<source><p>Detected old version of component Morrowind.</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="195"/>
|
||||
<source>Detected old version of component Morrowind.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="198"/>
|
||||
<source>Morrowind Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="225"/>
|
||||
<source>Installation finished</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="228"/>
|
||||
<source>Installation completed successfully!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="238"/>
|
||||
<source>Installation failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="240"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: %1</b></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="241"/>
|
||||
<source><p><span style="color:red;"><b>%1</b></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="252"/>
|
||||
<source><html><head/><body><p><b>The Wizard has encountered an error</b></p><p>The error reported was:</p><p>%1</p><p>Press &quot;Show Details...&quot; for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="248"/>
|
||||
<source>An error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="47"/>
|
||||
<source>Error creating destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="51"/>
|
||||
<source><html><head/><body><p><b>Could not create the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="68"/>
|
||||
<source><html><head/><body><p><b>Could not write to the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="82"/>
|
||||
<source><html><head/><body><p><b>The destination directory is not empty</b></p><p>An existing Morrowind installation is present in the specified location.</p><p>Please specify a different location, or go back and select the location as an existing installation.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="64"/>
|
||||
<source>Insufficient permissions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="78"/>
|
||||
<source>Destination not empty</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="95"/>
|
||||
<source>Select where to install Morrowind</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>English</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>French</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>German</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Italian</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Polish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Russian</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Spanish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::MainWizard</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="41"/>
|
||||
<source>OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="94"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="118"/>
|
||||
<source>Error opening Wizard log file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="57"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="450"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="477"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for writing</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="142"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="213"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for reading</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="158"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="190"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="226"/>
|
||||
<source>Error opening OpenMW configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="380"/>
|
||||
<source>Quit Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="383"/>
|
||||
<source>Are you sure you want to exit the Wizard?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="425"/>
|
||||
<source>Error creating OpenMW configuration directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="429"/>
|
||||
<source><html><head/><body><p><b>Could not create %1</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="446"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="473"/>
|
||||
<source>Error writing OpenMW configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::UnshieldWorker</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="177"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="196"/>
|
||||
<source>Failed to open Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="178"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="197"/>
|
||||
<source>Opening %1 failed: %2.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="203"/>
|
||||
<source>Failed to write Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="204"/>
|
||||
<source>Writing to %1 failed: %2.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="338"/>
|
||||
<source>Installing: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="367"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="775"/>
|
||||
<source>Installing: %1 directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="438"/>
|
||||
<source>Installation finished!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>Component parameter is invalid!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>An invalid component parameter was supplied.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="543"/>
|
||||
<source>Failed to find a valid archive containing %1.bsa! Retrying.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="586"/>
|
||||
<source>Installing %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>Installation media path not set!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>The source path for %1 was not set.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Cannot create temporary directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Failed to create %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="621"/>
|
||||
<source>Cannot move into temporary directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="622"/>
|
||||
<source>Failed to move into %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="631"/>
|
||||
<source>Moving installation files</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="712"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="779"/>
|
||||
<source>Could not install directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="713"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="780"/>
|
||||
<source>Installing %1 to %2 failed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Could not install translation file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Failed to install *%1 files.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<source>Could not install Morrowind data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="691"/>
|
||||
<source>Failed to install %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="690"/>
|
||||
<source>Could not install Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="709"/>
|
||||
<source>Installing: Sound directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<source>Could not find Tribunal data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="740"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Failed to find %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="739"/>
|
||||
<source>Could not find Tribunal patch file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Could not find Bloodmoon data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="760"/>
|
||||
<source>Updating Morrowind configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="785"/>
|
||||
<source>%1 installation finished!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="824"/>
|
||||
<source>Extracting: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Failed to open InstallShield Cabinet File.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Opening %1 failed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="879"/>
|
||||
<source>Failed to extract %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="880"/>
|
||||
<source>Complete path: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
858
files/lang/wizard_fr.ts
Normal file
858
files/lang/wizard_fr.ts
Normal file
|
@ -0,0 +1,858 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="fr_FR">
|
||||
<context>
|
||||
<name>ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="17"/>
|
||||
<source>Select Components</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="20"/>
|
||||
<source>Which components should be installed?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>Select which official Morrowind expansions should be installed. For best results, it is recommended to have both expansions installed.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to install expansions later by re-running this Wizard.<br/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="36"/>
|
||||
<source>Selected components:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="17"/>
|
||||
<source>Completing the OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="23"/>
|
||||
<source>Placeholder</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="17"/>
|
||||
<source>Select Existing Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="20"/>
|
||||
<source>Select an existing installation for OpenMW to use or modify.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="26"/>
|
||||
<source>Detected installations:</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="51"/>
|
||||
<source>Browse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ImportPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="17"/>
|
||||
<source>Import Settings</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="20"/>
|
||||
<source>Import settings from the Morrowind installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>OpenMW needs to import settings from the Morrowind configuration file in order to function properly.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to import settings later by re-running this Wizard.</p><p/></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="36"/>
|
||||
<source>Import settings from Morrowind.ini</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="46"/>
|
||||
<source>Import add-on and plugin selection</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="56"/>
|
||||
<source>Import bitmap fonts setup from Morrowind.ini</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="59"/>
|
||||
<source>Fonts shipped with the original engine are blurry with UI scaling and support only a small amount of characters,
|
||||
so OpenMW provides another set of fonts to avoid these issues. These fonts use TrueType technology and are quite similar
|
||||
to default Morrowind fonts. Check this box if you still prefer original fonts over OpenMW ones or if you use custom bitmap fonts.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="17"/>
|
||||
<source>Installing</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="20"/>
|
||||
<source>Please wait while Morrowind is installed on your computer.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="17"/>
|
||||
<source>Select Installation Destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="20"/>
|
||||
<source>Where should Morrowind be installed?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="47"/>
|
||||
<source>Morrowind will be installed to the following location. </source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="64"/>
|
||||
<source>Browse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IntroPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="17"/>
|
||||
<source>Welcome to the OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="23"/>
|
||||
<source>This Wizard will help you install Morrowind and its add-ons for OpenMW to use.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="17"/>
|
||||
<source>Select Morrowind Language</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="20"/>
|
||||
<source>What is the language of the Morrowind installation?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/preferences-desktop-locale.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="47"/>
|
||||
<source>Select the language of the Morrowind installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MethodSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="17"/>
|
||||
<source>Select Installation Method</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="20"/>
|
||||
<source><html><head/><body><p>Select how you would like to install <i>The Elder Scrolls III: Morrowind</i>.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="29"/>
|
||||
<source>Retail CD/DVD</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="63"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/system-installer.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="82"/>
|
||||
<source>Install from a retail disc to a new location.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="97"/>
|
||||
<source>Existing Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="128"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="141"/>
|
||||
<source>Select an existing installation.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="162"/>
|
||||
<source>Don't have a copy?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="195"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/dollar.png"/></p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="202"/>
|
||||
<source>Buy the game</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="61"/>
|
||||
<source><br><b>Could not find Morrowind.ini</b><br><br>The Wizard needs to update settings in this file.<br><br>Press "Browse..." to specify the location manually.<br></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="65"/>
|
||||
<source>B&rowse...</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="72"/>
|
||||
<source>Select configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="110"/>
|
||||
<source><b>Morrowind.bsa</b> is missing!<br>Make sure your Morrowind installation is complete.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="190"/>
|
||||
<source><br><b>There may be a more recent version of Morrowind available.</b><br><br>Do you wish to continue anyway?<br></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="185"/>
|
||||
<source>Most recent Morrowind not detected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="168"/>
|
||||
<source>Select a valid %1 installation media.<br><b>Hint</b>: make sure that it contains at least one <b>.cab</b> file.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="200"/>
|
||||
<source>There may be a more recent version of Morrowind available.<br><br>Do you wish to continue anyway?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="16"/>
|
||||
<source>&Install</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="46"/>
|
||||
<source>&Skip</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="83"/>
|
||||
<source>Morrowind (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="89"/>
|
||||
<source>Morrowind</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="97"/>
|
||||
<source>Tribunal (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="103"/>
|
||||
<source>Tribunal</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="111"/>
|
||||
<source>Bloodmoon (installed)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="117"/>
|
||||
<source>Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="137"/>
|
||||
<source>About to install Tribunal after Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="141"/>
|
||||
<source><html><head/><body><p><b>You are about to install Tribunal</b></p><p>Bloodmoon is already installed on your computer.</p><p>However, it is recommended that you install Tribunal before Bloodmoon.</p><p>Would you like to re-install Bloodmoon?</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="147"/>
|
||||
<source>Re-install &Bloodmoon</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="40"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully installed Morrowind on your computer.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="46"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully modified your existing Morrowind installation.</body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="53"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard failed to install Morrowind on your computer.</p><p>Please report any bugs you might have encountered to our <a href="https://gitlab.com/OpenMW/openmw/issues">bug tracker</a>.<br/>Make sure to include the installation log.</p><br/></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="18"/>
|
||||
<source>No existing installations detected</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="57"/>
|
||||
<source>Error detecting Morrowind configuration</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="73"/>
|
||||
<source>Morrowind configuration file (*.ini)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="92"/>
|
||||
<source>Select Morrowind.esm (located in Data Files)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="93"/>
|
||||
<source>Morrowind master file (Morrowind.esm)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="106"/>
|
||||
<source>Error detecting Morrowind files</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="161"/>
|
||||
<source><p>Attempting to install component %1.</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="162"/>
|
||||
<source>Attempting to install component %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="165"/>
|
||||
<source>%1 Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="174"/>
|
||||
<source>Select %1 installation media</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="179"/>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="209"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: The installation was aborted by the user</b></span></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="194"/>
|
||||
<source><p>Detected old version of component Morrowind.</p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="195"/>
|
||||
<source>Detected old version of component Morrowind.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="198"/>
|
||||
<source>Morrowind Installation</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="225"/>
|
||||
<source>Installation finished</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="228"/>
|
||||
<source>Installation completed successfully!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="238"/>
|
||||
<source>Installation failed!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="240"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: %1</b></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="241"/>
|
||||
<source><p><span style="color:red;"><b>%1</b></p></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="252"/>
|
||||
<source><html><head/><body><p><b>The Wizard has encountered an error</b></p><p>The error reported was:</p><p>%1</p><p>Press &quot;Show Details...&quot; for more information.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="248"/>
|
||||
<source>An error occurred</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="47"/>
|
||||
<source>Error creating destination</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="51"/>
|
||||
<source><html><head/><body><p><b>Could not create the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="68"/>
|
||||
<source><html><head/><body><p><b>Could not write to the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="82"/>
|
||||
<source><html><head/><body><p><b>The destination directory is not empty</b></p><p>An existing Morrowind installation is present in the specified location.</p><p>Please specify a different location, or go back and select the location as an existing installation.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="64"/>
|
||||
<source>Insufficient permissions</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="78"/>
|
||||
<source>Destination not empty</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="95"/>
|
||||
<source>Select where to install Morrowind</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>English</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>French</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>German</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Italian</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Polish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Russian</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Spanish</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::MainWizard</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="41"/>
|
||||
<source>OpenMW Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="94"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="118"/>
|
||||
<source>Error opening Wizard log file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="57"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="450"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="477"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for writing</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="142"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="213"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for reading</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="158"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="190"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="226"/>
|
||||
<source>Error opening OpenMW configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="380"/>
|
||||
<source>Quit Wizard</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="383"/>
|
||||
<source>Are you sure you want to exit the Wizard?</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="425"/>
|
||||
<source>Error creating OpenMW configuration directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="429"/>
|
||||
<source><html><head/><body><p><b>Could not create %1</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="446"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="473"/>
|
||||
<source>Error writing OpenMW configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::UnshieldWorker</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="177"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="196"/>
|
||||
<source>Failed to open Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="178"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="197"/>
|
||||
<source>Opening %1 failed: %2.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="203"/>
|
||||
<source>Failed to write Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="204"/>
|
||||
<source>Writing to %1 failed: %2.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="338"/>
|
||||
<source>Installing: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="367"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="775"/>
|
||||
<source>Installing: %1 directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="438"/>
|
||||
<source>Installation finished!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>Component parameter is invalid!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>An invalid component parameter was supplied.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="543"/>
|
||||
<source>Failed to find a valid archive containing %1.bsa! Retrying.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="586"/>
|
||||
<source>Installing %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>Installation media path not set!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>The source path for %1 was not set.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Cannot create temporary directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Failed to create %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="621"/>
|
||||
<source>Cannot move into temporary directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="622"/>
|
||||
<source>Failed to move into %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="631"/>
|
||||
<source>Moving installation files</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="712"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="779"/>
|
||||
<source>Could not install directory!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="713"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="780"/>
|
||||
<source>Installing %1 to %2 failed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Could not install translation file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Failed to install *%1 files.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<source>Could not install Morrowind data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="691"/>
|
||||
<source>Failed to install %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="690"/>
|
||||
<source>Could not install Morrowind configuration file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="709"/>
|
||||
<source>Installing: Sound directory</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<source>Could not find Tribunal data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="740"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Failed to find %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="739"/>
|
||||
<source>Could not find Tribunal patch file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Could not find Bloodmoon data file!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="760"/>
|
||||
<source>Updating Morrowind configuration file</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="785"/>
|
||||
<source>%1 installation finished!</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="824"/>
|
||||
<source>Extracting: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Failed to open InstallShield Cabinet File.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Opening %1 failed.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="879"/>
|
||||
<source>Failed to extract %1.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="880"/>
|
||||
<source>Complete path: %1</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
860
files/lang/wizard_ru.ts
Normal file
860
files/lang/wizard_ru.ts
Normal file
|
@ -0,0 +1,860 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="ru_RU">
|
||||
<context>
|
||||
<name>ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="17"/>
|
||||
<source>Select Components</source>
|
||||
<translation>Выбор компонентов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="20"/>
|
||||
<source>Which components should be installed?</source>
|
||||
<translation>Какие компоненты должны быть установлены?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>Select which official Morrowind expansions should be installed. For best results, it is recommended to have both expansions installed.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to install expansions later by re-running this Wizard.<br/></p></body></html></source>
|
||||
<translation><html><head/><body><p>Выберите, какие дополнения для Morrowind нужно установить. Для достижения наилучших результатов рекомендуется установить оба дополнения.</p><p><span style=" font-weight:bold;">Подсказка:</span> Можно установить дополнения позже, запустив этот Мастер установки заново.<br/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/componentselectionpage.ui" line="36"/>
|
||||
<source>Selected components:</source>
|
||||
<translation>Выбранные компоненты:</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="17"/>
|
||||
<source>Completing the OpenMW Wizard</source>
|
||||
<translation>Завершение работы Мастера установки OpenMW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/conclusionpage.ui" line="23"/>
|
||||
<source>Placeholder</source>
|
||||
<translation>Placeholder</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="17"/>
|
||||
<source>Select Existing Installation</source>
|
||||
<translation>Выбрать установленную копию игры</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="20"/>
|
||||
<source>Select an existing installation for OpenMW to use or modify.</source>
|
||||
<translation>Выбрать установленную копию игры для использования или изменения через OpenMW.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="26"/>
|
||||
<source>Detected installations:</source>
|
||||
<translation>Обнаруженные установленные копии:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/existinginstallationpage.ui" line="51"/>
|
||||
<source>Browse...</source>
|
||||
<translation>Выбрать...</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ImportPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="17"/>
|
||||
<source>Import Settings</source>
|
||||
<translation>Импортировать настройки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="20"/>
|
||||
<source>Import settings from the Morrowind installation.</source>
|
||||
<translation>Импортировать настройки из установленной копии Morrowind.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="26"/>
|
||||
<source><html><head/><body><p>OpenMW needs to import settings from the Morrowind configuration file in order to function properly.</p><p><span style=" font-weight:bold;">Note:</span> It is possible to import settings later by re-running this Wizard.</p><p/></body></html></source>
|
||||
<translation><html><head/><body><p>Чтобы OpenMW мог работать правильно, ему нужно импортировать настройки из файла с настройками Morrowind.</p><p><span style=" font-weight:bold;">Подсказка:</span> Также можно импортировать настройки позже, запустив Мастер импорта заново.</p><p/></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="36"/>
|
||||
<source>Import settings from Morrowind.ini</source>
|
||||
<translation>Импортировать настройки из Morrowind.ini</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="46"/>
|
||||
<source>Import add-on and plugin selection</source>
|
||||
<translation>Импортировать список подключенных плагинов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="56"/>
|
||||
<source>Import bitmap fonts setup from Morrowind.ini</source>
|
||||
<translation>Импортировать растровые шрифты из Morrowind.ini</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/importpage.ui" line="59"/>
|
||||
<source>Fonts shipped with the original engine are blurry with UI scaling and support only a small amount of characters,
|
||||
so OpenMW provides another set of fonts to avoid these issues. These fonts use TrueType technology and are quite similar
|
||||
to default Morrowind fonts. Check this box if you still prefer original fonts over OpenMW ones or if you use custom bitmap fonts.</source>
|
||||
<translation>Шрифты, поставляемые с оригинальной игрой, становятся размытыми при масштабировании интерфейса и поддерживают ограниченное количество символов,
|
||||
поэтому в комплекте с OpenMW идет набор шрифтов, не имеющих этих проблем. Они используют технологию TrueType и весьма похожи на шрифты Morrowind.
|
||||
Включите эту опцию, если вы все равно хотите использовать оригинальные шрифты вместо шрифтов OpenMW, или если вы используете сторонние растровые шрифты.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="17"/>
|
||||
<source>Installing</source>
|
||||
<translation>Установка</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationpage.ui" line="20"/>
|
||||
<source>Please wait while Morrowind is installed on your computer.</source>
|
||||
<translation>Пожалуйста, подождите, пока Morrowind устанавливается на ваш компьютер.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="17"/>
|
||||
<source>Select Installation Destination</source>
|
||||
<translation>Выберите путь для установки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="20"/>
|
||||
<source>Where should Morrowind be installed?</source>
|
||||
<translation>Куда нужно установить Morrowind?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="47"/>
|
||||
<source>Morrowind will be installed to the following location. </source>
|
||||
<translation>Morrowind будет установлен в следующее место.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/installationtargetpage.ui" line="64"/>
|
||||
<source>Browse...</source>
|
||||
<translation>Выбрать...</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>IntroPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="17"/>
|
||||
<source>Welcome to the OpenMW Wizard</source>
|
||||
<translation>Добро пожаловать в Мастер установки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/intropage.ui" line="23"/>
|
||||
<source>This Wizard will help you install Morrowind and its add-ons for OpenMW to use.</source>
|
||||
<translation>Этот Мастер поможет вам установить Morrowind и его дополнения, чтобы OpenMW мог их использовать.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="17"/>
|
||||
<source>Select Morrowind Language</source>
|
||||
<translation>Выберите язык вашей копии Morrowind</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="20"/>
|
||||
<source>What is the language of the Morrowind installation?</source>
|
||||
<translation>Какой язык использует ваша копия Morrowind?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="34"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/preferences-desktop-locale.png"/></p></body></html></source>
|
||||
<translation>><html><head/><body><p><img src=":/icons/tango/48x48/preferences-desktop-locale.png"/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/languageselectionpage.ui" line="47"/>
|
||||
<source>Select the language of the Morrowind installation.</source>
|
||||
<translation>Выберите язык, используемый вашей копией Morrowind.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MethodSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="14"/>
|
||||
<source>WizardPage</source>
|
||||
<translation>WizardPage</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="17"/>
|
||||
<source>Select Installation Method</source>
|
||||
<translation>Выберите способ установки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="20"/>
|
||||
<source><html><head/><body><p>Select how you would like to install <i>The Elder Scrolls III: Morrowind</i>.</p></body></html></source>
|
||||
<translation><html><head/><body><p>Выберите способ установки <i>The Elder Scrolls III: Morrowind</i>.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="29"/>
|
||||
<source>Retail CD/DVD</source>
|
||||
<translation>CD/DVD-диск</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="63"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/system-installer.png"/></p></body></html></source>
|
||||
<translation><html><head/><body><p><img src=":/icons/tango/48x48/system-installer.png"/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="82"/>
|
||||
<source>Install from a retail disc to a new location.</source>
|
||||
<translation>Установить игру с диска</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="97"/>
|
||||
<source>Existing Installation</source>
|
||||
<translation>Установленная копия игры</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="128"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></source>
|
||||
<translation><html><head/><body><p><img src=":/icons/tango/48x48/folder.png"/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="141"/>
|
||||
<source>Select an existing installation.</source>
|
||||
<translation>Выбрать установленную копию игры.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="162"/>
|
||||
<source>Don't have a copy?</source>
|
||||
<translation>Нет копии игры?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="195"/>
|
||||
<source><html><head/><body><p><img src=":/icons/tango/48x48/dollar.png"/></p></body></html></source>
|
||||
<translation><html><head/><body><p><img src=":/icons/tango/48x48/dollar.png"/></p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/ui/methodselectionpage.ui" line="202"/>
|
||||
<source>Buy the game</source>
|
||||
<translation>Купить игру</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="61"/>
|
||||
<source><br><b>Could not find Morrowind.ini</b><br><br>The Wizard needs to update settings in this file.<br><br>Press "Browse..." to specify the location manually.<br></source>
|
||||
<translation><br><b>Не удалось найти Morrowind.ini</b><br><br>Мастеру требуется обновить настройки в этом файле.<br><br>Нажмите "Выбрать...", чтобы задать местоположение файла вручную.<br></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="65"/>
|
||||
<source>B&rowse...</source>
|
||||
<translation>&Выбрать...</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="72"/>
|
||||
<source>Select configuration file</source>
|
||||
<translation>Выберите файл с настройками</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="110"/>
|
||||
<source><b>Morrowind.bsa</b> is missing!<br>Make sure your Morrowind installation is complete.</source>
|
||||
<translation><b>Morrowind.bsa</b> не найден!<br>Убедитесь, что Morrowind был установлен правильно.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="190"/>
|
||||
<source><br><b>There may be a more recent version of Morrowind available.</b><br><br>Do you wish to continue anyway?<br></source>
|
||||
<translation><br><b>Может существовать более свежая версия Morrowind.</b><br><br>Все равно продолжить?<br></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="185"/>
|
||||
<source>Most recent Morrowind not detected</source>
|
||||
<translation>Актуальная версия Morrowind не найдена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="168"/>
|
||||
<source>Select a valid %1 installation media.<br><b>Hint</b>: make sure that it contains at least one <b>.cab</b> file.</source>
|
||||
<translation>Выберите корректный установочный дистрибутив %1.<br><b>Подсказка</b>: он должен содержать как минимум один <b>.cab</b>-файл.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="200"/>
|
||||
<source>There may be a more recent version of Morrowind available.<br><br>Do you wish to continue anyway?</source>
|
||||
<translation>Может существовать более свежая версия Morrowind.<br><br>Все равно продолжить?</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ComponentSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="16"/>
|
||||
<source>&Install</source>
|
||||
<translation>&Установить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="46"/>
|
||||
<source>&Skip</source>
|
||||
<translation>&Пропустить</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="83"/>
|
||||
<source>Morrowind (installed)</source>
|
||||
<translation>Morrowind (установлен)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="89"/>
|
||||
<source>Morrowind</source>
|
||||
<translation>Morrowind</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="97"/>
|
||||
<source>Tribunal (installed)</source>
|
||||
<translation>Tribunal (установлен)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="103"/>
|
||||
<source>Tribunal</source>
|
||||
<translation>Tribunal</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="111"/>
|
||||
<source>Bloodmoon (installed)</source>
|
||||
<translation>Bloodmoon (установлен)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="117"/>
|
||||
<source>Bloodmoon</source>
|
||||
<translation>Bloodmoon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="137"/>
|
||||
<source>About to install Tribunal after Bloodmoon</source>
|
||||
<translation>Попытка установить Tribunal после Bloodmoon</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="141"/>
|
||||
<source><html><head/><body><p><b>You are about to install Tribunal</b></p><p>Bloodmoon is already installed on your computer.</p><p>However, it is recommended that you install Tribunal before Bloodmoon.</p><p>Would you like to re-install Bloodmoon?</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Вы собираетесь установить Tribunal</b></p><p>Bloodmoon уже установлен на ваш компьютер.</p><p>Tribunal рекомендуется устанавлить перед установкой Bloodmoon.</p><p>Желаете ли вы переустановить Bloodmoon?</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/componentselectionpage.cpp" line="147"/>
|
||||
<source>Re-install &Bloodmoon</source>
|
||||
<translation>Переустановить &Bloodmoon</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ConclusionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="40"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully installed Morrowind on your computer.</p></body></html></source>
|
||||
<translation><html><head/><body><p>Мастер OpenMW успешно установил Morrowind на ваш компьютер.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="46"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard successfully modified your existing Morrowind installation.</body></html></source>
|
||||
<translation><html><head/><body><p>Мастер OpenMW успешно завершил изменение вашей установленной копии Morrowind.</body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/conclusionpage.cpp" line="53"/>
|
||||
<source><html><head/><body><p>The OpenMW Wizard failed to install Morrowind on your computer.</p><p>Please report any bugs you might have encountered to our <a href="https://gitlab.com/OpenMW/openmw/issues">bug tracker</a>.<br/>Make sure to include the installation log.</p><br/></body></html></source>
|
||||
<translation><html><head/><body><p>Мастеру OpenMW не удалось установить Morrowind на ваш компьютер.</p><p>Пожалуйста, сообщите о встреченных вами ошибках на наш <a href="https://gitlab.com/OpenMW/openmw/issues">багтрекер</a>.<br/>Не забудьте включить туда лог установки.</p><br/></body></html></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::ExistingInstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="18"/>
|
||||
<source>No existing installations detected</source>
|
||||
<translation>Установленные копии игры не найдены</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="57"/>
|
||||
<source>Error detecting Morrowind configuration</source>
|
||||
<translation>Попытка найти настройки Morrowind завершилась ошибкой</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="73"/>
|
||||
<source>Morrowind configuration file (*.ini)</source>
|
||||
<translation>Файл настроек Morrowind (*.ini)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="92"/>
|
||||
<source>Select Morrowind.esm (located in Data Files)</source>
|
||||
<translation>Выберите Morrowind.esm (расположен в Data Files)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="93"/>
|
||||
<source>Morrowind master file (Morrowind.esm)</source>
|
||||
<translation>Мастер-файл Morrowind (Morrowind.esm)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/existinginstallationpage.cpp" line="106"/>
|
||||
<source>Error detecting Morrowind files</source>
|
||||
<translation>Не удалось обнаружить файлы Morrowind</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="161"/>
|
||||
<source><p>Attempting to install component %1.</p></source>
|
||||
<translation><p>Попытка установить компонент %1.</p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="162"/>
|
||||
<source>Attempting to install component %1.</source>
|
||||
<translation>Попытка установить компонент %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="165"/>
|
||||
<source>%1 Installation</source>
|
||||
<translation>Установка %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="174"/>
|
||||
<source>Select %1 installation media</source>
|
||||
<translation>Выберите установочный дистрибутив %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="179"/>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="209"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: The installation was aborted by the user</b></span></p></source>
|
||||
<translation><p><br/><span style="color:red;"><b>Ошибка: Установка была прервана пользователем</b></span></p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="194"/>
|
||||
<source><p>Detected old version of component Morrowind.</p></source>
|
||||
<translation>lt;p>Обнаружена устаревшая версия компонента Morrowind.</p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="195"/>
|
||||
<source>Detected old version of component Morrowind.</source>
|
||||
<translation>Обнаружена устаревшая версия компонента Morrowind.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="198"/>
|
||||
<source>Morrowind Installation</source>
|
||||
<translation>Установка Morrowind</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="225"/>
|
||||
<source>Installation finished</source>
|
||||
<translation>Установка завершена</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="228"/>
|
||||
<source>Installation completed successfully!</source>
|
||||
<translation>Установка успешно завершена!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="238"/>
|
||||
<source>Installation failed!</source>
|
||||
<translation>Установка не удалась!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="240"/>
|
||||
<source><p><br/><span style="color:red;"><b>Error: %1</b></p></source>
|
||||
<translation><p><br/><span style="color:red;"><b>Ошибка: %1</b></p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="241"/>
|
||||
<source><p><span style="color:red;"><b>%1</b></p></source>
|
||||
<translation><p><span style="color:red;"><b>%1</b></p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="252"/>
|
||||
<source><html><head/><body><p><b>The Wizard has encountered an error</b></p><p>The error reported was:</p><p>%1</p><p>Press &quot;Show Details...&quot; for more information.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>При работе Мастера возникла ошибка</b></p><p>Обнаруженная ошибка:</p><p>%1</p><p>Нажмите &quot;Показать детали...&quot; для получения дополнительной информации.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationpage.cpp" line="248"/>
|
||||
<source>An error occurred</source>
|
||||
<translation>Произошла ошибка</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::InstallationTargetPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="47"/>
|
||||
<source>Error creating destination</source>
|
||||
<translation>Не удалось создать директорию назначения</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="51"/>
|
||||
<source><html><head/><body><p><b>Could not create the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось создать директорию назначения</b></p><p>Пожалуйста, проверьте права доступа и повторите попытку, или же выберите другую директорию.</p></body></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="68"/>
|
||||
<source><html><head/><body><p><b>Could not write to the destination directory</b></p><p>Please make sure you have the right permissions and try again, or specify a different location.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось записать данные в директорию назначения</b></p><p>Пожалуйста, проверьте права доступа и повторите попытку, или же выберите другую директорию.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="82"/>
|
||||
<source><html><head/><body><p><b>The destination directory is not empty</b></p><p>An existing Morrowind installation is present in the specified location.</p><p>Please specify a different location, or go back and select the location as an existing installation.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Директория назначения содержит файлы</b></p><p>В указанной директории найдена установленная копия Morrowind.</p><p>Пожалуйста, выберите другую директорию, или же вернитесь на предыдущий шаг и выберите подключение установленной копии игры.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="64"/>
|
||||
<source>Insufficient permissions</source>
|
||||
<translation>Не хватает прав доступа</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="78"/>
|
||||
<source>Destination not empty</source>
|
||||
<translation>Выбранная директория не пустая</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/installationtargetpage.cpp" line="95"/>
|
||||
<source>Select where to install Morrowind</source>
|
||||
<translation>Выберите, куда установить Morrowind</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::LanguageSelectionPage</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>English</source>
|
||||
<translation>Английский</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="17"/>
|
||||
<source>French</source>
|
||||
<translation>Французский</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>German</source>
|
||||
<translation>Немецкий</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Italian</source>
|
||||
<translation>Итальянский</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="18"/>
|
||||
<source>Polish</source>
|
||||
<translation>Польский</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Russian</source>
|
||||
<translation>Русский</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/languageselectionpage.cpp" line="19"/>
|
||||
<source>Spanish</source>
|
||||
<translation>Испанский</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::MainWizard</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="41"/>
|
||||
<source>OpenMW Wizard</source>
|
||||
<translation>Мастер OpenMW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="94"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="118"/>
|
||||
<source>Error opening Wizard log file</source>
|
||||
<translation>Не удалось открыть лог-файл Мастера</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="57"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="450"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="477"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for writing</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось открыть %1 для записи</b></p><p>Пожалуйста, проверьте права доступа и повторите попытку.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="142"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="213"/>
|
||||
<source><html><head/><body><p><b>Could not open %1 for reading</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось открыть %1 для чтения</b></p><p>Пожалуйста, проверьте права доступа и повторите попытку.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="158"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="190"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="226"/>
|
||||
<source>Error opening OpenMW configuration file</source>
|
||||
<translation>Не удалось открыть файл с настройками OpenMW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="380"/>
|
||||
<source>Quit Wizard</source>
|
||||
<translation>Завершить работу Мастера</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="383"/>
|
||||
<source>Are you sure you want to exit the Wizard?</source>
|
||||
<translation>Вы уверены, что хотите завершить работу Мастера?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="425"/>
|
||||
<source>Error creating OpenMW configuration directory</source>
|
||||
<translation>Не удалось создать директорию для настроек OpenMW</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="429"/>
|
||||
<source><html><head/><body><p><b>Could not create %1</b></p><p>Please make sure you have the right permissions and try again.</p></body></html></source>
|
||||
<translation><html><head/><body><p><b>Не удалось создать %1</b></p><p>Пожалуйста, проверьте права доступа и повторите попытку.</p></body></html></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="446"/>
|
||||
<location filename="../../apps/wizard/mainwizard.cpp" line="473"/>
|
||||
<source>Error writing OpenMW configuration file</source>
|
||||
<translation>Не удалось записать данные в файл с настройками OpenMW</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Wizard::UnshieldWorker</name>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="177"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="196"/>
|
||||
<source>Failed to open Morrowind configuration file!</source>
|
||||
<translation>Не удалось открыть файл с настройками Morrowind!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="178"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="197"/>
|
||||
<source>Opening %1 failed: %2.</source>
|
||||
<translation>Попытка открыть %1 не удалась: %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="203"/>
|
||||
<source>Failed to write Morrowind configuration file!</source>
|
||||
<translation>Не удалось записать данные в файл с настройками Morrowind!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="204"/>
|
||||
<source>Writing to %1 failed: %2.</source>
|
||||
<translation>Запись в %1 завершилась с ошибкой: %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="338"/>
|
||||
<source>Installing: %1</source>
|
||||
<translation>Установка: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="367"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="775"/>
|
||||
<source>Installing: %1 directory</source>
|
||||
<translation>Установка: директория %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="438"/>
|
||||
<source>Installation finished!</source>
|
||||
<translation>Установка завершена!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>Component parameter is invalid!</source>
|
||||
<translation>Некорректный параметр для компонента!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="462"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="582"/>
|
||||
<source>An invalid component parameter was supplied.</source>
|
||||
<translation>Задан некорректный параметр для компонента.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="543"/>
|
||||
<source>Failed to find a valid archive containing %1.bsa! Retrying.</source>
|
||||
<translation>Не удалось найти архив, содержащий %1.bsa! Повторная попытка.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="586"/>
|
||||
<source>Installing %1</source>
|
||||
<translation>Установка %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>Installation media path not set!</source>
|
||||
<translation>путь к установочному дистрибутиву не задан!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="592"/>
|
||||
<source>The source path for %1 was not set.</source>
|
||||
<translation>Исходный пусть для %1 не задан.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Cannot create temporary directory!</source>
|
||||
<translation>Не удалось создать временную директорию!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="606"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="615"/>
|
||||
<source>Failed to create %1.</source>
|
||||
<translation>Не удалось создать %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="621"/>
|
||||
<source>Cannot move into temporary directory!</source>
|
||||
<translation>Не удалось переместить во временную директорию!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="622"/>
|
||||
<source>Failed to move into %1.</source>
|
||||
<translation>Не удалось переместить в %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="631"/>
|
||||
<source>Moving installation files</source>
|
||||
<translation>Перемещение файлов установки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="712"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="779"/>
|
||||
<source>Could not install directory!</source>
|
||||
<translation>Не удалось установить директорию!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="644"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="655"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="713"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="780"/>
|
||||
<source>Installing %1 to %2 failed.</source>
|
||||
<translation>Не удалось установить %1 в %2.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Could not install translation file!</source>
|
||||
<translation>Не удалось установить файл с переводом!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="668"/>
|
||||
<source>Failed to install *%1 files.</source>
|
||||
<translation>Не удалось установить файлы *%1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<source>Could not install Morrowind data file!</source>
|
||||
<translation>Не удалось установить файл с данными Morrowind!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="682"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="691"/>
|
||||
<source>Failed to install %1.</source>
|
||||
<translation>Не удалось установить %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="690"/>
|
||||
<source>Could not install Morrowind configuration file!</source>
|
||||
<translation>Не удалось установить файл с настройками Morrowind!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="709"/>
|
||||
<source>Installing: Sound directory</source>
|
||||
<translation>Установка: директория Sound</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<source>Could not find Tribunal data file!</source>
|
||||
<translation>Не удалось найти файл с данными Tribunal!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="725"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="740"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Failed to find %1.</source>
|
||||
<translation>Не удалось найти %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="739"/>
|
||||
<source>Could not find Tribunal patch file!</source>
|
||||
<translation>Не удалось найти файл с патчем для Tribunal!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="752"/>
|
||||
<source>Could not find Bloodmoon data file!</source>
|
||||
<translation>Не удалось найти файл с данными Bloodmoon!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="760"/>
|
||||
<source>Updating Morrowind configuration file</source>
|
||||
<translation>Обновление файла с настройками Morrowind</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="785"/>
|
||||
<source>%1 installation finished!</source>
|
||||
<translation>Установка %1 завершена!</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="824"/>
|
||||
<source>Extracting: %1</source>
|
||||
<translation>Извлечение: %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Failed to open InstallShield Cabinet File.</source>
|
||||
<translation>Не удалось открыть файл InstallShield Cabinet.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="850"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="983"/>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="1021"/>
|
||||
<source>Opening %1 failed.</source>
|
||||
<translation>Не удалось открыть %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="879"/>
|
||||
<source>Failed to extract %1.</source>
|
||||
<translation>Не удалось извлечь %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../../apps/wizard/unshield/unshieldworker.cpp" line="880"/>
|
||||
<source>Complete path: %1</source>
|
||||
<translation>Полный путь: %1</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -19,7 +19,7 @@
|
|||
-- @function [parent=#core] quit
|
||||
|
||||
---
|
||||
-- Send an event to global scripts.
|
||||
-- Send an event to global scripts. Note: in menu scripts, errors if the game is not running (check @{openmw.menu#menu.getState})
|
||||
-- @function [parent=#core] sendGlobalEvent
|
||||
-- @param #string eventName
|
||||
-- @param eventData
|
||||
|
|
Loading…
Reference in a new issue