Selaa lähdekoodia

Merge branch 'master' into 'develop'

Ivan Savenko 9 kuukautta sitten
vanhempi
sitoutus
543e241769
63 muutettua tiedostoa jossa 1233 lisäystä ja 769 poistoa
  1. 20 7
      AI/BattleAI/BattleEvaluator.cpp
  2. 5 1
      AI/Nullkiller/AIGateway.cpp
  3. 6 9
      AI/Nullkiller/Analyzers/BuildAnalyzer.cpp
  4. 34 0
      ChangeLog.md
  5. 1 0
      Mods/vcmi/Content/config/english.json
  6. 1 1
      Mods/vcmi/Content/config/ukrainian.json
  7. 2 1
      client/NetPacksLobbyClient.cpp
  8. 5 2
      client/adventureMap/CList.cpp
  9. 1 1
      client/battle/BattleInterfaceClasses.cpp
  10. 1 1
      client/eventsSDL/InputHandler.cpp
  11. 14 0
      client/eventsSDL/InputSourceKeyboard.cpp
  12. 2 0
      client/eventsSDL/InputSourceKeyboard.h
  13. 32 3
      client/lobby/CBonusSelection.cpp
  14. 8 1
      client/lobby/CBonusSelection.h
  15. 8 1
      client/lobby/CLobbyScreen.cpp
  16. 3 1
      client/lobby/CLobbyScreen.h
  17. 8 1
      client/lobby/CSelectionBase.cpp
  18. 3 0
      client/lobby/OptionsTab.cpp
  19. 3 0
      client/render/IImage.h
  20. 5 0
      client/renderSDL/ImageScaled.cpp
  21. 1 0
      client/renderSDL/ImageScaled.h
  22. 21 9
      client/renderSDL/SDLImage.cpp
  23. 2 0
      client/renderSDL/SDLImage.h
  24. 60 8
      client/windows/CCastleInterface.cpp
  25. 3 0
      client/windows/CCastleInterface.h
  26. 23 1
      clientapp/EntryPoint.cpp
  27. 1 1
      cmake_modules/VersionDefinition.cmake
  28. 6 1
      config/schemas/settings.json
  29. 6 0
      debian/changelog
  30. 1 0
      docs/Readme.md
  31. 1 0
      launcher/eu.vcmi.VCMI.metainfo.xml
  32. 5 5
      launcher/innoextract.cpp
  33. 7 1
      launcher/modManager/cmodlistview_moc.cpp
  34. 1 1
      launcher/modManager/modstatecontroller.cpp
  35. 14 0
      launcher/settingsView/csettingsview_moc.cpp
  36. 2 0
      launcher/settingsView/csettingsview_moc.h
  37. 76 53
      launcher/settingsView/csettingsview_moc.ui
  38. 55 49
      launcher/translation/chinese.ts
  39. 60 50
      launcher/translation/czech.ts
  40. 52 44
      launcher/translation/english.ts
  41. 53 45
      launcher/translation/french.ts
  42. 57 49
      launcher/translation/german.ts
  43. 59 49
      launcher/translation/polish.ts
  44. 57 49
      launcher/translation/portuguese.ts
  45. 59 49
      launcher/translation/russian.ts
  46. 52 44
      launcher/translation/spanish.ts
  47. 53 45
      launcher/translation/swedish.ts
  48. 68 50
      launcher/translation/ukrainian.ts
  49. 50 44
      launcher/translation/vietnamese.ts
  50. 51 57
      lib/CConsoleHandler.cpp
  51. 2 1
      lib/CCreatureSet.h
  52. 1 1
      lib/bonuses/IBonusBearer.cpp
  53. 6 6
      lib/entities/faction/CTownHandler.cpp
  54. 8 0
      lib/mapObjects/CGTownInstance.cpp
  55. 12 0
      lib/modding/IdentifierStorage.cpp
  56. 6 0
      lib/modding/IdentifierStorage.h
  57. 17 4
      lib/modding/ModManager.cpp
  58. 1 0
      lib/modding/ModManager.h
  59. 1 1
      lib/rmg/Functions.cpp
  60. 5 0
      lib/rmg/RmgObject.cpp
  61. 8 4
      lib/rmg/modificators/ObjectManager.cpp
  62. 22 12
      lib/rmg/modificators/RoadPlacer.cpp
  63. 26 6
      server/NetPacksLobbyServer.cpp

+ 20 - 7
AI/BattleAI/BattleEvaluator.cpp

@@ -702,7 +702,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 				spells::BattleCast cast(state.get(), hero, spells::Mode::HERO, ps.spell);
 				cast.castEval(state->getServerCallback(), ps.dest);
 
-				auto allUnits = state->battleGetUnitsIf([](const battle::Unit * u) -> bool { return u->isValidTarget(); });
+				auto allUnits = state->battleGetUnitsIf([](const battle::Unit * u) -> bool { return u->isValidTarget(true); });
 
 				auto needFullEval = vstd::contains_if(allUnits, [&](const battle::Unit * u) -> bool
 					{
@@ -720,6 +720,10 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 					state->makeWait(activeStack);
 				}
 
+				float stackActionScore = 0;
+				float damageToHostilesScore = 0;
+				float damageToFriendliesScore = 0;
+
 				if(needFullEval || !cachedAttack.ap)
 				{
 #if BATTLE_TRACE_LEVEL >= 1
@@ -737,11 +741,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 					{
 						auto newStackAction = innerEvaluator.findBestTarget(activeStack, innerTargets, innerCache, state);
 
-						ps.value = std::max(moveTarget.score, newStackAction.score);
+						stackActionScore = std::max(moveTarget.score, newStackAction.score);
 					}
 					else
 					{
-						ps.value = moveTarget.score;
+						stackActionScore = moveTarget.score;
 					}
 				}
 				else
@@ -756,7 +760,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 
 					auto updatedAttack = AttackPossibility::evaluate(updatedBai, cachedAttack.ap->from, innerCache, state);
 
-					ps.value = scoreEvaluator.evaluateExchange(updatedAttack, cachedAttack.turn, *targets, innerCache, state);
+					stackActionScore = scoreEvaluator.evaluateExchange(updatedAttack, cachedAttack.turn, *targets, innerCache, state);
 				}
 				for(const auto & unit : allUnits)
 				{
@@ -790,11 +794,11 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 							if(ourUnit && goodEffect && isMagical)
 								continue;
 
-							ps.value += dpsReduce * scoreEvaluator.getPositiveEffectMultiplier();
+							damageToHostilesScore += dpsReduce * scoreEvaluator.getPositiveEffectMultiplier();
 						}
 						else
 							// discourage AI making collateral damage with spells
-							ps.value -= 4 * dpsReduce * scoreEvaluator.getNegativeEffectMultiplier();
+							damageToFriendliesScore -= 4 * dpsReduce * scoreEvaluator.getNegativeEffectMultiplier();
 
 #if BATTLE_TRACE_LEVEL >= 1
 						// Ensure ps.dest is not empty before accessing the first element
@@ -826,8 +830,17 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 					}
 				}
 
+				if (vstd::isAlmostEqual(stackActionScore, static_cast<float>(EvaluationResult::INEFFECTIVE_SCORE)))
+				{
+					ps.value = damageToFriendliesScore + damageToHostilesScore;
+				}
+				else
+				{
+					ps.value = stackActionScore + damageToFriendliesScore + damageToHostilesScore;
+				}
+
 #if BATTLE_TRACE_LEVEL >= 1
-				logAi->trace("Total score: %2f", ps.value);
+				logAi->trace("Total score for %s: %2f (action: %2f, friedly damage: %2f, hostile damage: %2f)", ps.spell->getJsonKey(), ps.value, stackActionScore, damageToFriendliesScore, damageToHostilesScore);
 #endif
 			}
 #if BATTLE_TRACE_LEVEL == 0

+ 5 - 1
AI/Nullkiller/AIGateway.cpp

@@ -805,7 +805,11 @@ bool AIGateway::makePossibleUpgrades(const CArmedInstance * obj)
 						{
 							return id.toCreature()->getAIValue();
 						});
-					if(nullkiller->getFreeResources().canAfford(upgradeInfo.getUpgradeCostsFor(upgID) * s->count))
+
+					int oldValue = s->getCreature()->getAIValue();
+					int newValue = upgID.toCreature()->getAIValue();
+
+					if(newValue > oldValue && nullkiller->getFreeResources().canAfford(upgradeInfo.getUpgradeCostsFor(upgID) * s->count))
 					{
 						myCb->upgradeCreature(obj, SlotID(i), upgID);
 						upgraded = true;

+ 6 - 9
AI/Nullkiller/Analyzers/BuildAnalyzer.cpp

@@ -17,13 +17,9 @@ namespace NKAI
 
 void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
 {
-	auto townInfo = developmentInfo.town->getTown();
-	auto creatures = townInfo->creatures;
-	auto buildings = townInfo->getAllBuildings();
-
 	std::map<BuildingID, BuildingID> parentMap;
 
-	for(auto &pair : townInfo->buildings)
+	for(auto &pair : developmentInfo.town->getTown()->buildings)
 	{
 		if(pair.second->upgrade != BuildingID::NONE)
 		{
@@ -36,13 +32,14 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
 		logAi->trace("Checking dwelling level %d", level);
 		BuildingInfo nextToBuild = BuildingInfo();
 
-		for(int upgradeIndex : {2, 1, 0})
+		BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
+
+		for(; developmentInfo.town->getBuildings().count(buildID); BuildingID::advanceDwelling(buildID))
 		{
-			BuildingID building = BuildingID(BuildingID::getDwellingFromLevel(level, upgradeIndex));
-			if(!vstd::contains(buildings, building))
+			if(!developmentInfo.town->hasBuilt(buildID))
 				continue; // no such building in town
 
-			auto info = getBuildingOrPrerequisite(developmentInfo.town, building);
+			auto info = getBuildingOrPrerequisite(developmentInfo.town, buildID);
 
 			if(info.exists)
 			{

+ 34 - 0
ChangeLog.md

@@ -1,5 +1,39 @@
 # VCMI Project Changelog
 
+## 1.6.1 -> 1.6.2
+
+### General
+
+* Holding Alt while in town will now highlight all interactive buildings in town
+* Fixed missing surrender video on battle results dialog
+* Game will no longer show custom campaigns dialog for short period when selecting Heroes III campaign
+* Added workaround for right mouse button being recognized as 'back' button on some Android devices
+* Fixed regression that caused second and further upgrades that were not functioning correctly
+* Fixed regression that sometime caused curved path that leads to a blocked monolith in random map generation
+* Fixed regression that broke several mechanics, such as issues with Legion artifacts or with Gelu/Dracon specialties
+* Fixed broken positioning for some images when selected scaling factor is different from prescaled texture factor
+
+### Stability
+
+* Game will now show list of mods with critical issues that might cause crash after game start
+* Fixed crash in map editor on attempt to copy wandering monster
+* Fixed crash on having unsupported mod (e.g. Era mod) in a preset
+* Fixed crash on attempt to update a mod that depends on unknown mod that is not installed or not available in repository
+* Fixed possible crash on attempt to flip an empty image
+* Fixed possible crash on attempt to remove old saves
+
+### Campaigns
+
+* Game will now select correct scenario in campaigns with multiple available scenarios
+* Added blink animation for campaign scenario selection
+
+### AI
+
+* Nullkiller AI will now only upgrade units if this would increase their AI value. Fixes possible freeze on upgrading units in some mods that can be upgraded in both directions
+* Nullkiller AI will no longer attempt to build Mage Guild of 4th or 5th levels in towns without such guild
+* Battle AI now correctly estimates damage for spells that completely eliminate a unit
+* Fixed bug preventing AI from casting damaging spells if his troops are unable to reach enemies, for example during siege
+
 ## 1.6.0 -> 1.6.1
 
 ### General

+ 1 - 0
Mods/vcmi/Content/config/english.json

@@ -222,6 +222,7 @@
 
 	"vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s",
 	"vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.",
+	"vcmi.client.errors.modLoadingFailure" : "{Mod loading failure}\n\nCritical issues found when loading mods! Game may not work correctly or crash! Please update or disable following mods:\n\n",
 	"vcmi.server.errors.disconnected" : "{Network Error}\n\nConnection to game server has been lost!",
 	"vcmi.server.errors.playerLeft" : "{Player Left}\n\n%s player have disconnected from the game!", //%s -> player color
 	"vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",

+ 1 - 1
Mods/vcmi/Content/config/ukrainian.json

@@ -109,7 +109,6 @@
 	"vcmi.lobby.noUnderground" : "немає підземелля",
 	"vcmi.lobby.sortDate" : "Сортувати мапи за датою зміни",
 	"vcmi.lobby.backToLobby" : "Назад до лобі",
-
 	"vcmi.lobby.author" : "Автор",
 	"vcmi.lobby.handicap" : "Гандикап",
 	"vcmi.lobby.handicap.resource" : "Дає гравцям відповідні ресурси для початку гри на додаток до звичних стартових ресурсів. Від'ємні значення дозволені, але обмежені загальним значенням 0 (гравець ніколи не починає з від'ємними ресурсами).",
@@ -223,6 +222,7 @@
 
 	"vcmi.client.errors.invalidMap" : "{Пошкоджена карта або кампанія}\n\nНе вдалося запустити гру! Вибрана карта або кампанія може бути невірною або пошкодженою. Причина:\n%s",
 	"vcmi.client.errors.missingCampaigns" : "{Не вистачає файлів даних}\n\nФайли даних кампаній не знайдено! Можливо, ви використовуєте неповні або пошкоджені файли даних Heroes 3. Будь ласка, перевстановіть дані гри.",
+	"vcmi.client.errors.modLoadingFailure" : "{Помилка завантаження модифікації}\n\nВиявлено критичні проблеми при завантаженні модифікацій! Гра може працювати некоректно або аварійно завершитись! Будь ласка, оновіть або вимкніть наступні моди:\n\n",
 	"vcmi.server.errors.disconnected" : "{Помилка мережі}\n\nВтрачено зв'язок з сервером гри!",
 	"vcmi.server.errors.playerLeft" : "{Гравець покинув гру}\n\n%s гравець від'єднався від гри!", //%s -> player color
 	"vcmi.server.errors.existingProcess" : "Працює інший процес vcmiserver, будь ласка, спочатку завершіть його",

+ 2 - 1
client/NetPacksLobbyClient.cpp

@@ -78,7 +78,8 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
 				GH.windows().popWindows(1);
 			}
 
-			GH.windows().createAndPushWindow<CLobbyScreen>(handler.screenType);
+			bool hideScreen = handler.campaignStateToSend && (!handler.campaignStateToSend->campaignSet.empty() || handler.campaignStateToSend->lastScenario());
+			GH.windows().createAndPushWindow<CLobbyScreen>(handler.screenType, hideScreen);
 		}
 		handler.setState(EClientState::LOBBY);
 	}

+ 5 - 2
client/adventureMap/CList.cpp

@@ -471,8 +471,11 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
 	int townLowerPos = (townIndex > towns.size() - 2) ? -1 : townIndex + 1;
 
 	auto updateList = [](){
-		for (auto ki : GH.windows().findWindows<CCastleInterface>())
-			ki->townChange(); //update list
+		for (auto ci : GH.windows().findWindows<CCastleInterface>())
+		{
+			ci->townlist->updateWidget();
+			ci->townlist->select(ci->town);
+		}
 	};
 
 	std::vector<RadialMenuConfig> menuElements = {

+ 1 - 1
client/battle/BattleInterfaceClasses.cpp

@@ -908,7 +908,7 @@ BattleResultResources BattleResultWindow::getResources(const BattleResult & br)
 		case EBattleResult::SURRENDER:
 			resources.resultText.appendTextID("core.genrltxt.309");
 			resources.musicName = AudioPath::builtin("Music/Surrender Battle");
-			resources.prologueVideo = VideoPath();
+			resources.prologueVideo = VideoPath::builtin("SURRENDER.BIK");
 			resources.loopedVideo = VideoPath::builtin("SURRENDER.BIK");
 			break;
 		default:

+ 1 - 1
client/eventsSDL/InputHandler.cpp

@@ -211,7 +211,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 			return;
 		}
 
-		if(ev.key.keysym.scancode == SDL_SCANCODE_AC_BACK)
+		if(ev.key.keysym.scancode == SDL_SCANCODE_AC_BACK && !settings["input"]["handleBackRightMouseButton"].Bool())
 		{
 			boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
 			handleQuit(true);

+ 14 - 0
client/eventsSDL/InputSourceKeyboard.cpp

@@ -25,11 +25,13 @@
 #include <SDL_hints.h>
 
 InputSourceKeyboard::InputSourceKeyboard()
+: handleBackRightMouseButton(settings["input"]["handleBackRightMouseButton"].Bool())
 {
 #ifdef VCMI_MAC
 	// Ctrl+click should be treated as a right click on Mac OS X
 	SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
 #endif
+	SDL_SetHint(SDL_HINT_ANDROID_TRAP_BACK_BUTTON, handleBackRightMouseButton ? "1" : "0");
 }
 
 std::string InputSourceKeyboard::getKeyNameWithModifiers(const std::string & keyName, bool keyUp)
@@ -80,6 +82,12 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 			return; // ignore periodic event resends
 	}
 
+	if(handleBackRightMouseButton && key.keysym.scancode ==  SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
+	{
+		GH.events().dispatchShowPopup(GH.getCursorPosition(), settings["input"]["mouseToleranceDistance"].Integer());
+		return;
+	}
+
 	auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
 
 	if (vstd::contains(shortcutsVector, EShortcut::MAIN_MENU_LOBBY))
@@ -118,6 +126,12 @@ void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
 	if(key.repeat != 0)
 		return; // ignore periodic event resends
 
+	if(handleBackRightMouseButton && key.keysym.scancode ==  SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
+	{
+		GH.events().dispatchClosePopup(GH.getCursorPosition());
+		return;
+	}
+
 	std::string keyName = getKeyNameWithModifiers(SDL_GetKeyName(key.keysym.sym), true);
 	logGlobal->trace("keyboard: key '%s' released", keyName);
 

+ 2 - 0
client/eventsSDL/InputSourceKeyboard.h

@@ -19,6 +19,8 @@ class InputSourceKeyboard
 	bool wasKeyboardAltDown;
 	bool wasKeyboardShiftDown;
 
+	bool handleBackRightMouseButton; // on some android devices right mouse button is "back"
+
 	std::string getKeyNameWithModifiers(const std::string & keyName, bool keyUp);
 public:
 	InputSourceKeyboard();

+ 32 - 3
client/lobby/CBonusSelection.cpp

@@ -484,7 +484,7 @@ void CBonusSelection::decreaseDifficulty()
 }
 
 CBonusSelection::CRegion::CRegion(CampaignScenarioID id, bool accessible, bool selectable, bool labelOnly, const CampaignRegions & campDsc)
-	: CIntObject(LCLICK | SHOW_POPUP), idOfMapAndRegion(id), accessible(accessible), selectable(selectable), labelOnly(labelOnly)
+	: CIntObject(LCLICK | SHOW_POPUP | TIME), idOfMapAndRegion(id), accessible(accessible), selectable(selectable), labelOnly(labelOnly), blinkAnim({})
 {
 	OBJECT_CONSTRUCTION;
 
@@ -509,12 +509,18 @@ CBonusSelection::CRegion::CRegion(CampaignScenarioID id, bool accessible, bool s
 	}
 }
 
-void CBonusSelection::CRegion::updateState()
+void CBonusSelection::CRegion::updateState(bool disableAll)
 {
 	if(labelOnly)
 		return;
 
-	if(!accessible)
+	if(disableAll)
+	{
+		graphicsNotSelected->disable();
+		graphicsSelected->disable();
+		graphicsStriped->disable();
+	}
+	else if(!accessible)
 	{
 		graphicsNotSelected->disable();
 		graphicsSelected->disable();
@@ -534,6 +540,29 @@ void CBonusSelection::CRegion::updateState()
 	}
 }
 
+void CBonusSelection::CRegion::tick(uint32_t msPassed)
+{
+	if(!accessible)
+	{
+		removeUsedEvents(TIME);
+		return;
+	}
+
+	blinkAnim.msPassed += msPassed;
+	if(blinkAnim.msPassed >= 150)
+	{
+		blinkAnim.state = !blinkAnim.state;
+		blinkAnim.msPassed -= 150;
+		if(blinkAnim.state)
+			blinkAnim.count++;
+		else if(blinkAnim.count >= 3)
+			removeUsedEvents(TIME);
+	}
+	updateState(blinkAnim.state);
+	setRedrawParent(true);
+	redraw();
+}
+
 void CBonusSelection::CRegion::clickReleased(const Point & cursorPosition)
 {
 	if(!labelOnly && selectable && !graphicsNotSelected->getSurface()->isTransparent(cursorPosition - pos.topLeft()))

+ 8 - 1
client/lobby/CBonusSelection.h

@@ -51,9 +51,16 @@ public:
 		bool selectable; // true if region should be selectable
 		bool labelOnly;
 		std::shared_ptr<CLabel> label;
+		struct BlinkAnim
+		{
+			uint32_t msPassed;
+			uint32_t count;
+			bool state;
+		} blinkAnim;
 	public:
 		CRegion(CampaignScenarioID id, bool accessible, bool selectable, bool labelOnly, const CampaignRegions & campDsc);
-		void updateState();
+		void updateState(bool disableAll = false);
+		void tick(uint32_t msPassed) override;
 		void clickReleased(const Point & cursorPosition) override;
 		void showPopupWindow(const Point & cursorPosition) override;
 	};

+ 8 - 1
client/lobby/CLobbyScreen.cpp

@@ -21,6 +21,7 @@
 #include "../gui/CGuiHandler.h"
 #include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
+#include "../widgets/GraphicalPrimitiveCanvas.h"
 #include "../windows/InfoWindows.h"
 #include "../render/Colors.h"
 #include "../globalLobby/GlobalLobbyClient.h"
@@ -35,7 +36,7 @@
 #include "../../lib/rmg/CMapGenOptions.h"
 #include "../CGameInfo.h"
 
-CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
+CLobbyScreen::CLobbyScreen(ESelectionScreen screenType, bool hideScreen)
 	: CSelectionBase(screenType), bonusSel(nullptr)
 {
 	OBJECT_CONSTRUCTION;
@@ -114,6 +115,12 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType)
 		if (wasInLobbyRoom)
 			CSH->getGlobalLobby().activateInterface();
 	}, EShortcut::GLOBAL_CANCEL);
+
+	if(hideScreen) // workaround to avoid confusing players by custom campaign list displaying for a few ms -> instead of this draw a black screen while "loading"
+	{
+		blackScreen = std::make_shared<GraphicalPrimitiveCanvas>(Rect(Point(0, 0), pos.dimensions()));
+		blackScreen->addBox(Point(0, 0), pos.dimensions(), Colors::BLACK);
+	}
 }
 
 CLobbyScreen::~CLobbyScreen()

+ 3 - 1
client/lobby/CLobbyScreen.h

@@ -12,13 +12,15 @@
 #include "CSelectionBase.h"
 
 class CBonusSelection;
+class GraphicalPrimitiveCanvas;
 
 class CLobbyScreen final : public CSelectionBase
 {
 public:
 	std::shared_ptr<CButton> buttonChat;
+	std::shared_ptr<GraphicalPrimitiveCanvas> blackScreen;
 
-	CLobbyScreen(ESelectionScreen type);
+	CLobbyScreen(ESelectionScreen type, bool hideScreen = false);
 	~CLobbyScreen();
 	void toggleTab(std::shared_ptr<CIntObject> tab) final;
 	void startCampaign();

+ 8 - 1
client/lobby/CSelectionBase.cpp

@@ -74,7 +74,14 @@ int ISelectionScreenInfo::getCurrentDifficulty()
 
 PlayerInfo ISelectionScreenInfo::getPlayerInfo(PlayerColor color)
 {
-	return getMapInfo()->mapHeader->players.at(color.getNum());
+	auto mapInfo = getMapInfo();
+	if (!mapInfo)
+		throw std::runtime_error("Attempt to get player info for invalid map!");
+
+	if (!mapInfo->mapHeader)
+		throw std::runtime_error("Attempt to get player info for invalid map header!");
+
+	return mapInfo->mapHeader->players.at(color.getNum());
 }
 
 CSelectionBase::CSelectionBase(ESelectionScreen type)

+ 3 - 0
client/lobby/OptionsTab.cpp

@@ -933,6 +933,9 @@ void OptionsTab::SelectedBox::showPopupWindow(const Point & cursorPosition)
 
 void OptionsTab::SelectedBox::clickReleased(const Point & cursorPosition)
 {
+	if (!SEL)
+		return;
+
 	if(SEL->screenType != ESelectionScreen::newGame)
 		return;
 	

+ 3 - 0
client/render/IImage.h

@@ -81,6 +81,8 @@ public:
 	//test transparency of specific pixel
 	virtual bool isTransparent(const Point & coords) const = 0;
 
+	virtual Rect contentRect() const = 0;
+
 	virtual Point dimensions() const = 0;
 	int width() const;
 	int height() const;
@@ -109,6 +111,7 @@ public:
 	virtual Point dimensions() const = 0;
 	virtual void exportBitmap(const boost::filesystem::path & path, SDL_Palette * palette) const = 0;
 	virtual bool isTransparent(const Point & coords) const = 0;
+	virtual Rect contentRect() const = 0;
 	virtual void draw(SDL_Surface * where, SDL_Palette * palette, const Point & dest, const Rect * src, const ColorRGBA & colorMultiplier, uint8_t alpha, EImageBlitMode mode) const = 0;
 
 	[[nodiscard]] virtual std::shared_ptr<IImage> createImageReference(EImageBlitMode mode) const = 0;

+ 5 - 0
client/renderSDL/ImageScaled.cpp

@@ -60,6 +60,11 @@ bool ImageScaled::isTransparent(const Point &coords) const
 	return source->isTransparent(coords);
 }
 
+Rect ImageScaled::contentRect() const
+{
+	return source->contentRect();
+}
+
 Point ImageScaled::dimensions() const
 {
 	return source->dimensions();

+ 1 - 0
client/renderSDL/ImageScaled.h

@@ -52,6 +52,7 @@ public:
 	void scaleTo(const Point & size) override;
 	void exportBitmap(const boost::filesystem::path & path) const override;
 	bool isTransparent(const Point & coords) const override;
+	Rect contentRect() const override;
 	Point dimensions() const override;
 	void setAlpha(uint8_t value) override;
 	void setBlitMode(EImageBlitMode mode) override;

+ 21 - 9
client/renderSDL/SDLImage.cpp

@@ -278,12 +278,6 @@ void SDLImageShared::optimizeSurface()
 		margins.x += left;
 		margins.y += top;
 	}
-
-	if(preScaleFactor > 1 && preScaleFactor != GH.screenHandler().getScalingFactor())
-	{
-		margins.x = margins.x * GH.screenHandler().getScalingFactor() / preScaleFactor;
-		margins.y = margins.y * GH.screenHandler().getScalingFactor() / preScaleFactor;
-	}
 }
 
 std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL_Palette * palette, EImageBlitMode mode) const
@@ -309,15 +303,15 @@ std::shared_ptr<const ISharedImage> SDLImageShared::scaleInteger(int factor, SDL
 			scaled = CSDL_Ext::scaleSurfaceIntegerFactor(surf, factor, EScalingAlgorithm::XBRZ_ALPHA);
 	}
 	else
-		scaled = CSDL_Ext::scaleSurface(surf, (surf->w / preScaleFactor) * factor, (surf->h / preScaleFactor) * factor);
+		scaled = CSDL_Ext::scaleSurface(surf, (int) round((float)surf->w * factor / preScaleFactor), (int) round((float)surf->h * factor / preScaleFactor));
 
 	auto ret = std::make_shared<SDLImageShared>(scaled, preScaleFactor);
 
 	ret->fullSize.x = fullSize.x * factor;
 	ret->fullSize.y = fullSize.y * factor;
 
-	ret->margins.x = margins.x * factor;
-	ret->margins.y = margins.y * factor;
+	ret->margins.x = (int) round((float)margins.x * factor / preScaleFactor);
+	ret->margins.y = (int) round((float)margins.y * factor / preScaleFactor);
 	ret->optimizeSurface();
 
 	// erase our own reference
@@ -388,6 +382,13 @@ bool SDLImageShared::isTransparent(const Point & coords) const
 		return true;
 }
 
+Rect SDLImageShared::contentRect() const
+{
+	auto tmpMargins = margins / preScaleFactor;
+	auto tmpSize = Point(surf->w, surf->h) / preScaleFactor;
+	return Rect(tmpMargins, tmpSize);
+}
+
 Point SDLImageShared::dimensions() const
 {
 	return fullSize / preScaleFactor;
@@ -403,6 +404,9 @@ std::shared_ptr<IImage> SDLImageShared::createImageReference(EImageBlitMode mode
 
 std::shared_ptr<const ISharedImage> SDLImageShared::horizontalFlip() const
 {
+	if (!surf)
+		return shared_from_this();
+
 	SDL_Surface * flipped = CSDL_Ext::horizontalFlip(surf);
 	auto ret = std::make_shared<SDLImageShared>(flipped, preScaleFactor);
 	ret->fullSize = fullSize;
@@ -415,6 +419,9 @@ std::shared_ptr<const ISharedImage> SDLImageShared::horizontalFlip() const
 
 std::shared_ptr<const ISharedImage> SDLImageShared::verticalFlip() const
 {
+	if (!surf)
+		return shared_from_this();
+
 	SDL_Surface * flipped = CSDL_Ext::verticalFlip(surf);
 	auto ret = std::make_shared<SDLImageShared>(flipped, preScaleFactor);
 	ret->fullSize = fullSize;
@@ -621,6 +628,11 @@ bool SDLImageBase::isTransparent(const Point & coords) const
 	return image->isTransparent(coords);
 }
 
+Rect SDLImageBase::contentRect() const
+{
+	return image->contentRect();
+}
+
 Point SDLImageBase::dimensions() const
 {
 	return image->dimensions();

+ 2 - 0
client/renderSDL/SDLImage.h

@@ -57,6 +57,7 @@ public:
 	void exportBitmap(const boost::filesystem::path & path, SDL_Palette * palette) const override;
 	Point dimensions() const override;
 	bool isTransparent(const Point & coords) const override;
+	Rect contentRect() const override;
 	[[nodiscard]] std::shared_ptr<IImage> createImageReference(EImageBlitMode mode) const override;
 	[[nodiscard]] std::shared_ptr<const ISharedImage> horizontalFlip() const override;
 	[[nodiscard]] std::shared_ptr<const ISharedImage> verticalFlip() const override;
@@ -78,6 +79,7 @@ public:
 	SDLImageBase(const std::shared_ptr<const ISharedImage> & image, EImageBlitMode mode);
 
 	bool isTransparent(const Point & coords) const override;
+	Rect contentRect() const override;
 	Point dimensions() const override;
 	void setAlpha(uint8_t value) override;
 	void setBlitMode(EImageBlitMode mode) override;

+ 60 - 8
client/windows/CCastleInterface.cpp

@@ -36,6 +36,7 @@
 #include "../render/IRenderHandler.h"
 #include "../render/CAnimation.h"
 #include "../render/ColorFilter.h"
+#include "../render/IFont.h"
 #include "../adventureMap/AdventureMapInterface.h"
 #include "../adventureMap/CList.h"
 #include "../adventureMap/CResDataBar.h"
@@ -173,6 +174,8 @@ void CBuildingRect::show(Canvas & to)
 {
 	uint32_t stageDelay = BUILDING_APPEAR_TIMEPOINT;
 
+	bool showTextOverlay = GH.isKeyboardAltDown();
+
 	if(stateTimeCounter < BUILDING_APPEAR_TIMEPOINT)
 	{
 		setAlpha(255 * stateTimeCounter / stageDelay);
@@ -188,7 +191,7 @@ void CBuildingRect::show(Canvas & to)
 	{
 		if(stateTimeCounter >= BUILD_ANIMATION_FINISHED_TIMEPOINT)
 		{
-			if(parent->selectedBuilding == this)
+			if(parent->selectedBuilding == this || showTextOverlay)
 				to.draw(border, pos.topLeft());
 			return;
 		}
@@ -232,9 +235,9 @@ std::string CBuildingRect::getSubtitle()//hover text for building
 	if (!getBuilding())
 		return "";
 
-	int bid = getBuilding()->bid;
+	auto bid = getBuilding()->bid;
 
-	if (bid<30)//non-dwellings - only building name
+	if (!bid.IsDwelling())//non-dwellings - only building name
 		return town->getTown()->buildings.at(getBuilding()->bid)->getNameTranslated();
 	else//dwellings - recruit %creature%
 	{
@@ -646,6 +649,54 @@ void CCastleBuildings::recreate()
 	boost::sort(children, buildSorter); //TODO: create building in blit order
 }
 
+void CCastleBuildings::drawOverlays(Canvas & to, std::vector<std::shared_ptr<CBuildingRect>> buildingRects)
+{
+	std::vector<Rect> textRects;
+	for(auto & buildingRect : buildingRects)
+	{
+		if(!buildingRect->border)
+			continue;
+
+		auto building = buildingRect->getBuilding();
+		if (!building)
+			continue;
+		auto bid = building->bid;
+
+		auto overlay = town->getTown()->buildings.at(bid)->getNameTranslated();
+		const auto & font = GH.renderHandler().loadFont(FONT_TINY);
+
+		auto backColor = Colors::GREEN; // Other
+		if(bid.IsDwelling())
+			backColor = Colors::PURPLE; // dwelling
+
+		auto contentRect = buildingRect->border->contentRect();
+		auto center = Rect(buildingRect->pos.x + contentRect.x, buildingRect->pos.y + contentRect.y, contentRect.w, contentRect.h).center();
+		Point dimensions(font->getStringWidth(overlay), font->getLineHeight());
+		Rect textRect = Rect(center - dimensions / 2, dimensions).resize(2);
+
+		while(!pos.resize(-5).isInside(Point(textRect.topLeft().x, textRect.center().y)))
+			textRect.x++;
+		while(!pos.resize(-5).isInside(Point(textRect.topRight().x, textRect.center().y)))
+			textRect.x--;
+		while(std::any_of(textRects.begin(), textRects.end(), [textRect](Rect existingTextRect) { return existingTextRect.resize(3).intersectionTest(textRect); }))
+			textRect.y++;
+		textRects.push_back(textRect);
+
+		to.drawColor(textRect, backColor);
+		to.drawBorder(textRect, Colors::BRIGHT_YELLOW);
+		to.drawText(textRect.center(), EFonts::FONT_TINY, Colors::BLACK, ETextAlignment::CENTER, overlay);
+	}
+}
+
+void CCastleBuildings::show(Canvas & to)
+{
+	CIntObject::show(to);
+
+	bool showTextOverlay = GH.isKeyboardAltDown();
+	if(showTextOverlay)
+		drawOverlays(to, buildings);
+}
+
 void CCastleBuildings::addBuilding(BuildingID building)
 {
 	//FIXME: implement faster method without complete recreation of town
@@ -1813,12 +1864,13 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
 		BuildingID buildingID;
 		if(fortSize == town->getTown()->creatures.size())
 		{
-			BuildingID dwelling = BuildingID::getDwellingFromLevel(i, 1);
+			BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(i, 0));
 
-			if(town->hasBuilt(dwelling))
-				buildingID = BuildingID(BuildingID::getDwellingFromLevel(i, 1));
-			else
-				buildingID = BuildingID(BuildingID::getDwellingFromLevel(i, 0));
+			for(; town->getBuildings().count(buildID); BuildingID::advanceDwelling(buildID))
+			{
+				if(town->hasBuilt(buildID))
+					buildingID = buildID;
+			}
 		}
 		else
 		{

+ 3 - 0
client/windows/CCastleInterface.h

@@ -159,6 +159,9 @@ class CCastleBuildings : public CIntObject
 	void openTownHall();
 
 	void recreate();
+
+	void drawOverlays(Canvas & to, std::vector<std::shared_ptr<CBuildingRect>> buildingRects);
+	void show(Canvas & to) override;
 public:
 	CBuildingRect * selectedBuilding;
 

+ 23 - 1
clientapp/EntryPoint.cpp

@@ -38,7 +38,11 @@
 #include "../lib/ExceptionsCommon.h"
 #include "../lib/filesystem/Filesystem.h"
 #include "../lib/logging/CBasicLogConfigurator.h"
+#include "../lib/modding/IdentifierStorage.h"
+#include "../lib/modding/CModHandler.h"
+#include "../lib/modding/ModDescription.h"
 #include "../lib/texts/CGeneralTextHandler.h"
+#include "../lib/texts/MetaString.h"
 #include "../lib/VCMI_Lib.h"
 #include "../lib/VCMIDirs.h"
 
@@ -71,7 +75,7 @@ static void mainLoop();
 
 static CBasicLogConfigurator *logConfig;
 
-void init()
+static void init()
 {
 	CStopWatch tmh;
 	try
@@ -92,6 +96,23 @@ void init()
 	//commandController.processCommand("convert txt", false);
 }
 
+static void checkForModLoadingFailure()
+{
+	const auto & brokenMods = VLC->identifiersHandler->getModsWithFailedRequests();
+	if (!brokenMods.empty())
+	{
+		MetaString messageText;
+		messageText.appendTextID("vcmi.client.errors.modLoadingFailure");
+
+		for (const auto & modID : brokenMods)
+		{
+			messageText.appendRawString(VLC->modh->getModInfo(modID).getName());
+			messageText.appendEOL();
+		}
+		CInfoWindow::showInfoDialog(messageText.toString(), {});
+	}
+}
+
 static void prog_version()
 {
 	printf("%s\n", GameConstants::VCMI_VERSION.c_str());
@@ -386,6 +407,7 @@ int main(int argc, char * argv[])
 
 	if(!settings["session"]["headless"].Bool())
 	{
+		checkForModLoadingFailure();
 		mainLoop();
 	}
 	else

+ 1 - 1
cmake_modules/VersionDefinition.cmake

@@ -1,6 +1,6 @@
 set(VCMI_VERSION_MAJOR 1)
 set(VCMI_VERSION_MINOR 7)
-set(VCMI_VERSION_PATCH 1)
+set(VCMI_VERSION_PATCH 0)
 add_definitions(
 	-DVCMI_VERSION_MAJOR=${VCMI_VERSION_MAJOR}
 	-DVCMI_VERSION_MINOR=${VCMI_VERSION_MINOR}

+ 6 - 1
config/schemas/settings.json

@@ -295,7 +295,8 @@
 				"controllerAxisDeadZone",
 				"controllerAxisFullZone",
 				"controllerAxisSpeed",
-				"controllerAxisScale"
+				"controllerAxisScale",
+				"handleBackRightMouseButton"
 			],
 			"properties" : {
 				"radialWheelGarrisonSwipe" : {
@@ -345,6 +346,10 @@
 				"controllerAxisScale" : {
 					"type" : "number",
 					"default" : 2
+				},
+				"handleBackRightMouseButton" : {
+					"type" : "boolean",
+					"default" : false
 				}
 			}
 		},

+ 6 - 0
debian/changelog

@@ -4,6 +4,12 @@ vcmi (1.7.0) jammy; urgency=medium
 
  -- Ivan Savenko <[email protected]>  Fri, 30 May 2025 12:00:00 +0200
 
+vcmi (1.6.2) jammy; urgency=medium
+
+  * New upstream release
+
+ -- Ivan Savenko <[email protected]>  Fri, 3 Jan 2025 12:00:00 +0200
+
 vcmi (1.6.1) jammy; urgency=medium
 
   * New upstream release

+ 1 - 0
docs/Readme.md

@@ -3,6 +3,7 @@
 [![VCMI](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg?branch=develop&event=push)](https://github.com/vcmi/vcmi/actions/workflows/github.yml?query=branch%3Adevelop+event%3Apush)
 [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.6.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.6.0)
 [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.6.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.6.1)
+[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.6.2/total)](https://github.com/vcmi/vcmi/releases/tag/1.6.2)
 [![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
 
 VCMI is an open-source recreation of Heroes of Might & Magic III engine, giving it new and extended possibilities.

+ 1 - 0
launcher/eu.vcmi.VCMI.metainfo.xml

@@ -91,6 +91,7 @@
 	<launchable type="desktop-id">vcmilauncher.desktop</launchable>
 	<releases>
 		<release version="1.7.0" date="2025-05-30" type="development"/>
+		<release version="1.6.2" date="2025-01-03" type="stable"/>
 		<release version="1.6.1" date="2024-12-27" type="stable"/>
 		<release version="1.6.0" date="2024-12-20" type="stable"/>
 		<release version="1.5.7" date="2024-08-26" type="stable"/>

+ 5 - 5
launcher/innoextract.cpp

@@ -127,17 +127,17 @@ QString Innoextract::getHashError(QString exeFile, QString binFile, QString exeF
 	exeInfoOriginal = doHash(QFile(exeFileOriginal));
 	if(!binFileOriginal.isEmpty())
 		binInfoOriginal = doHash(QFile(binFileOriginal));
-	
+
 	if(exeInfo.hash.empty() || (!binFile.isEmpty() && binInfo.hash.empty()))
 		return QString{}; // hashing not possible -> previous error is enough
 
-	QString hashOutput = tr("SHA1 hash of provided files:\nExe (%1 bytes):\n%2").arg(QString::number(exeInfo.size), QString::fromStdString(exeInfo.hash));
+	QString hashOutput = tr("SHA1 hash of provided files:\nExe (%n bytes):\n%1", "param is hash", exeInfo.size).arg(QString::fromStdString(exeInfo.hash));
 	if(!binInfo.hash.empty())
-		hashOutput += tr("\nBin (%1 bytes):\n%2").arg(QString::number(binInfo.size), QString::fromStdString(binInfo.hash));
-	
+		hashOutput += tr("\nBin (%n bytes):\n%1", "param is hash", binInfo.size).arg(QString::fromStdString(binInfo.hash));
+
 	if((!exeInfoOriginal.hash.empty() && exeInfo.hash != exeInfoOriginal.hash) || (!binInfoOriginal.hash.empty() && !binFile.isEmpty() && !binFileOriginal.isEmpty() && binInfo.hash != binInfoOriginal.hash))
 		return tr("Internal copy process failed. Enough space on device?\n\n%1").arg(hashOutput);
-	
+
 	QString foundKnown;
 	QString exeLang;
 	QString binLang;

+ 7 - 1
launcher/modManager/cmodlistview_moc.cpp

@@ -1053,7 +1053,13 @@ QStringList CModListView::getUpdateableMods()
 	for(const auto & modName : modStateModel->getAllMods())
 	{
 		auto mod = modStateModel->getMod(modName);
-		if (mod.isUpdateAvailable())
+		if (!mod.isUpdateAvailable())
+			continue;
+
+		QStringList notInstalledDependencies = getModsToInstall(mod.getID());
+		QStringList unavailableDependencies = findUnavailableMods(notInstalledDependencies);
+
+		if (unavailableDependencies.empty())
 			result.push_back(modName);
 	}
 

+ 1 - 1
launcher/modManager/modstatecontroller.cpp

@@ -245,7 +245,7 @@ bool ModStateController::doUninstallMod(QString modname)
 	QString modDir = pathToQString(*CResourceHandler::get()->getResourceName(resID));
 
 	if(!QDir(modDir).exists())
-		return addError(modname, tr("Data with this mod was not found"));
+		return addError(modname, tr("Mod data was not found"));
 
 	QDir modFullDir(modDir);
 	if(!removeModDir(modDir))

+ 14 - 0
launcher/settingsView/csettingsview_moc.cpp

@@ -124,6 +124,10 @@ void CSettingsView::loadSettings()
 		ui->comboBoxFullScreen->setCurrentIndex(2);
 	else
 		ui->comboBoxFullScreen->setCurrentIndex(settings["video"]["fullscreen"].Bool());
+#endif
+#ifndef VCMI_ANDROID
+	ui->buttonHandleBackRightMouseButton->hide();
+	ui->labelHandleBackRightMouseButton->hide();
 #endif
 	fillValidScalingRange();
 
@@ -173,6 +177,7 @@ void CSettingsView::loadSettings()
 	ui->sliderRelativeCursorSpeed->setValue(settings["general"]["relativePointerSpeedMultiplier"].Integer());
 	ui->sliderLongTouchDuration->setValue(settings["general"]["longTouchTimeMilliseconds"].Integer());
 	ui->slideToleranceDistanceMouse->setValue(settings["input"]["mouseToleranceDistance"].Integer());
+	ui->buttonHandleBackRightMouseButton->setChecked(settings["input"]["handleBackRightMouseButton"].Bool());
 	ui->sliderToleranceDistanceTouch->setValue(settings["input"]["touchToleranceDistance"].Integer());
 	ui->sliderToleranceDistanceController->setValue(settings["input"]["shortcutToleranceDistance"].Integer());
 	ui->sliderControllerSticksSensitivity->setValue(settings["input"]["controllerAxisSpeed"].Integer());
@@ -214,6 +219,8 @@ void CSettingsView::loadToggleButtonSettings()
 	setCheckbuttonState(ui->buttonRelativeCursorMode, settings["general"]["userRelativePointer"].Bool());
 	setCheckbuttonState(ui->buttonHapticFeedback, settings["general"]["hapticFeedback"].Bool());
 
+	setCheckbuttonState(ui->buttonHandleBackRightMouseButton, settings["input"]["handleBackRightMouseButton"].Bool());
+
 	std::string cursorType = settings["video"]["cursor"].String();
 	int cursorTypeIndex = vstd::find_pos(cursorTypesList, cursorType);
 	setCheckbuttonState(ui->buttonCursorType, cursorTypeIndex);
@@ -842,3 +849,10 @@ void CSettingsView::on_buttonScalingAuto_toggled(bool checked)
 	node->Integer() = checked ? 0 : 100;
 }
 
+void CSettingsView::on_buttonHandleBackRightMouseButton_toggled(bool checked)
+{
+	Settings node = settings.write["input"]["handleBackRightMouseButton"];
+	node->Bool() = checked;
+	updateCheckbuttonText(ui->buttonHandleBackRightMouseButton);
+}
+

+ 2 - 0
launcher/settingsView/csettingsview_moc.h

@@ -101,6 +101,8 @@ private slots:
 
 	void on_buttonScalingAuto_toggled(bool checked);
 
+	void on_buttonHandleBackRightMouseButton_toggled(bool checked);
+
 private:
 	Ui::CSettingsView * ui;
 

+ 76 - 53
launcher/settingsView/csettingsview_moc.ui

@@ -69,7 +69,7 @@
          </property>
         </widget>
        </item>
-       <item row="60" column="0">
+       <item row="61" column="0">
         <widget class="QLabel" name="labelModsValidation">
          <property name="text">
           <string>Mods Validation</string>
@@ -105,7 +105,7 @@
          </item>
         </widget>
        </item>
-       <item row="43" column="1" colspan="5">
+       <item row="44" column="1" colspan="5">
         <widget class="QSlider" name="sliderControllerSticksSensitivity">
          <property name="minimum">
           <number>500</number>
@@ -133,7 +133,7 @@
          </property>
         </widget>
        </item>
-       <item row="35" column="1" colspan="5">
+       <item row="36" column="1" colspan="5">
         <widget class="QPushButton" name="pushButtonResetTutorialTouchscreen">
          <property name="text">
           <string>Reset</string>
@@ -147,7 +147,7 @@
          </property>
         </widget>
        </item>
-       <item row="39" column="1" colspan="5">
+       <item row="40" column="1" colspan="5">
         <widget class="QSlider" name="sliderLongTouchDuration">
          <property name="minimum">
           <number>500</number>
@@ -172,7 +172,7 @@
          </property>
         </widget>
        </item>
-       <item row="54" column="1">
+       <item row="55" column="1">
         <widget class="QToolButton" name="buttonAutoCheck">
          <property name="enabled">
           <bool>true</bool>
@@ -239,7 +239,7 @@
          </property>
         </widget>
        </item>
-       <item row="55" column="1">
+       <item row="56" column="1">
         <widget class="QToolButton" name="buttonRepositoryDefault">
          <property name="enabled">
           <bool>true</bool>
@@ -268,14 +268,14 @@
          </property>
         </widget>
        </item>
-       <item row="38" column="0">
+       <item row="39" column="0">
         <widget class="QLabel" name="labelHapticFeedback">
          <property name="text">
           <string>Haptic Feedback</string>
          </property>
         </widget>
        </item>
-       <item row="41" column="0">
+       <item row="42" column="0">
         <widget class="QLabel" name="labelToleranceDistanceTouch">
          <property name="text">
           <string>Touch Tap Tolerance</string>
@@ -288,7 +288,7 @@
        <item row="1" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxLanguage"/>
        </item>
-       <item row="58" column="1" colspan="5">
+       <item row="59" column="1" colspan="5">
         <widget class="QSpinBox" name="spinBoxNetworkPortLobby">
          <property name="minimum">
           <number>1024</number>
@@ -301,7 +301,7 @@
          </property>
         </widget>
        </item>
-       <item row="60" column="5">
+       <item row="61" column="5">
         <widget class="QToolButton" name="buttonValidationFull">
          <property name="enabled">
           <bool>true</bool>
@@ -326,7 +326,7 @@
          </attribute>
         </widget>
        </item>
-       <item row="42" column="0">
+       <item row="43" column="0">
         <widget class="QLabel" name="labelInputMouse_3">
          <property name="font">
           <font>
@@ -379,7 +379,7 @@
          </property>
         </widget>
        </item>
-       <item row="47" column="1" colspan="5">
+       <item row="48" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxEnemyPlayerAI">
          <property name="currentText">
           <string notr="true">VCAI</string>
@@ -396,7 +396,7 @@
          </item>
         </widget>
        </item>
-       <item row="55" column="2" colspan="4">
+       <item row="56" column="2" colspan="4">
         <widget class="QLineEdit" name="lineEditRepositoryDefault">
          <property name="text">
           <string notr="true"/>
@@ -406,7 +406,7 @@
          </property>
         </widget>
        </item>
-       <item row="48" column="1" colspan="5">
+       <item row="49" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxAlliedPlayerAI">
          <property name="currentText">
           <string notr="true">VCAI</string>
@@ -430,7 +430,7 @@
          </property>
         </widget>
        </item>
-       <item row="46" column="0">
+       <item row="47" column="0">
         <widget class="QLabel" name="labelArtificialIntelligence">
          <property name="font">
           <font>
@@ -445,7 +445,7 @@
          </property>
         </widget>
        </item>
-       <item row="55" column="0">
+       <item row="56" column="0">
         <widget class="QLabel" name="labelRepositoryDefault">
          <property name="text">
           <string>Default repository</string>
@@ -458,7 +458,7 @@
        <item row="14" column="4" colspan="2">
         <widget class="QSpinBox" name="spinBoxInterfaceScaling">
          <property name="suffix">
-          <string>%</string>
+          <string notr="true">%</string>
          </property>
          <property name="minimum">
           <number>50</number>
@@ -471,7 +471,7 @@
          </property>
         </widget>
        </item>
-       <item row="37" column="0">
+       <item row="38" column="0">
         <widget class="QLabel" name="labelRelativeCursorSpeed">
          <property name="text">
           <string>Relative Pointer Speed</string>
@@ -485,7 +485,7 @@
          </property>
         </widget>
        </item>
-       <item row="53" column="1" colspan="5">
+       <item row="54" column="1" colspan="5">
         <widget class="QToolButton" name="buttonIgnoreSslErrors">
          <property name="enabled">
           <bool>true</bool>
@@ -565,7 +565,7 @@
          </property>
         </widget>
        </item>
-       <item row="56" column="1">
+       <item row="57" column="1">
         <widget class="QToolButton" name="buttonRepositoryExtra">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -584,21 +584,21 @@
          </property>
         </widget>
        </item>
-       <item row="54" column="2" colspan="4">
+       <item row="55" column="2" colspan="4">
         <widget class="QPushButton" name="refreshRepositoriesButton">
          <property name="text">
           <string>Refresh now</string>
          </property>
         </widget>
        </item>
-       <item row="48" column="0">
+       <item row="49" column="0">
         <widget class="QLabel" name="labelAlliedPlayerAI">
          <property name="text">
           <string>Adventure Map Allies</string>
          </property>
         </widget>
        </item>
-       <item row="49" column="0">
+       <item row="50" column="0">
         <widget class="QLabel" name="labelNeutralAI">
          <property name="text">
           <string>Neutral AI in battles</string>
@@ -636,7 +636,7 @@
          </property>
         </widget>
        </item>
-       <item row="57" column="1" colspan="5">
+       <item row="58" column="1" colspan="5">
         <widget class="QLineEdit" name="lineEditGameLobbyHost">
          <property name="text">
           <string notr="true"/>
@@ -650,7 +650,7 @@
          </property>
         </widget>
        </item>
-       <item row="36" column="0">
+       <item row="37" column="0">
         <widget class="QLabel" name="labelRelativeCursorMode">
          <property name="text">
           <string>Use Relative Pointer Mode</string>
@@ -660,14 +660,14 @@
        <item row="7" column="1" colspan="5">
         <widget class="QSpinBox" name="spinBoxAutoSaveLimit"/>
        </item>
-       <item row="50" column="0">
+       <item row="51" column="0">
         <widget class="QLabel" name="labelFriendlyAI">
          <property name="text">
           <string>Autocombat AI in battles</string>
          </property>
         </widget>
        </item>
-       <item row="60" column="1" colspan="2">
+       <item row="61" column="1" colspan="2">
         <widget class="QToolButton" name="buttonValidationOff">
          <property name="enabled">
           <bool>true</bool>
@@ -714,7 +714,7 @@
          </property>
         </widget>
        </item>
-       <item row="38" column="1" colspan="5">
+       <item row="39" column="1" colspan="5">
         <widget class="QToolButton" name="buttonHapticFeedback">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -745,7 +745,7 @@
          </property>
         </widget>
        </item>
-       <item row="56" column="0">
+       <item row="57" column="0">
         <widget class="QLabel" name="labelRepositoryExtra">
          <property name="text">
           <string>Additional repository</string>
@@ -768,7 +768,7 @@
          </property>
         </widget>
        </item>
-       <item row="47" column="0">
+       <item row="48" column="0">
         <widget class="QLabel" name="labelEnemyPlayerAI">
          <property name="text">
           <string>Adventure Map Enemies</string>
@@ -796,7 +796,7 @@
          </property>
         </widget>
        </item>
-       <item row="34" column="0">
+       <item row="35" column="0">
         <widget class="QLabel" name="labelInputMouse_2">
          <property name="font">
           <font>
@@ -830,7 +830,7 @@
        <item row="23" column="1">
         <widget class="QLabel" name="labelScalingCursorValue"/>
        </item>
-       <item row="36" column="1" colspan="5">
+       <item row="37" column="1" colspan="5">
         <widget class="QToolButton" name="buttonRelativeCursorMode">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -853,28 +853,28 @@
          </property>
         </widget>
        </item>
-       <item row="57" column="0">
+       <item row="58" column="0">
         <widget class="QLabel" name="labelGameLobbyHost">
          <property name="text">
           <string>Online Lobby address</string>
          </property>
         </widget>
        </item>
-       <item row="58" column="0">
+       <item row="59" column="0">
         <widget class="QLabel" name="labelNetworkPortLobby">
          <property name="text">
           <string>Online Lobby port</string>
          </property>
         </widget>
        </item>
-       <item row="45" column="0">
+       <item row="46" column="0">
         <widget class="QLabel" name="labelToleranceDistanceController">
          <property name="text">
           <string>Controller Click Tolerance</string>
          </property>
         </widget>
        </item>
-       <item row="49" column="1" colspan="5">
+       <item row="50" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxNeutralAI">
          <property name="currentText">
           <string notr="true">BattleAI</string>
@@ -910,7 +910,7 @@
          </item>
         </widget>
        </item>
-       <item row="53" column="0">
+       <item row="54" column="0">
         <widget class="QLabel" name="labelIgnoreSslErrors">
          <property name="text">
           <string>Ignore SSL errors</string>
@@ -920,14 +920,14 @@
        <item row="20" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxDisplayIndex"/>
        </item>
-       <item row="35" column="0">
+       <item row="36" column="0">
         <widget class="QLabel" name="labelResetTutorialTouchscreen">
          <property name="text">
           <string>Show Tutorial again</string>
          </property>
         </widget>
        </item>
-       <item row="44" column="0">
+       <item row="45" column="0">
         <widget class="QLabel" name="labelControllerSticksAcceleration">
          <property name="text">
           <string>Sticks Acceleration</string>
@@ -949,7 +949,7 @@
          </property>
         </widget>
        </item>
-       <item row="51" column="1" colspan="5">
+       <item row="52" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxEnemyAI">
          <property name="editable">
           <bool>false</bool>
@@ -990,7 +990,30 @@
          </property>
         </widget>
        </item>
-       <item row="51" column="0">
+       <item row="34" column="0">
+        <widget class="QLabel" name="labelHandleBackRightMouseButton">
+         <property name="text">
+          <string>Handle back as right mouse button</string>
+         </property>
+        </widget>
+       </item>
+       <item row="34" column="1" colspan="5">
+        <widget class="QToolButton" name="buttonHandleBackRightMouseButton">
+         <property name="sizePolicy">
+          <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text">
+          <string/>
+         </property>
+         <property name="checkable">
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="52" column="0">
         <widget class="QLabel" name="labelEnemyAI">
          <property name="text">
           <string>Enemy AI in battles</string>
@@ -1004,7 +1027,7 @@
          </property>
         </widget>
        </item>
-       <item row="41" column="1" colspan="5">
+       <item row="42" column="1" colspan="5">
         <widget class="QSlider" name="sliderToleranceDistanceTouch">
          <property name="minimum">
           <number>0</number>
@@ -1046,7 +1069,7 @@
          </property>
         </widget>
        </item>
-       <item row="50" column="1" colspan="5">
+       <item row="51" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxFriendlyAI">
          <property name="editable">
           <bool>false</bool>
@@ -1066,7 +1089,7 @@
          </item>
         </widget>
        </item>
-       <item row="56" column="2" colspan="4">
+       <item row="57" column="2" colspan="4">
         <widget class="QLineEdit" name="lineEditRepositoryExtra">
          <property name="text">
           <string notr="true"/>
@@ -1118,7 +1141,7 @@
          </attribute>
         </widget>
        </item>
-       <item row="52" column="0">
+       <item row="53" column="0">
         <widget class="QLabel" name="labelNetwork">
          <property name="font">
           <font>
@@ -1133,7 +1156,7 @@
          </property>
         </widget>
        </item>
-       <item row="59" column="0">
+       <item row="60" column="0">
         <widget class="QLabel" name="labelMiscellaneous">
          <property name="font">
           <font>
@@ -1148,7 +1171,7 @@
          </property>
         </widget>
        </item>
-       <item row="44" column="1" colspan="5">
+       <item row="45" column="1" colspan="5">
         <widget class="QSlider" name="sliderControllerSticksAcceleration">
          <property name="minimum">
           <number>100</number>
@@ -1220,21 +1243,21 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
          </property>
         </widget>
        </item>
-       <item row="39" column="0">
+       <item row="40" column="0">
         <widget class="QLabel" name="labelLongTouchDuration">
          <property name="text">
           <string>Long Touch Duration</string>
          </property>
         </widget>
        </item>
-       <item row="54" column="0">
+       <item row="55" column="0">
         <widget class="QLabel" name="labelAutoCheck">
          <property name="text">
           <string>Check on startup</string>
          </property>
         </widget>
        </item>
-       <item row="45" column="1" colspan="5">
+       <item row="46" column="1" colspan="5">
         <widget class="QSlider" name="sliderToleranceDistanceController">
          <property name="minimum">
           <number>0</number>
@@ -1278,7 +1301,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
          </property>
         </widget>
        </item>
-       <item row="37" column="1" colspan="5">
+       <item row="38" column="1" colspan="5">
         <widget class="QSlider" name="sliderRelativeCursorSpeed">
          <property name="minimum">
           <number>100</number>
@@ -1393,7 +1416,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
          </property>
         </widget>
        </item>
-       <item row="43" column="0">
+       <item row="44" column="0">
         <widget class="QLabel" name="labelControllerSticksSensitivity">
          <property name="text">
           <string>Sticks Sensitivity</string>
@@ -1424,7 +1447,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
        <item row="12" column="1" colspan="5">
         <widget class="QComboBox" name="comboBoxResolution"/>
        </item>
-       <item row="60" column="3" colspan="2">
+       <item row="61" column="3" colspan="2">
         <widget class="QToolButton" name="buttonValidationBasic">
          <property name="enabled">
           <bool>true</bool>

+ 55 - 49
launcher/translation/chinese.ts

@@ -387,7 +387,7 @@ Install successfully downloaded?</source>
         <translation>人工智能</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>界面缩放</translation>
     </message>
@@ -397,7 +397,7 @@ Install successfully downloaded?</source>
         <translation>战场中立生物AI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>战场敌方玩家AI</translation>
     </message>
@@ -427,7 +427,7 @@ Install successfully downloaded?</source>
         <translation>自动战斗AI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>摇杆灵敏度</translation>
     </message>
@@ -449,7 +449,7 @@ Install successfully downloaded?</source>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>自动</translation>
     </message>
@@ -494,22 +494,27 @@ Install successfully downloaded?</source>
         <translation>在线大厅地址</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>指针缩放</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>可缩放字体</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>杂项</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -526,22 +531,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
 独占全屏模式 - 游戏将覆盖整个屏幕,并使用选定的分辨率。</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>字体缩放(测试中)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>原始字体</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>图像放大过滤器</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>基本</translation>
     </message>
@@ -581,7 +586,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>重置</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>网络</translation>
     </message>
@@ -596,7 +601,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>相对指针速度</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>音乐音量</translation>
     </message>
@@ -611,15 +616,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>输入 - 鼠标</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>长按触屏间隔</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -641,22 +641,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>音效音量</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>窗口化</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>无边框全屏</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>独占全屏</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>自动保存限制 (0 = 不限制)</translation>
     </message>
@@ -666,7 +666,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>帧率限制</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>自动保存文件名前缀</translation>
     </message>
@@ -681,7 +681,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>摇杆加速度</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>空 = 地图名称前缀</translation>
     </message>
@@ -717,7 +717,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>英雄无敌3翻译</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>启动时检查更新</translation>
     </message>
@@ -737,7 +737,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>VCMI语言</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>分辨率</translation>
     </message>
@@ -772,27 +772,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>显示开场动画</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>激活</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>禁用</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>启用</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>未安装</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>安装</translation>
     </message>
@@ -1163,23 +1163,29 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI编译时没有启用innoextract支持,启用了才可以从exe文件中提取数据!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>提供文件的SHA1哈希值:
-Exe(%1字节):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>提供文件的SHA1哈希值:
+Exe(%n字节):
+%1</numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1字节):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n字节):
+%1</numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1358,12 +1364,12 @@ Bin (%1字节):
         <translation type="unfinished">启动可执行文件时出错</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>替换配置文件?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>您想要替换%1吗?</translation>
     </message>
@@ -1451,8 +1457,8 @@ Bin (%1字节):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>此模组的数据未找到</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 60 - 50
launcher/translation/czech.ts

@@ -383,7 +383,7 @@ Nainstalovat úspěšně stažené?</translation>
         <translation>Umělá inteligence</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Škálování rozhraní</translation>
     </message>
@@ -393,7 +393,7 @@ Nainstalovat úspěšně stažené?</translation>
         <translation>Neutrální AI v bitvách</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Nepřátelská AI v bitvách</translation>
     </message>
@@ -418,7 +418,7 @@ Nainstalovat úspěšně stažené?</translation>
         <translation>AI automatického boje v bitvách</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Citlivost páček</translation>
     </message>
@@ -440,7 +440,7 @@ Nainstalovat úspěšně stažené?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automaticky</translation>
     </message>
@@ -485,22 +485,27 @@ Nainstalovat úspěšně stažené?</translation>
         <translation>Adresa online lobby</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Škálování kurzoru</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Škálovatelné</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Ostatní</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -517,22 +522,22 @@ Celá obrazovka bez okrajů - hra poběží v okně na celou obrazovku, přizpů
 Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané rozlišení.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Škálování písma (experimentální)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Původní</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Filtr škálování</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Základní</translation>
     </message>
@@ -572,7 +577,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Restart</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Síť</translation>
     </message>
@@ -587,7 +592,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Relativní rychlost myši</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Hlasitost hudby</translation>
     </message>
@@ -602,15 +607,10 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Vstup - Myš</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Doba dlouhého podržení</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -632,22 +632,22 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Hlasitost zvuků</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>V okně</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Celá obrazovka bez okrajů</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Exkluzivní celá obrazovka</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Limit aut. uložení (0=vypnuto)</translation>
     </message>
@@ -662,7 +662,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Omezení snímků za sekundu</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Předpona aut. uložení</translation>
     </message>
@@ -677,7 +677,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Zrychlení páček</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>prázná = předpona - název mapy</translation>
     </message>
@@ -712,7 +712,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Překlad Heroes III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Zkontrolovat při zapnutí</translation>
     </message>
@@ -732,7 +732,7 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Jazyk VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Rozlišení</translation>
     </message>
@@ -767,27 +767,27 @@ Režim celé obrazovky - hra pokryje celou vaši obrazovku a použije vybrané r
         <translation>Zobrazit intro</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Aktivní</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Zakázáno</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Povolit</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Nenainstalováno</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Instalovat</translation>
     </message>
@@ -1156,23 +1156,33 @@ Důvod chyby: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI bylo zkompilováno bez podpory innoextract, která je potřebná pro extrahování EXE souborů!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>Kontrolní součet SHA1 zadaných souborů:
-Exe (%1 bajtů):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>Kontrolní součet SHA1 zadaných souborů:
+Exe (%n bajtů):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1 bajtů):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n bajtů):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1348,15 +1358,15 @@ Bin (%1 bajtů):
     <message>
         <location filename="../mainwindow_moc.cpp" line="46"/>
         <source>Error starting executable</source>
-        <translation type="unfinished">Chyba při spouštění souboru</translation>
+        <translation>Chyba při spouštění souboru</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Chcete nahradit konfigurační soubor?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Chcete nahradit %1?</translation>
     </message>
@@ -1444,8 +1454,8 @@ Bin (%1 bajtů):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Data s touto modifikací nebyla nalezena</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 52 - 44
launcher/translation/english.ts

@@ -376,7 +376,7 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation type="unfinished"></translation>
     </message>
@@ -386,7 +386,7 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation type="unfinished"></translation>
     </message>
@@ -411,7 +411,7 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation type="unfinished"></translation>
     </message>
@@ -433,7 +433,7 @@ Install successfully downloaded?</source>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -478,22 +478,27 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -504,22 +509,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -559,7 +564,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation type="unfinished"></translation>
     </message>
@@ -574,7 +579,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation type="unfinished"></translation>
     </message>
@@ -589,15 +594,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -619,22 +619,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation type="unfinished"></translation>
     </message>
@@ -649,7 +649,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation type="unfinished"></translation>
     </message>
@@ -664,7 +664,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation type="unfinished"></translation>
     </message>
@@ -699,7 +699,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation type="unfinished"></translation>
     </message>
@@ -719,7 +719,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation type="unfinished"></translation>
     </message>
@@ -754,27 +754,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1133,19 +1133,27 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1314,12 +1322,12 @@ Bin (%1 bytes):
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1407,7 +1415,7 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
+        <source>Mod data was not found</source>
         <translation type="unfinished"></translation>
     </message>
     <message>

+ 53 - 45
launcher/translation/french.ts

@@ -389,7 +389,7 @@ Installer les téchargements réussis?</translation>
         <translation>Activé</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>IA ennemie dans les batailles</translation>
     </message>
@@ -414,7 +414,7 @@ Installer les téchargements réussis?</translation>
         <translation>IA de combat automatique dans les batailles</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Sensibilité au batons</translation>
     </message>
@@ -436,7 +436,7 @@ Installer les téchargements réussis?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automatique</translation>
     </message>
@@ -481,22 +481,27 @@ Installer les téchargements réussis?</translation>
         <translation>Adresse de la salle d&apos;attente en ligne</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -507,22 +512,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Filtre d&apos;Agrandissement</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -547,7 +552,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Entrée - Écran tactile</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Réseau</translation>
     </message>
@@ -577,7 +582,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Vitesse de Pointeur Relatif</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Volume de la Musique</translation>
     </message>
@@ -592,15 +597,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Entrée - Sourie</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Durée de Touche Prolongée</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -622,17 +622,17 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Volume du Son</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Fenêtré</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Fenêtré sans bord</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Plein écran exclusif</translation>
     </message>
@@ -647,7 +647,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>IA neutre dans les batailles</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Limite de sauvegarde auto (0 = désactivé)</translation>
     </message>
@@ -657,17 +657,17 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ennemis de la carte d&quot;aventure</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Préfix de sauvegarde auto.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>vide = prefix du nom de carte</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Mise à l&quot;échelle de l&quot;interface</translation>
     </message>
@@ -697,7 +697,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Dépôt supplémentaire</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Vérifier au démarrage</translation>
     </message>
@@ -732,7 +732,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Langue de VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Résolution</translation>
     </message>
@@ -762,27 +762,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Montrer l&apos;intro</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Actif</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Désactivé</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Activé</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Pas Installé</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Installer</translation>
     </message>
@@ -1142,19 +1142,27 @@ Raison de l&apos;erreur&#xa0;: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1323,12 +1331,12 @@ Bin (%1 bytes):
         <translation type="unfinished">Erreur lors du démarrage de l&apos;exécutable</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation type="unfinished">Remplacer le fichier de configuration ?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation type="unfinished">Voulez vous remplacer %1 ?</translation>
     </message>
@@ -1416,8 +1424,8 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation type="unfinished">Les données de ce mod n&apos;ont pas étés trouvées</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 57 - 49
launcher/translation/german.ts

@@ -383,7 +383,7 @@ Installation erfolgreich heruntergeladen?</translation>
         <translation>Künstliche Intelligenz</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Skalierung der Benutzeroberfläche</translation>
     </message>
@@ -393,7 +393,7 @@ Installation erfolgreich heruntergeladen?</translation>
         <translation>Neutrale KI in Kämpfen</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Gegnerische KI in Kämpfen</translation>
     </message>
@@ -423,7 +423,7 @@ Installation erfolgreich heruntergeladen?</translation>
         <translation>Autokampf-KI in Kämpfen</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Sticks Empfindlichkeit</translation>
     </message>
@@ -445,7 +445,7 @@ Installation erfolgreich heruntergeladen?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automatisch</translation>
     </message>
@@ -490,22 +490,27 @@ Installation erfolgreich heruntergeladen?</translation>
         <translation>Adresse der Online-Lobby</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Cursor-Skalierung</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Skalierbar</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Sonstiges</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -522,22 +527,22 @@ Randloser Fenstermodus - das Spiel läuft in einem Vollbildfenster, das der Aufl
 Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwendet die gewählte Auflösung.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Schriftskalierung (experimentell)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Original</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Hochskalierungsfilter</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Grundlegend</translation>
     </message>
@@ -577,7 +582,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Zurücksetzen</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Netzwerk</translation>
     </message>
@@ -592,7 +597,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Relative Zeigergeschwindigkeit</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Musik Lautstärke</translation>
     </message>
@@ -607,15 +612,10 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Eingabe - Maus</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Dauer der Berührung für &quot;lange Berührung&quot;</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -637,22 +637,22 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Sound-Lautstärke</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Fenstermodus</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Randloser Vollbildmodus</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Exklusiver Vollbildmodus</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Limit für Autospeicherung (0 = aus)</translation>
     </message>
@@ -662,7 +662,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Limit der Bildrate</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Präfix für Autospeicherung</translation>
     </message>
@@ -677,7 +677,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Sticks Beschleunigung</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>leer = Kartenname als Präfix</translation>
     </message>
@@ -712,7 +712,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Heroes III Übersetzung</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Beim Start prüfen</translation>
     </message>
@@ -732,7 +732,7 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>VCMI-Sprache</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Auflösung</translation>
     </message>
@@ -767,27 +767,27 @@ Exklusiver Vollbildmodus - das Spiel nimmt den gesamten Bildschirm ein und verwe
         <translation>Intro anzeigen</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Aktiv</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Deaktiviert</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Aktivieren</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Nicht installiert</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Installieren</translation>
     </message>
@@ -1157,23 +1157,31 @@ Fehlerursache: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI wurde ohne innoextract-Unterstützung kompiliert, die zum Extrahieren von exe-Dateien benötigt wird!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>SHA1-Hash der bereitgestellten Dateien:
-Exe (%1 Bytes):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>SHA1-Hash der bereitgestellten Dateien:
+Exe (%n Bytes):
+%1</numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1 Bytes):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n Bytes):
+%1</numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1352,12 +1360,12 @@ Bin (%1 Bytes):
         <translation type="unfinished">Fehler beim Starten der ausführbaren Datei</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Konfigurationsdatei ersetzen?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Soll %1 ersetzt werden?</translation>
     </message>
@@ -1445,8 +1453,8 @@ Bin (%1 Bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Daten mit dieser Mod wurden nicht gefunden</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 59 - 49
launcher/translation/polish.ts

@@ -383,7 +383,7 @@ Zainstalować pomyślnie pobrane?</translation>
         <translation>Sztuczna Inteligencja</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Skala interfejsu</translation>
     </message>
@@ -393,7 +393,7 @@ Zainstalować pomyślnie pobrane?</translation>
         <translation>AI bitewne jednostek neutralnych</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>AI bitewne wrogów</translation>
     </message>
@@ -423,7 +423,7 @@ Zainstalować pomyślnie pobrane?</translation>
         <translation>AI szybkiej walki</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Czułość gałek</translation>
     </message>
@@ -445,7 +445,7 @@ Zainstalować pomyślnie pobrane?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automatyczny</translation>
     </message>
@@ -490,22 +490,27 @@ Zainstalować pomyślnie pobrane?</translation>
         <translation>Adres lobby online</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Skalowanie kursora</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Skalowalne</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Różne</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -522,22 +527,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         Tryb pełnoekranowy - gra zajmie cały ekran i będzie korzystać z wybranej rozdzielczości.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Skalowanie czcionki (wersja testowa)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Oryginalne</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Filtr wyostrzający</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Podstawowy</translation>
     </message>
@@ -577,7 +582,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Zresetuj</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Sieć</translation>
     </message>
@@ -592,7 +597,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Prędkość kursora w trybie relatywnym</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Głośność muzyki</translation>
     </message>
@@ -607,15 +612,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Sterowanie - Mysz</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Czas do długiego dotyku</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -637,22 +637,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Głośność dźwięku</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Okno</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Pełny ekran (tryb okna)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Pełny ekran klasyczny</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Limit autozapisów (0 = brak)</translation>
     </message>
@@ -662,7 +662,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Limit FPS</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Przedrostek autozapisu</translation>
     </message>
@@ -677,7 +677,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Przyspieszenie gałek</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>puste = przedrostek z nazwy mapy</translation>
     </message>
@@ -712,7 +712,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Tłumaczenie Heroes III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Sprawdzaj przy uruchomieniu</translation>
     </message>
@@ -732,7 +732,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Język VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Rozdzielczość</translation>
     </message>
@@ -767,27 +767,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Pokaż intro</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Aktywny</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Wyłączone</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Włącz</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Nie zainstalowano</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Zainstaluj</translation>
     </message>
@@ -1158,23 +1158,33 @@ powód błędu: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI zostało skompilowane bez wsparcia innoextract, który jest niezbędny do rozpakowania plików exe</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>SHA1 suma kontrolna dostarczonych plików:
-Exe (%1 bajtów):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>SHA1 suma kontrolna dostarczonych plików:
+Exe (%n bajtów):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1 bajtów):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n bajtów):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1353,12 +1363,12 @@ Bin (%1 bajtów):
         <translation type="unfinished">Błąd podczas uruchamiania pliku wykonywalnego</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Zastąpić plik konfiguracji?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Czy chcesz zastąpić %1?</translation>
     </message>
@@ -1446,8 +1456,8 @@ Bin (%1 bajtów):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Dane z tym modem nie zostały znalezione</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 57 - 49
launcher/translation/portuguese.ts

@@ -383,7 +383,7 @@ O download da instalação foi bem-sucedido?</translation>
         <translation>Inteligência artificial</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Escala da interface</translation>
     </message>
@@ -393,7 +393,7 @@ O download da instalação foi bem-sucedido?</translation>
         <translation>IA neutra nas batalhas</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>IA inimiga em batalhas</translation>
     </message>
@@ -418,7 +418,7 @@ O download da instalação foi bem-sucedido?</translation>
         <translation>IA de combate automático nas batalhas</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Sensibilidade dos analógicos</translation>
     </message>
@@ -440,7 +440,7 @@ O download da instalação foi bem-sucedido?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automático</translation>
     </message>
@@ -485,22 +485,27 @@ O download da instalação foi bem-sucedido?</translation>
         <translation>Endereço da sala de espera on-line</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Escala do cursor</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Escalável</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Diversos</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -517,22 +522,22 @@ Modo de janela sem bordas - o jogo será executado em uma janela de tela cheia,
 Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolução selecionada.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Escala da fonte (experimental)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Original</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Filtro de aumento de escala</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Básico</translation>
     </message>
@@ -572,7 +577,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Redefinir</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Rede</translation>
     </message>
@@ -587,7 +592,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Velocidade do ponteiro relativo</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Volume da música</translation>
     </message>
@@ -602,15 +607,10 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Entrada - mouse</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Duração do toque longo</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -632,22 +632,22 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Volume do som</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Janela</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Tela cheia sem bordas</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Tela cheia exclusiva</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Limite de salvamento automático (0 = sem limite)</translation>
     </message>
@@ -662,7 +662,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Limite de taxa de quadros</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Prefixo do salvamento automático</translation>
     </message>
@@ -677,7 +677,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Aceleração dos analógicos</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>vazio = prefixo do mapa</translation>
     </message>
@@ -712,7 +712,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Tradução do Heroes III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Verificar na inicialização</translation>
     </message>
@@ -732,7 +732,7 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Idioma do VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Resolução</translation>
     </message>
@@ -767,27 +767,27 @@ Modo de tela cheia exclusivo - o jogo cobrirá toda a sua tela e usará a resolu
         <translation>Mostrar introdução</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Ativo</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Desativado</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Ativar</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Não instalado</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Instalar</translation>
     </message>
@@ -1157,23 +1157,31 @@ Motivo do erro: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>O VCMI foi compilado sem suporte ao innoextract, que é necessário para extrair arquivos EXE!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>Hash SHA1 dos arquivos fornecidos:
-Exe (%1 bytes):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>Hash SHA1 dos arquivos fornecidos:
+Exe (%n bytes):
+%1</numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1 bytes):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n bytes):
+%1</numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1352,12 +1360,12 @@ Bin (%1 bytes):
         <translation type="unfinished">Erro ao iniciar o executável</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Substituir arquivo de configuração?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Você deseja substituir %1?</translation>
     </message>
@@ -1445,8 +1453,8 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Não foram encontrados dados com este mod</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 59 - 49
launcher/translation/russian.ts

@@ -372,7 +372,7 @@ Install successfully downloaded?</source>
 <context>
     <name>CSettingsView</name>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Масштабирование интерфейса</translation>
     </message>
@@ -393,7 +393,7 @@ Install successfully downloaded?</source>
         <translation>Нейтральный ИИ в битвах</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Вражеский ИИ в битвах</translation>
     </message>
@@ -403,7 +403,7 @@ Install successfully downloaded?</source>
         <translation>Дополнительный репозиторий</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Проверять при запуске</translation>
     </message>
@@ -453,7 +453,7 @@ Install successfully downloaded?</source>
         <translation>ИИ автобоя в битвах</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Чувствительность стиков</translation>
     </message>
@@ -475,7 +475,7 @@ Install successfully downloaded?</source>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Автоматически</translation>
     </message>
@@ -520,22 +520,27 @@ Install successfully downloaded?</source>
         <translation>Адрес онлайн-лобби</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Масштабирование курсора</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Масштабируемый</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Разное</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -552,22 +557,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
 Эксклюзивный полноэкранный режим - игра займет весь экран и будет использовать выбранное разрешение.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Масштабирование шрифтов (экспериментально)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Оригинал</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Фильтр увеличения</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Базовый</translation>
     </message>
@@ -597,7 +602,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ввод - сенсорный экран</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Сеть</translation>
     </message>
@@ -627,7 +632,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Скорость относительного указателя</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Громкость музыки</translation>
     </message>
@@ -642,15 +647,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ввод - мышь</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Длительность долгого нажатия</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -672,17 +672,17 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Громкость звука</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Оконный</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Полноэкранный без рамок</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Эксклюзивный полноэкранный</translation>
     </message>
@@ -692,7 +692,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Зарезервированная область экрана</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Лимит автосохранений (0 = выкл)</translation>
     </message>
@@ -702,7 +702,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ограничение кадров</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Префикс автосохранений</translation>
     </message>
@@ -717,7 +717,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ускорение стиков</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>пусто = префикс имени карты</translation>
     </message>
@@ -737,7 +737,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Перевод Героев III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Разрешение экрана</translation>
     </message>
@@ -767,27 +767,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Вступление</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Активен</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Отключен</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Включить</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Не установлен</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Установить</translation>
     </message>
@@ -1157,23 +1157,33 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI была скомпилирована без поддержки innoextract, необходимой для распаковки exe-файлов!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>SHA1 хэш предоставленных файлов:
-Exe (%1 байт):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>SHA1 хэш предоставленных файлов:
+Exe (%n байт):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation>
-Bin (%1 байт):
-%2</translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform>
+Bin (%n байт):
+%1</numerusform>
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1352,12 +1362,12 @@ Bin (%1 байт):
         <translation type="unfinished">Ошибка запуска исполняемого файла</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Заменить конфигурационный файл?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Вы хотите заменить %1?</translation>
     </message>
@@ -1445,8 +1455,8 @@ Bin (%1 байт):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Данные этого мода не найдены</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 52 - 44
launcher/translation/spanish.ts

@@ -383,7 +383,7 @@ Instalar lo correctamente descargado?</translation>
         <translation>Inteligencia Artificial</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Escala de la interfaz</translation>
     </message>
@@ -393,7 +393,7 @@ Instalar lo correctamente descargado?</translation>
         <translation>IA neutral en batallas</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>IA enemiga en batallas</translation>
     </message>
@@ -423,7 +423,7 @@ Instalar lo correctamente descargado?</translation>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation type="unfinished"></translation>
     </message>
@@ -445,7 +445,7 @@ Instalar lo correctamente descargado?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -490,22 +490,27 @@ Instalar lo correctamente descargado?</translation>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -516,22 +521,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -571,7 +576,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation type="unfinished"></translation>
     </message>
@@ -586,7 +591,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation type="unfinished"></translation>
     </message>
@@ -601,15 +606,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -631,22 +631,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Ventana</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Ventana completa sin bordes</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Pantalla completa</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Límite de autosaves (0 = sin límite)</translation>
     </message>
@@ -656,7 +656,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Límite de fotogramas</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Prefijo autoguardado</translation>
     </message>
@@ -671,7 +671,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>Vacio = prefijo del mapa</translation>
     </message>
@@ -721,7 +721,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Idioma de VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Resolución</translation>
     </message>
@@ -756,32 +756,32 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Mostrar introducción</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Comprovar al inicio</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Activado</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Desactivado</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Activar</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>No Instalado</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Instalar</translation>
     </message>
@@ -1140,19 +1140,27 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1321,12 +1329,12 @@ Bin (%1 bytes):
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1414,7 +1422,7 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
+        <source>Mod data was not found</source>
         <translation type="unfinished"></translation>
     </message>
     <message>

+ 53 - 45
launcher/translation/swedish.ts

@@ -383,7 +383,7 @@ Installation framgångsrikt nedladdad?</translation>
         <translation>Artificiell intelligens</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Gränssnittsskalning</translation>
     </message>
@@ -393,7 +393,7 @@ Installation framgångsrikt nedladdad?</translation>
         <translation>Neutralt AI i strider</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Fiendens AI i strider</translation>
     </message>
@@ -418,7 +418,7 @@ Installation framgångsrikt nedladdad?</translation>
         <translation>Automatiska AI-strider</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Styrspak-känslighet</translation>
     </message>
@@ -440,7 +440,7 @@ Installation framgångsrikt nedladdad?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Automatisk</translation>
     </message>
@@ -485,22 +485,27 @@ Installation framgångsrikt nedladdad?</translation>
         <translation>Adressen till online-väntrummet</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Skalning av markör</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Skalbar</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Övrigt</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -511,22 +516,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Skalning av teckensnitt (experimentell)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Original</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Uppskalnings-filter</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Grundläggande</translation>
     </message>
@@ -566,7 +571,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Återställ</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Nätverk</translation>
     </message>
@@ -581,7 +586,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Relativ pekarhastighet</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Musikvolym</translation>
     </message>
@@ -596,15 +601,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ingång/indata - Mus</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Utökad beröringslängd</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -626,22 +626,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ljudvolym</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Fönsterläge</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Kantlös helskärm</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Exklusiv helskärm</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Antal platser för automatisk-sparning (0 = inaktiverad)</translation>
     </message>
@@ -656,7 +656,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Gräns ​​för bildhastighet</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Prefix för automatisk-sparning</translation>
     </message>
@@ -671,7 +671,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Styrspaks-acceleration</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>tomt = kartnamnsprefix</translation>
     </message>
@@ -706,7 +706,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Heroes III - Översättning</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Kontrollera vid uppstart</translation>
     </message>
@@ -726,7 +726,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>VCMI-språk</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Upplösning</translation>
     </message>
@@ -761,27 +761,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Visa intro</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Aktiv</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Inaktiverad</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Aktivera</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Inte installerad</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Installera</translation>
     </message>
@@ -1141,19 +1141,27 @@ Orsak till fel: </translation>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI kompilerades utan stöd för innoextract, vilket behövs för att extrahera exe-filer!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1317,12 +1325,12 @@ Bin (%1 bytes):
         <translation type="unfinished">Fel vid uppstart av körbar fil (.exe)</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation type="unfinished">Byt ut konfigurationsfilen?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation type="unfinished">Vill du ersätta %1?</translation>
     </message>
@@ -1415,8 +1423,8 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Modd-data för denna modd hittades inte</translation>
+        <source>Mod data was not found</source>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 68 - 50
launcher/translation/ukrainian.ts

@@ -383,7 +383,7 @@ Install successfully downloaded?</source>
         <translation>Штучний інтелект</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Масштабування інтерфейсу</translation>
     </message>
@@ -393,7 +393,7 @@ Install successfully downloaded?</source>
         <translation>Нейтральний ШІ в боях</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Ворожий ШІ в боях</translation>
     </message>
@@ -423,7 +423,7 @@ Install successfully downloaded?</source>
         <translation>ШІ автобою</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation>Чутливість стиків</translation>
     </message>
@@ -445,7 +445,7 @@ Install successfully downloaded?</source>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation>Автоматично</translation>
     </message>
@@ -490,22 +490,27 @@ Install successfully downloaded?</source>
         <translation>Адреса онлайн-лобі</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation>Кнопка «Назад» як права кнопка миші</translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation>Масштабування курсору</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation>Векторні</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation>Інше</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -522,22 +527,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
 Повноекранний ексклюзивний режим - гра займатиме весь екран і використовуватиме вибрану роздільну здатність.</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation>Масштабування шрифтів ( експериментально)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation>Оригінальні</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation>Фільтр масштабування</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation>Базова</translation>
     </message>
@@ -577,7 +582,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Скинути</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation>Мережа</translation>
     </message>
@@ -592,7 +597,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Швидкість відносного вказівника</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation>Гучність музики</translation>
     </message>
@@ -607,15 +612,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Введення - Миша</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation>Тривалість довгого дотику</translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation>%</translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -637,22 +637,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Гучність звуку</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>У вікні</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Повноекранне вікно</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Повноекранний (ексклюзивно)</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Кількість автозбережень</translation>
     </message>
@@ -662,7 +662,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Обмеження частоти кадрів</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Префікс назв автозбережень</translation>
     </message>
@@ -677,7 +677,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Прискорення стиків</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>(використовувати назву карти)</translation>
     </message>
@@ -712,7 +712,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Переклад Heroes III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Перевіряти на старті</translation>
     </message>
@@ -732,7 +732,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Мова VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Роздільна здатність</translation>
     </message>
@@ -767,27 +767,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Вступні відео</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Активні</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Деактивований</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Активувати</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Не встановлено</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Встановити</translation>
     </message>
@@ -823,7 +823,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
     <message>
         <location filename="../modManager/chroniclesextractor.cpp" line="144"/>
         <source>Heroes Chronicles %1 - %2</source>
-        <translation type="unfinished">Хроніки Героїв %1 - %2</translation>
+        <translation>Хроніки Героїв %1 - %2</translation>
     </message>
 </context>
 <context>
@@ -1157,23 +1157,41 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation>VCMI було створено без підтримки innoextract, яка необхідна для розпакування exe-файлів!</translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation>SHA1 хеш наданих файлів:
-Exe (%1 байтів):
-%2</translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation>
+            <numerusform>SHA1 хеш наданих файлів:
+Exe (%n байт):
+%1</numerusform>
+            <numerusform>SHA1 хеш наданих файлів:
+Exe (%n байти):
+%1</numerusform>
+            <numerusform>SHA1 хеш наданих файлів:
+Exe (%n байтів):
+%1</numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
         <translation>
-Bin (%1 байтів):
-%2</translation>
+            <numerusform>
+Bin (%n байт):
+%1</numerusform>
+            <numerusform>
+Bin (%n байти):
+%1</numerusform>
+            <numerusform>
+Bin (%n байтів):
+%1</numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1349,15 +1367,15 @@ Bin (%1 байтів):
     <message>
         <location filename="../mainwindow_moc.cpp" line="46"/>
         <source>Error starting executable</source>
-        <translation type="unfinished">Помилка запуску виконуваного файлу</translation>
+        <translation>Помилка запуску виконуваного файлу</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation>Замінити файл налаштувань?</translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation>Ви дійсно хочете замінити %1?</translation>
     </message>
@@ -1445,8 +1463,8 @@ Bin (%1 байтів):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
-        <translation>Дані з цією модифікацією не знайдено</translation>
+        <source>Mod data was not found</source>
+        <translation>Не знайдено файли даних модифікації</translation>
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="252"/>

+ 50 - 44
launcher/translation/vietnamese.ts

@@ -376,7 +376,7 @@ Install successfully downloaded?</source>
         <translation>Trí tuệ nhân tạo</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1038"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1061"/>
         <source>Interface Scaling</source>
         <translation>Phóng đại giao diện</translation>
     </message>
@@ -386,7 +386,7 @@ Install successfully downloaded?</source>
         <translation>Máy hoang dã trong trận đánh</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1019"/>
         <source>Enemy AI in battles</source>
         <translation>Máy đối thủ trong trận đánh</translation>
     </message>
@@ -416,7 +416,7 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1399"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1422"/>
         <source>Sticks Sensitivity</source>
         <translation type="unfinished"></translation>
     </message>
@@ -438,7 +438,7 @@ Install successfully downloaded?</source>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="83"/>
         <location filename="../settingsView/csettingsview_moc.ui" line="539"/>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1389"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1412"/>
         <source>Automatic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -483,22 +483,27 @@ Install successfully downloaded?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1079"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="996"/>
+        <source>Handle back as right mouse button</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1102"/>
         <source>Cursor Scaling</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1108"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1131"/>
         <source>Scalable</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1167"/>
         <source>Miscellaneous</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1182"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
         <source>Select a display mode for the game
 
 Windowed - the game will run inside a window that covers part of your screen.
@@ -509,22 +514,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1303"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1326"/>
         <source>Font Scaling (experimental)</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1367"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1390"/>
         <source>Original</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1406"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1429"/>
         <source>Upscaling Filter</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1439"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1462"/>
         <source>Basic</source>
         <translation type="unfinished"></translation>
     </message>
@@ -564,7 +569,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1129"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1152"/>
         <source>Network</source>
         <translation type="unfinished"></translation>
     </message>
@@ -579,7 +584,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1045"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1068"/>
         <source>Music Volume</source>
         <translation type="unfinished"></translation>
     </message>
@@ -594,15 +599,10 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1226"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1249"/>
         <source>Long Touch Duration</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="461"/>
-        <source>%</source>
-        <translation type="unfinished"></translation>
-    </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="873"/>
         <source>Controller Click Tolerance</source>
@@ -624,22 +624,22 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1195"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1218"/>
         <source>Windowed</source>
         <translation>Cửa sổ</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1200"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1223"/>
         <source>Borderless fullscreen</source>
         <translation>Toàn màn hình không viền</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1205"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1228"/>
         <source>Exclusive fullscreen</source>
         <translation>Toàn màn hình riêng biệt</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1003"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1026"/>
         <source>Autosave limit (0 = off)</source>
         <translation>Giới hạn lưu tự động (0 = không giới hạn)</translation>
     </message>
@@ -649,7 +649,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Giới hạn khung hình</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1413"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1436"/>
         <source>Autosave prefix</source>
         <translation>Thêm tiền tố vào lưu tự động</translation>
     </message>
@@ -664,7 +664,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1354"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1377"/>
         <source>empty = map name prefix</source>
         <translation>Rỗng = tên bản đồ</translation>
     </message>
@@ -699,7 +699,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Bản dịch Heroes III</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1233"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1256"/>
         <source>Check on startup</source>
         <translation>Kiểm tra khi khởi động</translation>
     </message>
@@ -719,7 +719,7 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Ngôn ngữ VCMI</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.ui" line="1420"/>
+        <location filename="../settingsView/csettingsview_moc.ui" line="1443"/>
         <source>Resolution</source>
         <translation>Độ phân giải</translation>
     </message>
@@ -754,27 +754,27 @@ Fullscreen Exclusive Mode - the game will cover the entirety of your screen and
         <translation>Hiện thị giới thiệu</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="530"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="537"/>
         <source>Active</source>
         <translation>Bật</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="535"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
         <source>Disabled</source>
         <translation>Tắt</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="536"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="543"/>
         <source>Enable</source>
         <translation>Bật</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="541"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="548"/>
         <source>Not Installed</source>
         <translation>Chưa cài đặt</translation>
     </message>
     <message>
-        <location filename="../settingsView/csettingsview_moc.cpp" line="542"/>
+        <location filename="../settingsView/csettingsview_moc.cpp" line="549"/>
         <source>Install</source>
         <translation>Cài đặt</translation>
     </message>
@@ -1133,19 +1133,25 @@ error reason: </source>
         <source>VCMI was compiled without innoextract support, which is needed to extract exe files!</source>
         <translation type="unfinished"></translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="134"/>
         <source>SHA1 hash of provided files:
-Exe (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Exe (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+        </translation>
     </message>
-    <message>
+    <message numerus="yes">
         <location filename="../innoextract.cpp" line="136"/>
         <source>
-Bin (%1 bytes):
-%2</source>
-        <translation type="unfinished"></translation>
+Bin (%n bytes):
+%1</source>
+        <comment>param is hash</comment>
+        <translation type="unfinished">
+            <numerusform></numerusform>
+        </translation>
     </message>
     <message>
         <location filename="../innoextract.cpp" line="139"/>
@@ -1314,12 +1320,12 @@ Bin (%1 bytes):
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Replace config file?</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location filename="../mainwindow_moc.cpp" line="284"/>
+        <location filename="../mainwindow_moc.cpp" line="287"/>
         <source>Do you want to replace %1?</source>
         <translation type="unfinished"></translation>
     </message>
@@ -1407,7 +1413,7 @@ Bin (%1 bytes):
     </message>
     <message>
         <location filename="../modManager/modstatecontroller.cpp" line="248"/>
-        <source>Data with this mod was not found</source>
+        <source>Mod data was not found</source>
         <translation type="unfinished"></translation>
     </message>
     <message>

+ 51 - 57
lib/CConsoleHandler.cpp

@@ -23,6 +23,15 @@ DLL_LINKAGE CConsoleHandler * console = nullptr;
 
 VCMI_LIB_NAMESPACE_END
 
+#if defined(NDEBUG) && !defined(VCMI_ANDROID)
+#define USE_ON_TERMINATE
+#endif
+
+#if defined(NDEBUG) && defined(VCMI_WINDOWS)
+#define USE_UNHANDLED_EXCEPTION_FILTER
+#define CREATE_MEMORY_DUMP
+#endif
+
 #ifndef VCMI_WINDOWS
 	using TColor = std::string;
 	#define CONSOLE_GREEN "\x1b[1;32m"
@@ -57,27 +66,44 @@ static TColor defColor;
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-#ifdef VCMI_WINDOWS
+#ifdef CREATE_MEMORY_DUMP
 
-void printWinError()
+static void createMemoryDump(MINIDUMP_EXCEPTION_INFORMATION * meinfo)
 {
-	//Get error code
-	int error = GetLastError();
-	if(!error)
+	//create file where dump will be placed
+	char *mname = nullptr;
+	char buffer[MAX_PATH + 1];
+	HMODULE hModule = nullptr;
+	GetModuleFileNameA(hModule, buffer, MAX_PATH);
+	mname = strrchr(buffer, '\\');
+	if (mname != nullptr)
+		mname++;
+	else
+		mname = buffer;
+
+	strcat(mname, "_crashinfo.dmp");
+	HANDLE dfile = CreateFileA(mname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
+	logGlobal->error("Crash info will be put in %s", mname);
+
+	auto dumpType = MiniDumpWithDataSegs;
+
+	if(settings["general"]["extraDump"].Bool())
 	{
-		logGlobal->error("No Win error information set.");
-		return;
+		dumpType = (MINIDUMP_TYPE)(
+			MiniDumpWithFullMemory
+			| MiniDumpWithFullMemoryInfo
+			| MiniDumpWithHandleData
+			| MiniDumpWithUnloadedModules
+			| MiniDumpWithThreadInfo);
 	}
-	logGlobal->error("Error %d encountered:", error);
-
-	//Get error description
-	char* pTemp = nullptr;
-	FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
-		nullptr, error,  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPSTR)&pTemp, 1, nullptr);
-	logGlobal->error(pTemp);
-	LocalFree( pTemp );
+
+	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dfile, dumpType, meinfo, nullptr, nullptr);
+	MessageBoxA(0, "VCMI has crashed. We are sorry. File with information about encountered problem has been created.", "VCMI Crashhandler", MB_OK | MB_ICONERROR);
 }
 
+#endif
+
+#ifdef USE_UNHANDLED_EXCEPTION_FILTER
 const char* exceptionName(DWORD exc)
 {
 #define EXC_CASE(EXC)	case EXCEPTION_##EXC : return "EXCEPTION_" #EXC
@@ -111,39 +137,6 @@ const char* exceptionName(DWORD exc)
 #undef EXC_CASE
 }
 
-static void createMemoryDump(MINIDUMP_EXCEPTION_INFORMATION * meinfo)
-{
-	//create file where dump will be placed
-	char *mname = nullptr;
-	char buffer[MAX_PATH + 1];
-	HMODULE hModule = nullptr;
-	GetModuleFileNameA(hModule, buffer, MAX_PATH);
-	mname = strrchr(buffer, '\\');
-	if (mname != nullptr)
-		mname++;
-	else
-		mname = buffer;
-
-	strcat(mname, "_crashinfo.dmp");
-	HANDLE dfile = CreateFileA(mname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0, 0);
-	logGlobal->error("Crash info will be put in %s", mname);
-
-	auto dumpType = MiniDumpWithDataSegs;
-
-	if(settings["general"]["extraDump"].Bool())
-	{
-		dumpType = (MINIDUMP_TYPE)(
-			MiniDumpWithFullMemory
-			| MiniDumpWithFullMemoryInfo
-			| MiniDumpWithHandleData
-			| MiniDumpWithUnloadedModules
-			| MiniDumpWithThreadInfo);
-	}
-
-	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), dfile, dumpType, meinfo, nullptr, nullptr);
-	MessageBoxA(0, "VCMI has crashed. We are sorry. File with information about encountered problem has been created.", "VCMI Crashhandler", MB_OK | MB_ICONERROR);
-}
-
 LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 {
 	logGlobal->error("Disaster happened.");
@@ -161,14 +154,15 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 	//exception info to be placed in the dump
 	MINIDUMP_EXCEPTION_INFORMATION meinfo = {threadId, exception, TRUE};
 
+#ifdef CREATE_MEMORY_DUMP
 	createMemoryDump(&meinfo);
+#endif
 
 	return EXCEPTION_EXECUTE_HANDLER;
 }
-
 #endif
 
-#ifdef NDEBUG
+#ifdef USE_ON_TERMINATE
 [[noreturn]] static void onTerminate()
 {
 	logGlobal->error("Disaster happened.");
@@ -198,7 +192,7 @@ LONG WINAPI onUnhandledException(EXCEPTION_POINTERS* exception)
 	stream << boost::stacktrace::stacktrace();
 	logGlobal->error("%s", stream.str());
 
-#ifdef VCMI_WINDOWS
+#ifdef CREATE_MEMORY_DUMP
 	const DWORD threadId = ::GetCurrentThreadId();
 	logGlobal->error("Thread ID: %d", threadId);
 
@@ -298,19 +292,19 @@ CConsoleHandler::CConsoleHandler():
 
 	GetConsoleScreenBufferInfo(handleErr, &csbi);
 	defErrColor = csbi.wAttributes;
-#ifdef NDEBUG
-#ifndef VCMI_ANDROID
-	SetUnhandledExceptionFilter(onUnhandledException);
-#endif
-#endif
 #else
 	defColor = "\x1b[0m";
 #endif
 
-#ifdef NDEBUG
+#ifdef USE_UNHANDLED_EXCEPTION_FILTER
+	SetUnhandledExceptionFilter(onUnhandledException);
+#endif
+
+#ifdef USE_ON_TERMINATE
 	std::set_terminate(onTerminate);
 #endif
 }
+
 CConsoleHandler::~CConsoleHandler()
 {
 	logGlobal->info("Killing console...");

+ 2 - 1
lib/CCreatureSet.h

@@ -59,7 +59,8 @@ public:
 		{
 			CreatureID creatureID;
 			h & creatureID;
-			setType(creatureID.toCreature());
+			if(creatureID != CreatureID::NONE)
+				setType(creatureID.toCreature());
 		}
 
 		h & count;

+ 1 - 1
lib/bonuses/IBonusBearer.cpp

@@ -59,7 +59,7 @@ TConstBonusListPtr IBonusBearer::getBonusesOfType(BonusType type) const
 TConstBonusListPtr IBonusBearer::getBonusesOfType(BonusType type, BonusSubtypeID subtype) const
 {
 	std::string cachingStr = "type_" + std::to_string(static_cast<int>(type)) + "_" + subtype.toString();
-	CSelector s = Selector::type()(type);
+	CSelector s = Selector::typeSubtype(type, subtype);
 	return getBonuses(s, cachingStr);
 }
 

+ 6 - 6
lib/entities/faction/CTownHandler.cpp

@@ -389,13 +389,10 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
 
 void CTownHandler::loadBuildings(CTown * town, const JsonNode & source)
 {
-	if(source.isStruct())
+	for(const auto & node : source.Struct())
 	{
-		for(const auto & node : source.Struct())
-		{
-			if (!node.second.isNull())
-				loadBuilding(town, node.first, node.second);
-		}
+		if (!node.second.isNull())
+			loadBuilding(town, node.first, node.second);
 	}
 }
 
@@ -874,6 +871,9 @@ void CTownHandler::beforeValidate(JsonNode & object)
 
 	for (auto & building : object["town"]["buildings"].Struct())
 	{
+		if (building.second.isNull())
+			continue;
+
 		inheritBuilding(building.first, building.second);
 		if (building.second.Struct().count("type"))
 			inheritBuilding(building.second["type"].String(), building.second);

+ 8 - 0
lib/mapObjects/CGTownInstance.cpp

@@ -1247,6 +1247,14 @@ void CGTownInstance::postDeserialize()
 	setNodeType(CBonusSystemNode::TOWN);
 	for(auto & building : rewardableBuildings)
 		building.second->town = this;
+
+	if (getFactionID().hasValue())
+	{
+		vstd::erase_if(builtBuildings, [this](const BuildingID & buildID)
+		{
+			return getTown()->buildings.count(buildID) == 0;
+		});
+	}
 }
 
 std::map<BuildingID, TownRewardableBuildingInstance*> CGTownInstance::convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector)

+ 12 - 0
lib/modding/IdentifierStorage.cpp

@@ -442,6 +442,7 @@ bool CIdentifierStorage::resolveIdentifier(const ObjectCallback & request) const
 	}
 
 	// error found. Try to generate some debug info
+	failedRequests.push_back(request);
 	showIdentifierResolutionErrorDetails(request);
 	return false;
 }
@@ -494,4 +495,15 @@ void CIdentifierStorage::debugDumpIdentifiers()
 	}
 }
 
+std::vector<std::string> CIdentifierStorage::getModsWithFailedRequests() const
+{
+	std::vector<std::string> result;
+
+	for (const auto & request : failedRequests)
+		if (!vstd::contains(result, request.localScope))
+			result.push_back(request.localScope);
+
+	return result;
+}
+
 VCMI_LIB_NAMESPACE_END

+ 6 - 0
lib/modding/IdentifierStorage.h

@@ -58,6 +58,9 @@ class DLL_LINKAGE CIdentifierStorage
 	std::multimap<std::string, ObjectData> registeredObjects;
 	mutable std::vector<ObjectCallback> scheduledRequests;
 
+	/// All non-optional requests that have failed to resolve, for debug & error reporting
+	mutable std::vector<ObjectCallback> failedRequests;
+
 	ELoadingState state = ELoadingState::LOADING;
 
 	/// Helper method that dumps all registered identifier into log file
@@ -101,6 +104,9 @@ public:
 
 	/// called at the very end of loading to check for any missing ID's
 	void finalize();
+
+	/// Returns list of all mods, from which at least one identifier has failed to resolve
+	std::vector<std::string> getModsWithFailedRequests() const;
 };
 
 VCMI_LIB_NAMESPACE_END

+ 17 - 4
lib/modding/ModManager.cpp

@@ -549,7 +549,7 @@ double ModManager::getInstalledModSizeMegabytes(const TModID & modName) const
 
 void ModManager::eraseMissingModsFromPreset()
 {
-	const TModList & installedMods = modsState->getInstalledMods();
+	const TModList & installedMods = getInstalledValidMods();
 	const TModList & rootMods = modsPreset->getActiveRootMods();
 
 	modsPreset->removeOldMods(installedMods);
@@ -572,7 +572,7 @@ void ModManager::eraseMissingModsFromPreset()
 
 void ModManager::addNewModsToPreset()
 {
-	const TModList & installedMods = modsState->getInstalledMods();
+	const TModList & installedMods = getInstalledValidMods();
 
 	for(const auto & modID : installedMods)
 	{
@@ -591,6 +591,19 @@ void ModManager::addNewModsToPreset()
 	}
 }
 
+TModList ModManager::getInstalledValidMods() const
+{
+	TModList installedMods = modsState->getInstalledMods();
+	TModList validMods = modsStorage->getAllMods();
+
+	TModList result;
+	for (const auto & modID : installedMods)
+		if (vstd::contains(validMods, modID))
+			result.push_back(modID);
+
+	return result;
+}
+
 TModList ModManager::collectDependenciesRecursive(const TModID & modID) const
 {
 	TModList result;
@@ -688,7 +701,7 @@ void ModManager::updatePreset(const ModDependenciesResolver & testResolver)
 
 	for (const auto & modID : newActiveMods)
 	{
-		assert(vstd::contains(modsState->getInstalledMods(), modID));
+		assert(vstd::contains(getInstalledValidMods(), modID));
 		modsPreset->setModActive(modID, true);
 	}
 
@@ -847,7 +860,7 @@ std::tuple<std::string, TModList> ModManager::importPreset(const JsonNode & data
 	std::string presetName = modsPreset->importPreset(data);
 
 	TModList requiredMods = modsPreset->getRootMods(presetName);
-	TModList installedMods = modsState->getInstalledMods();
+	TModList installedMods = getInstalledValidMods();
 
 	TModList missingMods;
 	for (const auto & modID : requiredMods)

+ 1 - 0
lib/modding/ModManager.h

@@ -132,6 +132,7 @@ class DLL_LINKAGE ModManager : boost::noncopyable
 	void addNewModsToPreset();
 	void updatePreset(const ModDependenciesResolver & newData);
 
+	TModList getInstalledValidMods() const;
 	TModList collectDependenciesRecursive(const TModID & modID) const;
 
 	void tryEnableMod(const TModID & modList);

+ 1 - 1
lib/rmg/Functions.cpp

@@ -24,7 +24,7 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-void replaceWithCurvedPath(rmg::Path & path, const Zone & zone, const int3 & src, bool onlyStraight)
+void replaceWithCurvedPath(rmg::Path & path, const Zone & zone, const int3 & src, bool onlyStraight /* = true */)
 {
 	auto costFunction = rmg::Path::createCurvedCostFunction(zone.area()->getBorder());
 	auto pathArea = zone.areaForRoads();

+ 5 - 0
lib/rmg/RmgObject.cpp

@@ -271,6 +271,11 @@ const int3 & Object::getPosition() const
 int3 Object::getVisitablePosition() const
 {
 	assert(!dInstances.empty());
+
+	// FIXME: This doesn't take into account Hota monster offset
+	if (guarded)
+		return getGuardPos();
+
 	for(const auto & instance : dInstances)
 		if(!getArea().contains(instance.getVisitablePosition()))
 			return instance.getVisitablePosition();

+ 8 - 4
lib/rmg/modificators/ObjectManager.cpp

@@ -418,12 +418,14 @@ bool ObjectManager::createMonoliths()
 			logGlobal->error("Failed to fill zone %d due to lack of space", zone.getId());
 			return false;
 		}
+
+		// Object must be placed first so that curved path won't go through occupied tiles
+		placeObject(rmgObject, guarded, true, objInfo.createRoad);
 		
-		// Once it can be created, replace with curved path
+		// Once it can be created, replace with curved path.
 		replaceWithCurvedPath(path, zone, rmgObject.getVisitablePosition());
 		
 		zone.connectPath(path);
-		placeObject(rmgObject, guarded, true, objInfo.createRoad);
 	}
 
 	vstd::erase_if(requiredObjects, [](const auto & objInfo)
@@ -452,6 +454,8 @@ bool ObjectManager::createRequiredObjects()
 			logGlobal->error("Failed to fill zone %d due to lack of space", zone.getId());
 			return false;
 		}
+
+		placeObject(rmgObject, guarded, true, objInfo.createRoad);
 		if (objInfo.createRoad)
 		{
 			// Once valid path can be created, replace with curved path
@@ -459,7 +463,6 @@ bool ObjectManager::createRequiredObjects()
 		}
 		
 		zone.connectPath(path);
-		placeObject(rmgObject, guarded, true, objInfo.createRoad);
 		
 		for(const auto & nearby : nearbyObjects)
 		{
@@ -631,7 +634,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
 		for (auto id : adjacentZones)
 		{
 			auto otherZone = map.getZones().at(id);
-			if ((otherZone->getType() == ETemplateZoneType::WATER) == (zone.getType()	== ETemplateZoneType::WATER))
+			if ((otherZone->getType() == ETemplateZoneType::WATER) == (zone.getType() == ETemplateZoneType::WATER))
 			{
 				// Do not update other zone if only one is water
 				auto manager = otherZone->getModificator<ObjectManager>();
@@ -672,6 +675,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
 
 			if (object.isGuarded())
 			{
+				// Do not route roads through guarded objects
 				rp->areaVisitable().add(instance->getVisitablePosition());
 			}
 		}

+ 22 - 12
lib/rmg/modificators/RoadPlacer.cpp

@@ -76,25 +76,35 @@ bool RoadPlacer::createRoad(const int3 & destination)
 
 	auto simpleRoutig = [this, &border](const int3& src, const int3& dst)
 	{
-		if(areaIsolated().contains(dst))
+		if(std::abs((src - dst).y) == 1)
 		{
-			return 1000.0f; //Do not route road behind objects that are not visitable from top, such as Monoliths
+			//Do not allow connections straight up through object not visitable from top
+			if(areaIsolated().contains(dst) || areaIsolated().contains(src))
+			{
+				return 1e12f;
+			}
 		}
 		else
 		{
-			float ret = dst.dist2d(src);
-
-			if (visitableTiles.contains(src) || visitableTiles.contains(dst))
-			{
-				ret *= VISITABLE_PENALTY;
-			}
-			float dist = border.distanceSqr(dst);
-			if(dist > 1.0f)
+			if(areaIsolated().contains(dst))
 			{
-				ret /= dist;
+				//Simply do not route road behind objects that are not visitable from top, such as Monoliths
+				return 1e6f;
 			}
-			return ret;
 		}
+
+		float ret = dst.dist2d(src);
+
+		if (visitableTiles.contains(src) || visitableTiles.contains(dst))
+		{
+			ret *= VISITABLE_PENALTY;
+		}
+		float dist = border.distanceSqr(dst);
+		if(dist > 1.0f)
+		{
+			ret /= dist;
+		}
+		return ret;
 	};
 	
 	auto res = path.search(destination, true, simpleRoutig);

+ 26 - 6
server/NetPacksLobbyServer.cpp

@@ -170,8 +170,10 @@ void ApplyOnServerNetPackVisitor::visitLobbySetCampaign(LobbySetCampaign & pack)
 
 	bool isCurrentMapConquerable = pack.ourCampaign->currentScenario() && pack.ourCampaign->isAvailable(*pack.ourCampaign->currentScenario());
 
-	for(auto scenarioID : pack.ourCampaign->allScenarios())
+	auto scenarios = pack.ourCampaign->allScenarios();
+	for(std::set<CampaignScenarioID>::reverse_iterator itr = scenarios.rbegin(); itr != scenarios.rend(); itr++) // reverse -> on multiple scenario selection set lowest id at the end
 	{
+		auto scenarioID = *itr;
 		if(pack.ourCampaign->isAvailable(scenarioID))
 		{
 			if(!isCurrentMapConquerable || (isCurrentMapConquerable && scenarioID == *pack.ourCampaign->currentScenario()))
@@ -452,10 +454,19 @@ void ApplyOnServerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
 			return;
 		}
 
-		auto file = boost::filesystem::canonical(*name);
-		boost::filesystem::remove(file);
-		if(boost::filesystem::is_empty(file.parent_path()))
-			boost::filesystem::remove(file.parent_path());
+		boost::system::error_code ec;
+		auto file = boost::filesystem::canonical(*name, ec);
+
+		if (ec)
+		{
+			logGlobal->error("Failed to delete file '%s'. Reason: %s", res.getOriginalName(), ec.message());
+		}
+		else
+		{
+			boost::filesystem::remove(file);
+			if(boost::filesystem::is_empty(file.parent_path()))
+				boost::filesystem::remove(file.parent_path());
+		}
 	}
 	else if(pack.type == LobbyDelete::EType::SAVEGAME_FOLDER)
 	{
@@ -466,8 +477,17 @@ void ApplyOnServerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
 			logGlobal->error("Failed to find folder with name '%s'", res.getOriginalName());
 			return;
 		}
+
+		boost::system::error_code ec;
 		auto folder = boost::filesystem::canonical(*name);
-		boost::filesystem::remove_all(folder);
+		if (ec)
+		{
+			logGlobal->error("Failed to delete folder '%s'. Reason: %s", res.getOriginalName(), ec.message());
+		}
+		else
+		{
+			boost::filesystem::remove_all(folder);
+		}
 	}
 
 	LobbyUpdateState lus;