Ver código fonte

Merge remote-tracking branch 'upstream/develop' into develop

Xilmi 1 ano atrás
pai
commit
d679ee72b9

+ 11 - 5
AI/BattleAI/AttackPossibility.cpp

@@ -44,24 +44,30 @@ void DamageCache::buildObstacleDamageCache(std::shared_ptr<HypotheticBattle> hb,
 		if(!triggerIsNegative)
 			continue;
 
-		const auto * hero = hb->battleGetFightingHero(spellObstacle->casterSide);
-		auto caster = spells::ObstacleCasterProxy(hb->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle);
+		std::unique_ptr<spells::BattleCast> cast = nullptr;
+		if(spellObstacle->obstacleType == SpellCreatedObstacle::EObstacleType::SPELL_CREATED)
+		{
+			const auto * hero = hb->battleGetFightingHero(spellObstacle->casterSide);
+			auto caster = spells::ObstacleCasterProxy(hb->getSidePlayer(spellObstacle->casterSide), hero, *spellObstacle);
+			cast = std::make_unique<spells::BattleCast>(spells::BattleCast(hb.get(), &caster, spells::Mode::PASSIVE, obst->getTrigger().toSpell()));
+		}
 
 		auto affectedHexes = obst->getAffectedTiles();
 		auto stacks = hb->battleGetUnitsIf([](const battle::Unit * u) -> bool {
 			return u->alive() && !u->isTurret() && u->getPosition().isValid();
 		});
 
+		std::shared_ptr<HypotheticBattle> inner = std::make_shared<HypotheticBattle>(hb->env, hb);
+
 		for(auto stack : stacks)
 		{
-			std::shared_ptr<HypotheticBattle> inner = std::make_shared<HypotheticBattle>(hb->env, hb);
-			auto cast = spells::BattleCast(hb.get(), &caster, spells::Mode::PASSIVE, obst->getTrigger().toSpell());
 			auto updated = inner->getForUpdate(stack->unitId());
 
 			spells::Target target;
 			target.push_back(spells::Destination(updated.get()));
 
-			cast.castEval(inner->getServerCallback(), target);
+			if(cast)
+				cast->castEval(inner->getServerCallback(), target);
 
 			auto damageDealt = stack->getAvailableHealth() - updated->getAvailableHealth();
 

+ 4 - 1
AI/BattleAI/BattleEvaluator.cpp

@@ -337,7 +337,10 @@ BattleAction BattleEvaluator::moveOrAttack(const CStack * stack, BattleHex hex,
 	}
 	else
 	{
-		return BattleAction::makeMove(stack, hex);
+		if(stack->position == hex)
+			return BattleAction::makeDefend(stack);
+		else
+			return BattleAction::makeMove(stack, hex);
 	}
 }
 

+ 8 - 0
AI/StupidAI/StupidAI.cpp

@@ -296,7 +296,11 @@ BattleAction CStupidAI::goTowards(const BattleID & battleID, const CStack * stac
 	for(auto hex : hexes)
 	{
 		if(vstd::contains(avHexes, hex))
+		{
+			if(stack->position == hex)
+				return BattleAction::makeDefend(stack);
 			return BattleAction::makeMove(stack, hex);
+		}
 
 		if(stack->coversPos(hex))
 		{
@@ -336,7 +340,11 @@ BattleAction CStupidAI::goTowards(const BattleID & battleID, const CStack * stac
 			}
 
 			if(vstd::contains(avHexes, currentDest))
+			{
+				if(stack->position == currentDest)
+					return BattleAction::makeDefend(stack);
 				return BattleAction::makeMove(stack, currentDest);
+			}
 
 			currentDest = reachability.predecessors[currentDest];
 		}

+ 54 - 10
ChangeLog.md

@@ -1,27 +1,32 @@
-# 1.5.5 -> 1.6.0 (in development)
+# 1.5.7 -> 1.6.0 (in development)
+
+### Major changes
+* Implemented handicap system, with options to reduce income and growth in addition to starting resources restriction
+* Game will now show statistics after scenario completion, such as resources or army strength over time
+* Implemented spell quick selection panel in combat
+* Implemented adventure map overlay accessible via Alt key that highlights all interactive objects on screen
+* Implemented xBRZ upscaling filter
+* It is now possible to import data from Heroes Chronicles (gog.com installer only) as custom campaigns
 
 ### General
 * Saved game size reduced by approximately 3 times, especially for large maps or games with a large number of mods.
 * Added option to start vcmi server on randomly selected TCP port
 * Fixed potential desynchronization between server and clients on randomization of map objects if client and server run on different operating systems
-* It is now possible to generate game statistics using `!statistic` command in game chat
 
 ### Stability
 * Fixed possible crash on connecting bluetooth mouse during gameplay on Android
 * VCMI will now write more detailed information to log file on crash due to uncaught exception
 
-### Multiplayer
-* Implemented handicap system, with options to reduce income and growth in addition to starting resources restriction
-
 ### Mechanics
 * Arrow tower will now prefer to attack more units that are viewed most dangerous instead of simply attacking top-most unit
 * Score in campaigns will now be correctly tracked for games loaded from a save
 * Fixed incorrect direction of Dragon Breath attack in some cases if wide creature attacks another wide creature
 * Map events and town events are now triggered on start of turn of player affected by event, in line with H3 instead of triggering on start of new day for all players
+* Neutral towns should now have initial garrison and weekly growth of garrison identical to H3
+* It is now possible to buy a new war machine in town if hero has different war machine in the slot
 
 ### Interface
-* Implemented spell quick selection panel in combat
-* Implemented adventure map overlay accessible via Alt key that highlights all interactive objects on screen
+* Added option to drag map with right-click
 * Added hotkeys to reorder list of owned towns or heroes
 * The number of units resurrected using the Life Drain ability is now written to the combat log.
 * Fixed playback of audio stream with different formats from video files in some Heroes 3 versions
@@ -29,6 +34,7 @@
 * When resuming video playback, the video will now be continued instead of being restarted.
 * Reduced video decompression artefacts for video formats that store RGB rather than YUV data.
 * Fixed order of popup dialogs after battle.
+* Right-click on wandering monster on adventure map will now also show creature level and faction it belongs to
 * Added additional information to map right-click popup dialog: map author, map creation date, map version
 * Added scrollbars for selection of starting town, starting hero, and tavern invite if number of objects is too large to fit into the screen
 * Fixed incorrect battle turn queue displaying incorrect turn order when all units have waited
@@ -37,10 +43,26 @@
 * Added unassigned by default shortcuts for toggling visibility of visitable and blocked tiles
 * Spellbook button in battle is now blocked if hero has no spellbook 
 * Adventure map will no longer scroll if window is not in focus
+* Removed second info window when player loses his last town
+* Fixed hero path not updating correctly after hiring or dismissing creatures
+* Fixed missing description of a stack artifact when accessed through unit window
+* Fixed text overflow on campaign scenario window if campaign name is too long
+* Intro videos are now played inside a frame on resolutions higher than 800x600 instead of filling entire screen
 
 ### Random Maps Generator
 * Implemented connection option 'forcePortal'
 * It is now possible to connect zone to itself using pair of portals
+* It is now possible for a random map template to change game settings
+* Road settings will now be correctly loaded when opening random map setup tab
+
+### Campaigns
+* It is now possible to use .zip archive for VCMI campaigns instead of raw gzip stream
+* Fixed handling of hero placeholders in VCMI map format (.vmap)
+* Fixed not functioning hero carryover in VCMI campaigns
+* Added support for campaign outro videos, such as outro in "Song for the Father" campaign
+* Added support for rim image for intro video, such as opening videos in Heroes Chronicles
+* Added support for custom loading screen in campaigns
+* Added support for custom region definitions (such as background images) for VCMI campaigns 
 
 ### AI
 * Fixed bug where BattleAI attempts to move double-wide unit to an unreachable hex
@@ -48,6 +70,13 @@
 * Nullkiller is now capable of visiting configurable objects from mods
 * Nullkiller now uses whirlpools for map movement
 * AI can now correctly estimate effect of Dragon Breath and other similar abilities
+* Battle AI should now avoid ending turn on the moat
+* Fixed case where BattleAI will go around the map to attack ranged units if direct path is blocked by another unit
+* Fixed evaluation of effects of waiting if unit is under haste effect by Battle AI
+* Battle AI can now use location spells
+
+### Launcher
+* Added Swedish translation
 
 ### Map Editor
 * Implemented tracking of building requirements for Building Dialog
@@ -55,20 +84,35 @@
 * It is now possible to set spells allowed or required to be present in Mages Guild
 * It is now possible to add timed events to a town
 * Fixed editor not marking mod as dependency if spells from mod are used in town Mages Guild or in hero starting spells
+* It is now possible to choose road types for random map generation in editor
+* Validator will now warn in case if map has players with no heroes or towns
 
 ### Modding
 * Fixed multiple issues with configurable town buildings
 * Added documentation for configurable town buildings. See docs/Moddders/Entities_Format/Town_Buildings_Format.md
 * Replaced some of hardcoded town buildings with configurable buildings. These building types are now deprecated and will be removed in future.
+* Added support for explicitly visitable town buildings that will activate only on click and not on construction or on hero visit (Mana Vortex from HotA)
+* It is now possible to add guards to a configurable objects. All H3 creature banks are now implemented as configurable object.
+* It is now possible to define starting position of units in a guarded configurable object
+* Added `canCastWithoutSkip` parameter to a spell. If such spell is cast by a creature, its turn will not end after a spellcast
+* Mod can now provide pregenerated assets in place of autogenerated, such as large spellbook.
 * Added support for custom music and opening sound for a battlefield
 * Added support for multiple music tracks for towns
 * Added support for multiple music tracks for terrains on adventure map
 * Fixed several cases where vcmi will report errors in json without specifying filename of invalid file
-* It is now possible to use .zip archive for VCMI campaigns instead of raw gzip stream
-* Added support for custom region definitions (such as background images) for VCMI campaigns 
 * It is now possible to change minimal values of primary skills for heroes
-* Added support for HotA bank building from Factory
+* Added support for HotA Bank building from Factory
+* Added support for HotA Grotto buiding from Cove
 * Added support for HotA-style 8th creature in town
+* Town building can now define war machine produced in this building (Blacksmith or Ballista Yard)
+* Town building can now define provided fortifications - health of walls, towers, presence of moat, identifier of creature shooter on tower
+* Added DISINTEGRATE bonus
+* Added INVINCIBLE bonus
+* Added THIEVES_GUILD_ACCESS bonus that changes amount of information available in thieves guild
+* TimesStackLevelUpdater now supports commanders
+* Black market restock period setting now correctly restocks on specified date instead of restocking on all dates other than specified one
+* Game now supports vp8 and vp9 encoding for video files on all platforms
+* Json Validator will now attempt to detect typos when encountering unknown property in Json
 
 # 1.5.6 -> 1.5.7
 

+ 4 - 1
Mods/vcmi/config/vcmi/english.json

@@ -12,6 +12,7 @@
 	"vcmi.adventureMap.monsterThreat.levels.9"  : "Overpowering",
 	"vcmi.adventureMap.monsterThreat.levels.10" : "Deadly",
 	"vcmi.adventureMap.monsterThreat.levels.11" : "Impossible",
+	"vcmi.adventureMap.monsterLevel"            : "\n\nLevel %LEVEL %TOWN unit",
 
 	"vcmi.adventureMap.confirmRestartGame"               : "Are you sure you want to restart the game?",
 	"vcmi.adventureMap.noTownWithMarket"                 : "There are no available marketplaces!",
@@ -664,5 +665,7 @@
 	"core.bonus.WIDE_BREATH.name": "Wide breath",
 	"core.bonus.WIDE_BREATH.description": "Wide breath attack (multiple hexes)",
 	"core.bonus.DISINTEGRATE.name": "Disintegrate",
-	"core.bonus.DISINTEGRATE.description": "No corpse remains after death"
+	"core.bonus.DISINTEGRATE.description": "No corpse remains after death",
+	"core.bonus.INVINCIBLE.name": "Invincible",
+	"core.bonus.INVINCIBLE.description": "Cannot be affected by anything"
 }

+ 1 - 0
Mods/vcmi/config/vcmi/german.json

@@ -12,6 +12,7 @@
 	"vcmi.adventureMap.monsterThreat.levels.9"  : "Überwältigend",
 	"vcmi.adventureMap.monsterThreat.levels.10" : "Tödlich",
 	"vcmi.adventureMap.monsterThreat.levels.11" : "Unmöglich",
+	"vcmi.adventureMap.monsterLevel"            : "\n\nStufe %LEVEL %TOWN-Einheit",
 
 	"vcmi.adventureMap.confirmRestartGame"               : "Seid Ihr sicher, dass Ihr das Spiel neu starten wollt?",
 	"vcmi.adventureMap.noTownWithMarket"                 : "Kein Marktplatz verfügbar!",

+ 1 - 1
client/renderSDL/CTrueTypeFont.cpp

@@ -96,7 +96,7 @@ size_t CTrueTypeFont::getGlyphWidth(const char *data) const
 size_t CTrueTypeFont::getStringWidth(const std::string & data) const
 {
 	if (fallbackFont && fallbackFont->canRepresentString(data))
-		return fallbackFont->getStringWidth(data) / getScalingFactor();
+		return fallbackFont->getStringWidth(data);
 
 	int width;
 	TTF_SizeUTF8(font.get(), data.c_str(), &width, nullptr);

+ 9 - 0
config/bonuses.json

@@ -600,6 +600,15 @@
 			"icon":  "zvs/Lib1.res/DISINTEGRATE"
 		}
 
+	},
+
+	"INVINCIBLE":
+	{
+		"graphics":
+		{
+			"icon":  "zvs/Lib1.res/INVINCIBLE"
+		}
+
 	}
 }
 

+ 4 - 0
config/creatures/castle.json

@@ -10,6 +10,10 @@
 			"cavalryChargeImmunity" :
 			{
 				"type" : "CHARGE_IMMUNITY"
+			},
+			"invincible" :
+			{
+				"type" : "INVINCIBLE"
 			}
 		},
 		"graphics" :

+ 2 - 11
config/gameConfig.json

@@ -273,17 +273,8 @@
 				}
 			},
 			"chronicles" : { 
-				"supported" : true,
-				"iconIndex" : 2,
-				
-				"portraits" : {
-					"portraitTarnumBarbarian" : 163,
-					"portraitTarnumKnight" : 164,
-					"portraitTarnumWizard" : 165,
-					"portraitTarnumRanger" : 166,
-					"portraitTarnumOverlord" : 167,
-					"portraitTarnumBeastmaster" : 168
-				}
+				"supported" : false,
+				"iconIndex" : 2
 			},
 			"jsonVCMI" : { 
 				"supported" : true,

+ 1 - 175
config/heroes/portraits.json

@@ -202,179 +202,5 @@
 		],
 		"skills" : [],
 		"specialty" : {}
-	},
-	"portraitTarnumBarbarian" :
-	{
-		"class" : "barbarian",
-		"special" : true,
-		"images": {
-			"large" : "HPL137",
-			"small" : "HPS137",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "goblin",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
-	},
-	"portraitTarnumKnight" :
-	{
-		"class" : "knight",
-		"special" : true,
-		"images": {
-			"large" : "HPL138",
-			"small" : "HPS138",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "pikeman",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
-	},
-	"portraitTarnumWizard" :
-	{
-		"class" : "wizard",
-		"special" : true,
-		"images": {
-			"large" : "HPL139",
-			"small" : "HPS139",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "enchanter",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
-	},
-	"portraitTarnumRanger" :
-	{
-		"class" : "ranger",
-		"special" : true,
-		"images": {
-			"large" : "HPL140",
-			"small" : "HPS140",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "sharpshooter",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
-	},
-	"portraitTarnumOverlord" :
-	{
-		"class" : "overlord",
-		"special" : true,
-		"images": {
-			"large" : "HPL141",
-			"small" : "HPS141",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "troglodyte",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
-	},
-	"portraitTarnumBeastmaster" :
-	{
-		"class" : "beastmaster",
-		"special" : true,
-		"images": {
-			"large" : "HPL142",
-			"small" : "HPS142",
-			"specialtySmall" : "default",
-			"specialtyLarge" : "default"
-		},
-		"texts" : {
-			"name" : "",
-			"biography" : "",
-			"specialty" : {
-				"description" : "",
-				"tooltip" : "",
-				"name" : ""
-			}
-		},
-		"army" : [
-			{
-				"creature" : "gnoll",
-				"min" : 1,
-				"max" : 1
-			}
-		],
-		"skills" : [],
-		"specialty" : {}
 	}
-}
+}

+ 176 - 0
config/heroes/portraitsChronicles.json

@@ -0,0 +1,176 @@
+{
+	"portraitTarnumBarbarian" : // 163
+	{
+		"class" : "barbarian",
+		"special" : true,
+		"images": {
+			"large" : "HPL137",
+			"small" : "HPS137",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "goblin",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	},
+	"portraitTarnumKnight" : // 164
+	{
+		"class" : "knight",
+		"special" : true,
+		"images": {
+			"large" : "HPL138",
+			"small" : "HPS138",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "pikeman",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	},
+	"portraitTarnumWizard" : // 165
+	{
+		"class" : "wizard",
+		"special" : true,
+		"images": {
+			"large" : "HPL139",
+			"small" : "HPS139",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "enchanter",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	},
+	"portraitTarnumRanger" : // 166
+	{
+		"class" : "ranger",
+		"special" : true,
+		"images": {
+			"large" : "HPL140",
+			"small" : "HPS140",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "sharpshooter",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	},
+	"portraitTarnumOverlord" : // 167
+	{
+		"class" : "overlord",
+		"special" : true,
+		"images": {
+			"large" : "HPL141",
+			"small" : "HPS141",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "troglodyte",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	},
+	"portraitTarnumBeastmaster" : // 168
+	{
+		"class" : "beastmaster",
+		"special" : true,
+		"images": {
+			"large" : "HPL142",
+			"small" : "HPS142",
+			"specialtySmall" : "default",
+			"specialtyLarge" : "default"
+		},
+		"texts" : {
+			"name" : "",
+			"biography" : "",
+			"specialty" : {
+				"description" : "",
+				"tooltip" : "",
+				"name" : ""
+			}
+		},
+		"army" : [
+			{
+				"creature" : "gnoll",
+				"min" : 1,
+				"max" : 1
+			}
+		],
+		"skills" : [],
+		"specialty" : {}
+	}
+}

+ 4 - 0
config/schemas/settings.json

@@ -367,6 +367,10 @@
 					"type" : "boolean",
 					"default" : false
 				},
+				"rightButtonDrag" : {
+					"type" : "boolean",
+					"default" : false
+				},
 				"smoothDragging" : {
 					"type" : "boolean",
 					"default" : true

+ 5 - 1
docs/modders/Bonus/Bonus_Types.md

@@ -1022,4 +1022,8 @@ Internal bonus, do not use
 
 ### DISINTEGRATE
 
-After death of unit no corpse remains
+When a unit affected by this bonus dies, no corpse is left behind
+
+### INVINCIBLE
+
+The unit affected by this bonus cannot be target of attacks or spells

+ 12 - 0
launcher/modManager/chroniclesextractor.cpp

@@ -106,6 +106,18 @@ void ChroniclesExtractor::createBaseMod() const
 		{ "author", "3DO" },
 		{ "version", "1.0" },
 		{ "contact", "vcmi.eu" },
+		{ "heroes", QJsonArray({"config/heroes/portraitsChronicles.json"}) },
+		{ "settings", QJsonObject({{"mapFormat", QJsonObject({{"chronicles", QJsonObject({{
+			{"supported", true},
+			{"portraits", QJsonObject({
+				{"portraitTarnumBarbarian", 163},
+				{"portraitTarnumKnight", 164},
+				{"portraitTarnumWizard", 165},
+				{"portraitTarnumRanger", 166},
+				{"portraitTarnumOverlord", 167},
+				{"portraitTarnumBeastmaster", 168},
+			})},
+		}})}})}})},
 	};
 
 	QFile jsonFile(dir.filePath("mod.json"));

+ 6 - 0
launcher/modManager/cmodlistview_moc.cpp

@@ -1080,6 +1080,12 @@ bool CModListView::isModEnabled(const QString & modName)
 	return mod.isEnabled();
 }
 
+bool CModListView::isModInstalled(const QString & modName)
+{
+	auto mod = modModel->getMod(modName);
+	return mod.isInstalled();
+}
+
 QString CModListView::getTranslationModName(const QString & language)
 {
 	for(const auto & modName : modModel->getModList())

+ 3 - 0
launcher/modManager/cmodlistview_moc.h

@@ -95,6 +95,9 @@ public:
 	/// returns true if mod is currently enabled
 	bool isModEnabled(const QString & modName);
 
+	/// returns true if mod is currently installed
+	bool isModInstalled(const QString & modName);
+
 public slots:
 	void enableModByName(QString modName);
 	void disableModByName(QString modName);

+ 37 - 5
launcher/settingsView/csettingsview_moc.cpp

@@ -54,6 +54,14 @@ static constexpr std::array downscalingFilterTypes =
 	"best"
 };
 
+MainWindow * CSettingsView::getMainWindow()
+{
+	foreach(QWidget *w, qApp->allWidgets())
+		if(QMainWindow* mainWin = qobject_cast<QMainWindow*>(w))
+			return dynamic_cast<MainWindow *>(mainWin);
+	return nullptr;
+}
+
 void CSettingsView::setDisplayList()
 {
 	QStringList list;
@@ -166,6 +174,17 @@ void CSettingsView::loadSettings()
 	ui->sliderControllerSticksAcceleration->setValue(settings["input"]["controllerAxisScale"].Float() * 100);
 	ui->lineEditGameLobbyHost->setText(QString::fromStdString(settings["lobby"]["hostname"].String()));
 	ui->spinBoxNetworkPortLobby->setValue(settings["lobby"]["port"].Integer());
+	
+	auto mainWindow = getMainWindow();
+	if(mainWindow)
+	{
+		bool fontModAvailable = mainWindow->getModView()->isModInstalled("vcmi-extras.truetypefonts");
+		if(!fontModAvailable)
+		{
+			ui->labelTtfFont->hide();
+			ui->buttonTtfFont->hide();
+		}
+	}
 
 	loadToggleButtonSettings();
 }
@@ -190,6 +209,10 @@ void CSettingsView::loadToggleButtonSettings()
 	std::string cursorType = settings["video"]["cursor"].String();
 	int cursorTypeIndex = vstd::find_pos(cursorTypesList, cursorType);
 	setCheckbuttonState(ui->buttonCursorType, cursorTypeIndex);
+
+	auto mainWindow = getMainWindow();
+	if(mainWindow)
+		setCheckbuttonState(ui->buttonTtfFont, mainWindow->getModView()->isModEnabled("vcmi-extras.truetypefonts"));
 }
 
 void CSettingsView::fillValidResolutions()
@@ -442,8 +465,7 @@ void CSettingsView::on_comboBoxLanguage_currentIndexChanged(int index)
 	QString selectedLanguage = ui->comboBoxLanguage->itemData(index).toString();
 	node->String() = selectedLanguage.toStdString();
 
-	if(auto * mainWindow = dynamic_cast<MainWindow *>(qApp->activeWindow()))
-		mainWindow->updateTranslation();
+	getMainWindow()->updateTranslation();
 }
 
 void CSettingsView::changeEvent(QEvent *event)
@@ -475,7 +497,7 @@ void CSettingsView::loadTranslation()
 {
 	QString baseLanguage = Languages::getHeroesDataLanguage();
 
-	auto * mainWindow = dynamic_cast<MainWindow *>(qApp->activeWindow());
+	auto * mainWindow = getMainWindow();
 
 	if (!mainWindow)
 		return;
@@ -518,7 +540,7 @@ void CSettingsView::loadTranslation()
 
 void CSettingsView::on_pushButtonTranslation_clicked()
 {
-	auto * mainWindow = dynamic_cast<MainWindow *>(qApp->activeWindow());
+	auto * mainWindow = getMainWindow();
 
 	assert(mainWindow);
 	if (!mainWindow)
@@ -582,7 +604,7 @@ void CSettingsView::on_spinBoxInterfaceScaling_valueChanged(int arg1)
 
 void CSettingsView::on_refreshRepositoriesButton_clicked()
 {
-	auto * mainWindow = dynamic_cast<MainWindow *>(qApp->activeWindow());
+	auto * mainWindow = getMainWindow();
 
 	assert(mainWindow);
 	if (!mainWindow)
@@ -747,3 +769,13 @@ void CSettingsView::on_sliderControllerSticksSensitivity_valueChanged(int value)
 	Settings node = settings.write["input"]["controllerAxisSpeed"];
 	node->Integer() = value;
 }
+
+void CSettingsView::on_buttonTtfFont_toggled(bool value)
+{
+	auto mainWindow = getMainWindow();
+	if(value)
+		mainWindow->getModView()->enableModByName("vcmi-extras.truetypefonts");
+	else
+		mainWindow->getModView()->disableModByName("vcmi-extras.truetypefonts");
+	updateCheckbuttonText(ui->buttonTtfFont);
+}

+ 6 - 0
launcher/settingsView/csettingsview_moc.h

@@ -14,10 +14,14 @@ namespace Ui
 class CSettingsView;
 }
 
+class MainWindow;
+
 class CSettingsView : public QWidget
 {
 	Q_OBJECT
 
+	MainWindow * getMainWindow();
+
 public:
 	explicit CSettingsView(QWidget * parent = nullptr);
 	~CSettingsView();
@@ -84,6 +88,8 @@ private slots:
 
 	void on_sliderControllerSticksSensitivity_valueChanged(int value);
 
+	void on_buttonTtfFont_toggled(bool value);
+
 private:
 	Ui::CSettingsView * ui;
 

+ 78 - 55
launcher/settingsView/csettingsview_moc.ui

@@ -68,7 +68,7 @@
          </property>
         </widget>
        </item>
-       <item row="46" column="1" colspan="4">
+       <item row="47" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxEnemyAI">
          <property name="editable">
           <bool>false</bool>
@@ -88,14 +88,14 @@
          </item>
         </widget>
        </item>
-       <item row="39" column="0">
+       <item row="40" column="0">
         <widget class="QLabel" name="labelControllerSticksAcceleration">
          <property name="text">
           <string>Sticks Acceleration</string>
          </property>
         </widget>
        </item>
-       <item row="49" column="2" colspan="3">
+       <item row="50" column="2" colspan="3">
         <widget class="QPushButton" name="refreshRepositoriesButton">
          <property name="text">
           <string>Refresh now</string>
@@ -132,14 +132,14 @@
          </property>
         </widget>
        </item>
-       <item row="52" column="0">
+       <item row="53" column="0">
         <widget class="QLabel" name="labelGameLobbyHost">
          <property name="text">
           <string>Online Lobby address</string>
          </property>
         </widget>
        </item>
-       <item row="43" column="1" colspan="4">
+       <item row="44" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxAlliedPlayerAI">
          <property name="currentText">
           <string notr="true">VCAI</string>
@@ -172,7 +172,7 @@
          </property>
         </widget>
        </item>
-       <item row="25" column="1" colspan="4">
+       <item row="26" column="1" colspan="4">
         <widget class="QSlider" name="sliderMusicVolume">
          <property name="maximum">
           <number>100</number>
@@ -243,7 +243,7 @@
          </property>
         </widget>
        </item>
-       <item row="50" column="0">
+       <item row="51" column="0">
         <widget class="QLabel" name="labelRepositoryDefault">
          <property name="text">
           <string>Default repository</string>
@@ -270,7 +270,7 @@
          </property>
         </widget>
        </item>
-       <item row="32" column="1" colspan="4">
+       <item row="33" column="1" colspan="4">
         <widget class="QSlider" name="sliderRelativeCursorSpeed">
          <property name="minimum">
           <number>100</number>
@@ -296,7 +296,7 @@
          </property>
         </widget>
        </item>
-       <item row="41" column="0">
+       <item row="42" column="0">
         <widget class="QLabel" name="labelArtificialIntelligence">
          <property name="font">
           <font>
@@ -311,7 +311,7 @@
          </property>
         </widget>
        </item>
-       <item row="31" column="0">
+       <item row="32" column="0">
         <widget class="QLabel" name="labelRelativeCursorMode">
          <property name="text">
           <string>Use Relative Pointer Mode</string>
@@ -325,7 +325,7 @@
          </property>
         </widget>
        </item>
-       <item row="45" column="0">
+       <item row="46" column="0">
         <widget class="QLabel" name="labelFriendlyAI">
          <property name="text">
           <string>Autocombat AI in battles</string>
@@ -339,35 +339,35 @@
          </property>
         </widget>
        </item>
-       <item row="34" column="0">
+       <item row="35" column="0">
         <widget class="QLabel" name="labelLongTouchDuration">
          <property name="text">
           <string>Long Touch Duration</string>
          </property>
         </widget>
        </item>
-       <item row="38" column="0">
+       <item row="39" column="0">
         <widget class="QLabel" name="labelControllerSticksSensitivity">
          <property name="text">
           <string>Sticks Sensitivity</string>
          </property>
         </widget>
        </item>
-       <item row="36" column="0">
+       <item row="37" column="0">
         <widget class="QLabel" name="labelToleranceDistanceTouch">
          <property name="text">
           <string>Touch Tap Tolerance</string>
          </property>
         </widget>
        </item>
-       <item row="51" column="2" colspan="3">
+       <item row="52" column="2" colspan="3">
         <widget class="QLineEdit" name="lineEditRepositoryExtra">
          <property name="text">
           <string notr="true"/>
          </property>
         </widget>
        </item>
-       <item row="26" column="1" colspan="4">
+       <item row="27" column="1" colspan="4">
         <widget class="QSlider" name="sliderSoundVolume">
          <property name="maximum">
           <number>100</number>
@@ -414,7 +414,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </item>
         </widget>
        </item>
-       <item row="50" column="1">
+       <item row="51" column="1">
         <widget class="QToolButton" name="buttonRepositoryDefault">
          <property name="enabled">
           <bool>true</bool>
@@ -436,7 +436,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="50" column="2" colspan="3">
+       <item row="51" column="2" colspan="3">
         <widget class="QLineEdit" name="lineEditRepositoryDefault">
          <property name="text">
           <string notr="true"/>
@@ -456,7 +456,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
        <item row="19" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxDisplayIndex"/>
        </item>
-       <item row="36" column="1" colspan="4">
+       <item row="37" column="1" colspan="4">
         <widget class="QSlider" name="sliderToleranceDistanceTouch">
          <property name="minimum">
           <number>0</number>
@@ -484,7 +484,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="53" column="0">
+       <item row="54" column="0">
         <widget class="QLabel" name="labelNetworkPortLobby">
          <property name="text">
           <string>Online Lobby port</string>
@@ -525,7 +525,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="24" column="0">
+       <item row="25" column="0">
         <widget class="QLabel" name="labelAudio">
          <property name="font">
           <font>
@@ -540,7 +540,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="51" column="1">
+       <item row="52" column="1">
         <widget class="QToolButton" name="buttonRepositoryExtra">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -559,7 +559,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="38" column="1" colspan="4">
+       <item row="39" column="1" colspan="4">
         <widget class="QSlider" name="sliderControllerSticksSensitivity">
          <property name="minimum">
           <number>500</number>
@@ -620,7 +620,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </item>
         </widget>
        </item>
-       <item row="45" column="1" colspan="4">
+       <item row="46" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxFriendlyAI">
          <property name="editable">
           <bool>false</bool>
@@ -640,14 +640,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </item>
         </widget>
        </item>
-       <item row="49" column="0">
+       <item row="50" column="0">
         <widget class="QLabel" name="labelAutoCheck">
          <property name="text">
           <string>Check on startup</string>
          </property>
         </widget>
        </item>
-       <item row="28" column="1" colspan="4">
+       <item row="29" column="1" colspan="4">
         <widget class="QSlider" name="slideToleranceDistanceMouse">
          <property name="minimum">
           <number>0</number>
@@ -691,7 +691,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="34" column="1" colspan="4">
+       <item row="35" column="1" colspan="4">
         <widget class="QSlider" name="sliderLongTouchDuration">
          <property name="minimum">
           <number>500</number>
@@ -719,7 +719,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
        <item row="1" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxLanguage"/>
        </item>
-       <item row="53" column="1" colspan="4">
+       <item row="54" column="1" colspan="4">
         <widget class="QSpinBox" name="spinBoxNetworkPortLobby">
          <property name="minimum">
           <number>1024</number>
@@ -732,14 +732,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="46" column="0">
+       <item row="47" column="0">
         <widget class="QLabel" name="labelEnemyAI">
          <property name="text">
           <string>Enemy AI in battles</string>
          </property>
         </widget>
        </item>
-       <item row="29" column="0">
+       <item row="30" column="0">
         <widget class="QLabel" name="labelInputMouse_2">
          <property name="font">
           <font>
@@ -761,7 +761,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="48" column="0">
+       <item row="49" column="0">
         <widget class="QLabel" name="labelIgnoreSslErrors">
          <property name="text">
           <string>Ignore SSL errors</string>
@@ -778,7 +778,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="52" column="1" colspan="4">
+       <item row="53" column="1" colspan="4">
         <widget class="QLineEdit" name="lineEditGameLobbyHost">
          <property name="text">
           <string notr="true"/>
@@ -792,14 +792,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="33" column="0">
+       <item row="34" column="0">
         <widget class="QLabel" name="labelHapticFeedback">
          <property name="text">
           <string>Haptic Feedback</string>
          </property>
         </widget>
        </item>
-       <item row="33" column="1" colspan="4">
+       <item row="34" column="1" colspan="4">
         <widget class="QToolButton" name="buttonHapticFeedback">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -815,14 +815,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="51" column="0">
+       <item row="52" column="0">
         <widget class="QLabel" name="labelRepositoryExtra">
          <property name="text">
           <string>Additional repository</string>
          </property>
         </widget>
        </item>
-       <item row="28" column="0">
+       <item row="29" column="0">
         <widget class="QLabel" name="labelToleranceDistanceMouse">
          <property name="text">
           <string>Mouse Click Tolerance</string>
@@ -836,14 +836,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="32" column="0">
+       <item row="33" column="0">
         <widget class="QLabel" name="labelRelativeCursorSpeed">
          <property name="text">
           <string>Relative Pointer Speed</string>
          </property>
         </widget>
        </item>
-       <item row="47" column="0">
+       <item row="48" column="0">
         <widget class="QLabel" name="labelNetwork">
          <property name="font">
           <font>
@@ -865,7 +865,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="48" column="1" colspan="4">
+       <item row="49" column="1" colspan="4">
         <widget class="QToolButton" name="buttonIgnoreSslErrors">
          <property name="enabled">
           <bool>true</bool>
@@ -894,14 +894,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="42" column="0">
+       <item row="43" column="0">
         <widget class="QLabel" name="labelEnemyPlayerAI">
          <property name="text">
           <string>Adventure Map Enemies</string>
          </property>
         </widget>
        </item>
-       <item row="44" column="1" colspan="4">
+       <item row="45" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxNeutralAI">
          <property name="currentText">
           <string notr="true">BattleAI</string>
@@ -918,21 +918,21 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </item>
         </widget>
        </item>
-       <item row="44" column="0">
+       <item row="45" column="0">
         <widget class="QLabel" name="labelNeutralAI">
          <property name="text">
           <string>Neutral AI in battles</string>
          </property>
         </widget>
        </item>
-       <item row="43" column="0">
+       <item row="44" column="0">
         <widget class="QLabel" name="labelAlliedPlayerAI">
          <property name="text">
           <string>Adventure Map Allies</string>
          </property>
         </widget>
        </item>
-       <item row="27" column="0">
+       <item row="28" column="0">
         <widget class="QLabel" name="labelInputMouse">
          <property name="font">
           <font>
@@ -947,7 +947,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="49" column="1">
+       <item row="50" column="1">
         <widget class="QToolButton" name="buttonAutoCheck">
          <property name="enabled">
           <bool>true</bool>
@@ -985,7 +985,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="42" column="1" colspan="4">
+       <item row="43" column="1" colspan="4">
         <widget class="QComboBox" name="comboBoxEnemyPlayerAI">
          <property name="currentText">
           <string notr="true">VCAI</string>
@@ -1009,7 +1009,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="37" column="0">
+       <item row="38" column="0">
         <widget class="QLabel" name="labelInputMouse_3">
          <property name="font">
           <font>
@@ -1031,14 +1031,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="40" column="0">
+       <item row="41" column="0">
         <widget class="QLabel" name="labelToleranceDistanceController">
          <property name="text">
           <string>Controller Click Tolerance</string>
          </property>
         </widget>
        </item>
-       <item row="39" column="1" colspan="4">
+       <item row="40" column="1" colspan="4">
         <widget class="QSlider" name="sliderControllerSticksAcceleration">
          <property name="minimum">
           <number>100</number>
@@ -1080,14 +1080,14 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="26" column="0">
+       <item row="27" column="0">
         <widget class="QLabel" name="labelSoundVolume">
          <property name="text">
           <string>Sound Volume</string>
          </property>
         </widget>
        </item>
-       <item row="40" column="1" colspan="4">
+       <item row="41" column="1" colspan="4">
         <widget class="QSlider" name="sliderToleranceDistanceController">
          <property name="minimum">
           <number>0</number>
@@ -1115,7 +1115,7 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="31" column="1" colspan="4">
+       <item row="32" column="1" colspan="4">
         <widget class="QToolButton" name="buttonRelativeCursorMode">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
@@ -1131,21 +1131,21 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </property>
         </widget>
        </item>
-       <item row="25" column="0">
+       <item row="26" column="0">
         <widget class="QLabel" name="labelMusicVolume">
          <property name="text">
           <string>Music Volume</string>
          </property>
         </widget>
        </item>
-       <item row="30" column="0">
+       <item row="31" column="0">
         <widget class="QLabel" name="labelResetTutorialTouchscreen">
          <property name="text">
           <string>Show Tutorial again</string>
          </property>
         </widget>
        </item>
-       <item row="30" column="1" colspan="4">
+       <item row="31" column="1" colspan="4">
         <widget class="QPushButton" name="pushButtonResetTutorialTouchscreen">
          <property name="text">
           <string>Reset</string>
@@ -1188,6 +1188,29 @@ Fullscreen Exclusive Mode - game will cover entirety of your screen and will use
          </item>
         </widget>
        </item>
+       <item row="24" column="0">
+        <widget class="QLabel" name="labelTtfFont">
+         <property name="text">
+          <string>Use scalable fonts</string>
+         </property>
+        </widget>
+       </item>
+       <item row="24" column="1" colspan="4">
+        <widget class="QToolButton" name="buttonTtfFont">
+         <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>
       </layout>
      </widget>
     </widget>

+ 113 - 115
launcher/translation/swedish.ts

@@ -11,7 +11,7 @@
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="29"/>
         <source>Have a question? Found a bug? Want to help? Join us!</source>
-        <translation type="unfinished">Har du något som är svår att förstå? Har du hittat ett fel eller ett annat problem? Behöver du hjälp? Förena oss i samma grupp!</translation>
+        <translation type="unfinished">Har du en fråga? Hittat en bugg? Vill du hjälpa till? Anslut dig till oss!</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="36"/>
@@ -31,7 +31,7 @@
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="182"/>
         <source>User data directory</source>
-        <translation type="unfinished">Användardatamapp</translation>
+        <translation type="unfinished">Användardata-mapp</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="88"/>
@@ -54,17 +54,17 @@
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="114"/>
         <source>Log files directory</source>
-        <translation type="unfinished">Loggmapp</translation>
+        <translation type="unfinished">Loggfils-mapp</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="107"/>
         <source>Data Directories</source>
-        <translation type="unfinished">Datafil</translation>
+        <translation type="unfinished">Datafilsregister</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="168"/>
         <source>Game data directory</source>
-        <translation type="unfinished">Speldatamapp</translation>
+        <translation type="unfinished">Speldata-mapp</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="175"/>
@@ -74,7 +74,7 @@
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="227"/>
         <source>Configuration files directory</source>
-        <translation type="unfinished">Mapp för konfigurationsfiler</translation>
+        <translation type="unfinished">Konfigurationsfils-mapp</translation>
     </message>
     <message>
         <location filename="../aboutProject/aboutproject_moc.ui" line="290"/>
@@ -171,7 +171,7 @@
     <message>
         <location filename="../modManager/cmodlistmodel_moc.cpp" line="60"/>
         <source>Expansion</source>
-        <translation type="unfinished">Tillägg</translation>
+        <translation type="unfinished">Expansion/Tillägg</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistmodel_moc.cpp" line="61"/>
@@ -204,7 +204,7 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="66"/>
         <source>All mods</source>
-        <translation type="unfinished">Alla mods</translation>
+        <translation type="unfinished">Alla moddar</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="71"/>
@@ -234,7 +234,7 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="105"/>
         <source>Reload repositories</source>
-        <translation type="unfinished">Ladda om mappar</translation>
+        <translation type="unfinished">Ladda om repositorier</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="163"/>
@@ -245,12 +245,12 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="209"/>
         <source>Changelog</source>
-        <translation type="unfinished">Dagbok</translation>
+        <translation type="unfinished">Förändringshistorik</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="231"/>
         <source>Screenshots</source>
-        <translation type="unfinished">Skärmutskrifter</translation>
+        <translation type="unfinished">Skärmbilder</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.ui" line="327"/>
@@ -295,7 +295,7 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="285"/>
         <source>Mod name</source>
-        <translation type="unfinished">Modnamn</translation>
+        <translation type="unfinished">Modd-namn</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="286"/>
@@ -341,23 +341,23 @@
         <location filename="../modManager/cmodlistview_moc.cpp" line="311"/>
         <location filename="../modManager/cmodlistview_moc.cpp" line="319"/>
         <source>Required VCMI version</source>
-        <translation type="unfinished">Obligatorisk version av VCMI</translation>
+        <translation type="unfinished">VCMI-version som krävs</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="317"/>
         <source>Supported VCMI version</source>
-        <translation type="unfinished">Version av VCMI som stöds</translation>
+        <translation type="unfinished">Stödd VCMI-version</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="317"/>
-        <source>please upgrade mod</source>
-        <translation type="unfinished">vänligen uppdatera mod</translation>
+        <source>Please upgrade mod</source>
+        <translation type="unfinished">Vänligen uppdatera modd</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="189"/>
         <location filename="../modManager/cmodlistview_moc.cpp" line="809"/>
         <source>mods repository index</source>
-        <translation type="unfinished">Mod Repository Index</translation>
+        <translation type="unfinished">Modd-repositorie index</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="319"/>
@@ -367,7 +367,7 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="322"/>
         <source>Supported VCMI versions</source>
-        <translation type="unfinished">Versionerna av VCMI som stöds</translation>
+        <translation type="unfinished">VCMI-versioner som stöds</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="346"/>
@@ -377,37 +377,37 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="348"/>
         <source>Required mods</source>
-        <translation type="unfinished">Obligatoriska mods</translation>
+        <translation type="unfinished">Moddar som krävs</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="349"/>
         <source>Conflicting mods</source>
-        <translation type="unfinished">Modskonflikt</translation>
+        <translation type="unfinished">Modd-konflikter</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="354"/>
         <source>This mod can not be installed or enabled because the following dependencies are not present</source>
-        <translation type="unfinished">Denna mod kan inte installeras eller aktiveras eftersom följande beroenden inte finns</translation>
+        <translation type="unfinished">Denna modd kan inte installeras eller aktiveras eftersom följande beroenden inte finns</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="355"/>
         <source>This mod can not be enabled because the following mods are incompatible with it</source>
-        <translation type="unfinished">Denna mod kan inte installeras eller aktiveras eftersom följande beroenden är inkompatibla med den</translation>
+        <translation type="unfinished">Denna modd kan inte aktiveras eftersom följande beroenden är inkompatibla med den</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="356"/>
         <source>This mod cannot be disabled because it is required by the following mods</source>
-        <translation type="unfinished">Denna mod kan inte inaktiveras eftersom den krävs för följande beroenden</translation>
+        <translation type="unfinished">Denna modd kan inte inaktiveras eftersom den krävs för följande beroenden</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="357"/>
         <source>This mod cannot be uninstalled or updated because it is required by the following mods</source>
-        <translation type="unfinished">Denna mod kan inte avinstalleras eller uppdateras eftersom den krävs för följande beroenden</translation>
+        <translation type="unfinished">Denna modd kan inte avinstalleras eller uppdateras eftersom den krävs för följande beroenden</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="358"/>
         <source>This is a submod and it cannot be installed or uninstalled separately from its parent mod</source>
-        <translation type="unfinished">Denna undermod kan inte installeras eller uppdateras separat från modermoden</translation>
+        <translation type="unfinished">Denna undermodd/submodd kan inte installeras eller uppdateras separat från huvud-modden</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="373"/>
@@ -437,17 +437,17 @@
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="639"/>
         <source>Mods</source>
-        <translation type="unfinished">Mods</translation>
+        <translation type="unfinished">Moddar</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="640"/>
         <source>Select files (configs, mods, maps, campaigns) to install...</source>
-        <translation type="unfinished">Välj filer att installera (konfigurationer, mods, kartor, kampanjer)...</translation>
+        <translation type="unfinished">Välj filer att installera (konfigurationer, moddar, kartor, kampanjer)...</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="665"/>
         <source>Replace config file?</source>
-        <translation type="unfinished">Byta ut konfigurationsfilen?</translation>
+        <translation type="unfinished">Byt ut konfigurationsfilen?</translation>
     </message>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="665"/>
@@ -500,7 +500,7 @@ Installera lyckade nedladdningar?</translation>
         <location filename="../modManager/cmodlistview_moc.cpp" line="951"/>
         <source>Encountered errors:
 </source>
-        <translation type="unfinished">Fel påträffade:
+        <translation type="unfinished">Fel påträffades:
 </translation>
     </message>
     <message>
@@ -516,7 +516,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../modManager/cmodlistview_moc.cpp" line="280"/>
         <source>Mod is incompatible</source>
-        <translation type="unfinished">Denna mod är inkompatibel</translation>
+        <translation type="unfinished">Denna modd är inkompatibel</translation>
     </message>
 </context>
 <context>
@@ -524,95 +524,95 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="168"/>
         <source>Can not install submod</source>
-        <translation type="unfinished">Det går inte att installera undermod</translation>
+        <translation type="unfinished">Det går inte att installera undermodd/submodd</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="171"/>
         <source>Mod is already installed</source>
-        <translation type="unfinished">Mod är redan installerad</translation>
+        <translation type="unfinished">Modden är redan installerad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="180"/>
         <source>Can not uninstall submod</source>
-        <translation type="unfinished">Det går inte att avinstallera submod</translation>
+        <translation type="unfinished">Det går inte att avinstallera undermodd/submodd</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="183"/>
         <source>Mod is not installed</source>
-        <translation type="unfinished">Mod är inte installerad</translation>
+        <translation type="unfinished">Modden är inte installerad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="193"/>
         <source>Mod is already enabled</source>
-        <translation type="unfinished">Mod redan aktiverad</translation>
+        <translation type="unfinished">Modden är redan aktiverad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="196"/>
         <location filename="../modManager/cmodmanager.cpp" line="239"/>
         <source>Mod must be installed first</source>
-        <translation type="unfinished">Läget måste installeras först</translation>
+        <translation type="unfinished">Modden måste installeras först</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="200"/>
         <source>Mod is not compatible, please update VCMI and checkout latest mod revisions</source>
-        <translation type="unfinished">Mod inte kompatibel, uppdatera VCMI och kontrollera den senaste versionen av moden</translation>
+        <translation type="unfinished">Modden är inte kompatibel. Vänligen uppdatera VCMI och kontrollera att du har den senaste versionen av modden</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="205"/>
         <source>Required mod %1 is missing</source>
-        <translation type="unfinished">Obligatorisk mod %1 saknas</translation>
+        <translation type="unfinished">Den obligatorisk modden %1 saknas</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="210"/>
         <source>Required mod %1 is not enabled</source>
-        <translation type="unfinished">Obligatorisk mod %1 är inte aktiverad</translation>
+        <translation type="unfinished">Den obligatorisk modden %1 är inte aktiverad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="219"/>
         <location filename="../modManager/cmodmanager.cpp" line="226"/>
         <source>This mod conflicts with %1</source>
-        <translation type="unfinished">Denna mod är i konflikt med %1</translation>
+        <translation type="unfinished">Denna modd är i konflikt med %1</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="236"/>
         <source>Mod is already disabled</source>
-        <translation type="unfinished">Mod redan inaktiverad</translation>
+        <translation type="unfinished">Modden är redan inaktiverad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="246"/>
         <source>This mod is needed to run %1</source>
-        <translation type="unfinished">Modden krävs för att köra %1</translation>
+        <translation type="unfinished">Denna modden krävs för att köra %1</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="288"/>
         <source>Mod archive is missing</source>
-        <translation type="unfinished">Modarkiv saknas</translation>
+        <translation type="unfinished">Modd-arkiv saknas</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="291"/>
         <source>Mod with such name is already installed</source>
-        <translation type="unfinished">En mod med samma namn är redan installerad</translation>
+        <translation type="unfinished">En modd med samma namn är redan installerad</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="296"/>
         <source>Mod archive is invalid or corrupted</source>
-        <translation type="unfinished">Modarkivet är ogiltigt eller korrupt</translation>
+        <translation type="unfinished">Modd-arkivet är ogiltigt eller korrupt</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="322"/>
         <source>Failed to extract mod data</source>
-        <translation type="unfinished">Det gick inte att extrahera data från mod</translation>
+        <translation type="unfinished">Det gick inte att extrahera data från modd</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="350"/>
         <source>Data with this mod was not found</source>
-        <translation type="unfinished">Data för denna mod hittades inte</translation>
+        <translation type="unfinished">Modd-data för denna modd hittades inte</translation>
     </message>
     <message>
         <location filename="../modManager/cmodmanager.cpp" line="354"/>
         <source>Mod is located in protected directory, please remove it manually:
 </source>
-        <translation type="unfinished">Modden är placerad i en skyddad mapp, vänligen radera den manuellt:
+        <translation type="unfinished">Modden är placerad i en skyddad mapp. Vänligen radera den manuellt:
 </translation>
     </message>
 </context>
@@ -641,7 +641,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="249"/>
         <source>Default repository</source>
-        <translation type="unfinished">Standardförråd</translation>
+        <translation type="unfinished">Standard-repositorie</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="593"/>
@@ -651,17 +651,17 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="490"/>
         <source>Online Lobby port</source>
-        <translation type="unfinished">Port av väntrummet online</translation>
+        <translation type="unfinished">Port-numret till online-väntrummet</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="331"/>
         <source>Autocombat AI in battles</source>
-        <translation type="unfinished">Automatisk strids-AI i strider</translation>
+        <translation type="unfinished">Automatiska AI-strider</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="352"/>
         <source>Sticks Sensitivity</source>
-        <translation type="unfinished">Känslighet för sticks</translation>
+        <translation type="unfinished">Spak-känslighet</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="618"/>
@@ -671,12 +671,12 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="798"/>
         <source>Haptic Feedback</source>
-        <translation type="unfinished">Tryck på Tillbaka</translation>
+        <translation type="unfinished">Haptisk återkoppling (vibrationer i kontrollen)</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="835"/>
         <source>Software Cursor</source>
-        <translation type="unfinished">Programvarumarkör</translation>
+        <translation type="unfinished">Programvarumarkör (muspekare)</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1166"/>
@@ -686,7 +686,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1171"/>
         <source>None</source>
-        <translation type="unfinished">Ingen</translation>
+        <translation type="unfinished">Inget</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1176"/>
@@ -706,7 +706,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="138"/>
         <source>Online Lobby address</source>
-        <translation type="unfinished">Väntrumsadress online</translation>
+        <translation type="unfinished">Adressen till online-väntrummet</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1158"/>
@@ -716,7 +716,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="317"/>
         <source>Use Relative Pointer Mode</source>
-        <translation type="unfinished">Använda relativt pekarläge</translation>
+        <translation type="unfinished">Använd läge för relativ muspekare</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="608"/>
@@ -731,7 +731,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="750"/>
         <source>Input - Touchscreen</source>
-        <translation type="unfinished">Enter - Pekskärm</translation>
+        <translation type="unfinished">Ingång/indata - Pekskärm</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="854"/>
@@ -741,12 +741,12 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="893"/>
         <source>Downscaling Filter</source>
-        <translation type="unfinished">Skrympfilter</translation>
+        <translation type="unfinished">Nerskalnings-filter</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1144"/>
         <source>Show Tutorial again</source>
-        <translation type="unfinished">Titta om självstudien</translation>
+        <translation type="unfinished">Visa övningsgenomgången igen</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1151"/>
@@ -776,7 +776,7 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="943"/>
         <source>Input - Mouse</source>
-        <translation type="unfinished">Enter - Smile</translation>
+        <translation type="unfinished">Ingång/indata - Mus</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="345"/>
@@ -791,17 +791,17 @@ Installera lyckade nedladdningar?</translation>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1037"/>
         <source>Controller Click Tolerance</source>
-        <translation type="unfinished">Styrenhet Klicka på Tolerans</translation>
+        <translation type="unfinished">Tolerans för klick på styrenhet</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="359"/>
         <source>Touch Tap Tolerance</source>
-        <translation type="unfinished">Tanslagstolerans</translation>
+        <translation type="unfinished">Tolerans för pektryck</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1020"/>
         <source>Input - Controller</source>
-        <translation type="unfinished">Ingång - Styrenhet</translation>
+        <translation type="unfinished">Ingång/indata - Kontroll</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1086"/>
@@ -819,21 +819,21 @@ Borderless Windowed Mode - game will run in a window that covers entirely of you
 Fullscreen Exclusive Mode - game will cover entirety of your screen and will use selected resolution.</source>
         <translation type="unfinished">Välj visningsläge för spelet
 
-Windowed - spelet kommer att köras i ett fönster som täcker en del av din skärm
+Fönsterläge - spelet kommer att köras i ett fönster som täcker en viss del av din skärm (kan även täcka hela skärmen).
 
-Kantlöst fönsterläge - spelet körs i ett fönster som helt täcker din skärm, med samma upplösning som din skärm.
+Kantlöst fönsterläge - spelet körs i ett fönster som täcker hela din skärm och som använder samma upplösning som ditt operativsystem.
 
 Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda den valda upplösningen.</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="402"/>
         <source>Windowed</source>
-        <translation type="unfinished">Fönster</translation>
+        <translation type="unfinished">Fönsterläge</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="407"/>
         <source>Borderless fullscreen</source>
-        <translation type="unfinished">Fönster utan kant</translation>
+        <translation type="unfinished">Kantlöst fönsterläge</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="412"/>
@@ -848,27 +848,27 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="924"/>
         <source>Neutral AI in battles</source>
-        <translation type="unfinished">Neutral AI i strider</translation>
+        <translation type="unfinished">Neutralt AI i strider</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="777"/>
         <source>Autosave limit (0 = off)</source>
-        <translation type="unfinished">Gräns ​​för automatisk lagring (0 = inaktiverad)</translation>
+        <translation type="unfinished">Antal platser för automatisk-sparning (0 = inaktiverad)</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="900"/>
         <source>Adventure Map Enemies</source>
-        <translation type="unfinished">Äventyrskartfiender</translation>
+        <translation type="unfinished">Fiender på äventyskartan</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="760"/>
         <source>Autosave prefix</source>
-        <translation type="unfinished">Autospara prefix</translation>
+        <translation type="unfinished">Prefix för automatisk-sparning</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1008"/>
         <source>empty = map name prefix</source>
-        <translation type="unfinished">tomt = kortnamnsprefix</translation>
+        <translation type="unfinished">tomt = kartnamnsprefix</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="1072"/>
@@ -888,17 +888,17 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="269"/>
         <source>Heroes III Translation</source>
-        <translation type="unfinished">Heroes III översättning</translation>
+        <translation type="unfinished">Heroes III - Översättning</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="931"/>
         <source>Adventure Map Allies</source>
-        <translation type="unfinished">Adventure Map Allies</translation>
+        <translation type="unfinished">Allierade på äventyrskartan</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="821"/>
         <source>Additional repository</source>
-        <translation type="unfinished">Ytterligare insättning</translation>
+        <translation type="unfinished">Ytterligare repositorier</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="646"/>
@@ -913,7 +913,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="94"/>
         <source>Sticks Acceleration</source>
-        <translation type="unfinished">Personalacceleration</translation>
+        <translation type="unfinished">Styrspaks-acceleration</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="101"/>
@@ -943,7 +943,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="791"/>
         <source>Autosave</source>
-        <translation type="unfinished">Autospara</translation>
+        <translation type="unfinished">Auto-spara</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.ui" line="338"/>
@@ -978,12 +978,12 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../settingsView/csettingsview_moc.cpp" line="509"/>
         <source>Enable</source>
-        <translation type="unfinished">Aktiverad</translation>
+        <translation type="unfinished">Aktivera</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.cpp" line="514"/>
         <source>Not Installed</source>
-        <translation type="unfinished">Inte installerat</translation>
+        <translation type="unfinished">Inte installerad</translation>
     </message>
     <message>
         <location filename="../settingsView/csettingsview_moc.cpp" line="515"/>
@@ -1034,7 +1034,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="78"/>
         <source>Mods Preset</source>
-        <translation type="unfinished">Mod-förinställningar</translation>
+        <translation type="unfinished">Modd-förinställningar</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="126"/>
@@ -1044,7 +1044,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="169"/>
         <source>Have a question? Found a bug? Want to help? Join us!</source>
-        <translation type="unfinished">Har du en fråga? Hittade du en bugg? Behöver du hjälp? Gå med oss!</translation>
+        <translation type="unfinished">Har du en fråga? Hittat en bugg? Vill du hjälpa till? Anslut dig till oss!</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="248"/>
@@ -1054,12 +1054,12 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="297"/>
         <source>Use offline installer from gog.com</source>
-        <translation type="unfinished">Använd offlineinstallationsprogrammet från gog.com</translation>
+        <translation type="unfinished">Använd offline-installationsprogrammet från GOG.com</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="310"/>
         <source>You can manually copy directories Maps, Data and Mp3 from the original game directory to VCMI data directory that you can see on top of this page</source>
-        <translation type="unfinished">Du kan manuellt kopiera mappar Maps, Data och Mp3 från den ursprungliga spelmappen till VCMI-datamappen som du kan se överst på den här sidan</translation>
+        <translation type="unfinished">Du kan manuellt kopiera mapparna 'Maps', 'Data' och 'Mp3' från den ursprungliga spel-mappen till VCMI-datamappen som du kan se överst på den här sidan</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="329"/>
@@ -1074,7 +1074,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="388"/>
         <source>Installing... %p%</source>
-        <translation type="unfinished">Facilitet... %p%</translation>
+        <translation type="unfinished">Installerar... %p%</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="417"/>
@@ -1095,8 +1095,7 @@ Exklusivt helskärmsläge - spelet kommer att täcka hela skärmen och använda
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="504"/>
         <source>If you own Heroes III on gog.com you can download backup offline installer from gog.com, and VCMI will import Heroes III data using offline installer. 
 Offline installer consists of two parts, .exe and .bin. Make sure you download both of them.</source>
-        <translation type="unfinished">Om du äger Heroes III från gog.com kan du ladda ner backup offlineinstallationsprogrammet från gog.com, och VCMI kommer att importera Heroes III-data med offlineinstallationsprogrammet.
-Offlineinstallationsprogrammet består av två delar, .exe och .bin. Se till att ladda ner båda.</translation>
+        <translation type="unfinished">Om du äger Heroes III från GOG.com kan du ladda ner backup offline-installationsprogrammet från GOG.com - VCMI kommer att importera Heroes III-data med hjälp av offline-installationsprogrammet. Offline-installationsprogrammet består av två delar, en .exe och en .bin. Se till att ladda ner båda.</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="622"/>
@@ -1131,7 +1130,7 @@ Heroes® of Might and Magic® III HD is currently not supported!</source>
 
 Innan du kan börja spela finns det några steg kvar att slutföra.
 
-Tänk på att för att använda VCMI måste du ha originaldatafilerna för Heroes® of Might and Magic® III: Complete eller The Shadow of Death.
+Observera: för att använda VCMI måste du ha originaldatafilerna för Heroes® of Might and Magic® III: Complete eller The Shadow of Death.
 
 Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
     </message>
@@ -1160,52 +1159,52 @@ Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="557"/>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="860"/>
         <source>Back</source>
-        <translation type="unfinished">Retur</translation>
+        <translation type="unfinished">Tillbaka</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="594"/>
         <source>Install VCMI Mod Preset</source>
-        <translation type="unfinished">Installera VCMI Mod Preset</translation>
+        <translation type="unfinished">Installera VCMI Modd-förinställningar</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="710"/>
         <source>Horn of the Abyss</source>
-        <translation type="unfinished">Avgrundens horn</translation>
+        <translation type="unfinished">Avgrundens horn (Horn of the Abyss)</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="643"/>
         <source>Heroes III Translation</source>
-        <translation type="unfinished">Heroes III översättning</translation>
+        <translation type="unfinished">Heroes III - Översättning</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="742"/>
         <source>Interface Improvements</source>
-        <translation type="unfinished">Utvecklingsgränssnitt</translation>
+        <translation type="unfinished">Gränssnitts-förbättringar</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="809"/>
         <source>In The Wake of Gods</source>
-        <translation type="unfinished">In The Wake of Gods</translation>
+        <translation type="unfinished">I gudars kölvatten (In The Wake of Gods)</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="689"/>
         <source>Optionally, you can install additional mods either now, or at any point later, using the VCMI Launcher</source>
-        <translation type="unfinished">Valfritt kan du installera ytterligare mods antingen nu eller när som helst senare med hjälp av VCMI Launcher</translation>
+        <translation type="unfinished">Valfritt kan du installera ytterligare moddar antingen nu eller när som helst senare med hjälp av 'VCMI Launcher'</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="788"/>
         <source>Install mod that provides various interface improvements, such as better interface for random maps and selectable actions in battles</source>
-        <translation type="unfinished">Installera moden som ger olika gränssnittsförbättringar, såsom ett bättre gränssnitt för slumpmässiga kartor och valbara åtgärder i strider</translation>
+        <translation type="unfinished">Installera en modd som förbättrar olika användargränssnitt i spelet, såsom ett bättre användargränssnitt för slumpmässiga kartor och valbara åtgärder i strider</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="673"/>
         <source>Install compatible version of &quot;Horn of the Abyss&quot;, a fan-made Heroes III expansion ported by the VCMI team</source>
-        <translation type="unfinished">Installera en kompatibel version av &quot;Horn of the Abyss&quot;, en fantillverkad Heroes III-expansion som stöds av VCMI-teamet</translation>
+        <translation type="unfinished">Installera en kompatibel version av &quot;Horn of the Abyss&quot; (en fantillverkad Heroes III-expansion som blivit portad av VCMI-teamet)</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.ui" line="772"/>
         <source>Install compatible version of &quot;In The Wake of Gods&quot;, a fan-made Heroes III expansion</source>
-        <translation type="unfinished">Installera en kompatibel version av &quot;In The Wake of Gods&quot;, en fan-made Heroes III-expansion</translation>
+        <translation type="unfinished">Installera en kompatibel version av &quot;In The Wake of Gods&quot; (en fantillverkad Heroes III-expansion)</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="178"/>
@@ -1215,7 +1214,7 @@ Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="178"/>
         <source>Copy data to VCMI folder?</source>
-        <translation type="unfinished">Kopiera datamappen till VCMI-mappen?</translation>
+        <translation type="unfinished">Kopiera data till VCMI-mappen?</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="317"/>
@@ -1227,7 +1226,7 @@ Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="318"/>
         <source>You have to select %1 file!</source>
         <comment>param is file extension</comment>
-        <translation type="unfinished">Du har valt filen %1!</translation>
+        <translation type="unfinished">Du behöver välja filen %1!</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="320"/>
@@ -1241,13 +1240,13 @@ Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="330"/>
-        <source>File cannot opened</source>
+        <source>File cannot be opened</source>
         <translation type="unfinished">Filen kan inte öppnas</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="336"/>
         <source>Invalid file selected</source>
-        <translation type="unfinished">Ogiltig vald fil</translation>
+        <translation type="unfinished">Ogiltig fil vald</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="346"/>
@@ -1281,25 +1280,24 @@ Heroes® of Might and Magic® III HD stöds för närvarande inte!</translation>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="482"/>
         <source>Failed to detect valid Heroes III data in chosen directory.
 Please select directory with installed Heroes III data.</source>
-        <translation type="unfinished">Det går inte att upptäcka giltiga Heroes III-data i den valda katalogen,
-Välj en mapp där Heroes III-data finns.</translation>
+        <translation type="unfinished">Det går inte att upptäcka giltiga Heroes III-data i den valda katalogen. Välj en mapp där Heroes III-data finns.</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="387"/>
         <source>You&apos;ve provided GOG Galaxy installer! This file doesn&apos;t contain the game. Please download the offline backup game installer!</source>
-        <translation type="unfinished">Du har tillhandahållit installationsprogrammet för GOG Galaxy! Den här filen innehåller inte spelet. Ladda ner installationsprogrammet för spelet offline!</translation>
+        <translation type="unfinished">Du har tillhandahållit installationsprogrammet för GOG Galaxy! Den här filen innehåller inte spelet. Ladda ner offline-installationsprogrammet för spelet!</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="412"/>
         <source>Stream error while extracting files!
 error reason: </source>
-        <translation type="unfinished">Strömfel vid extrahering av filer!
+        <translation type="unfinished">Strömningsfel vid extrahering av filer!
 Orsak till fel: </translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="425"/>
         <source>Not a supported Inno Setup installer!</source>
-        <translation type="unfinished">Inno Setup-installationsprogram stöds inte!</translation>
+        <translation type="unfinished">Inno Setup-installationsprogrammet stöds inte!</translation>
     </message>
     <message>
         <location filename="../firstLaunch/firstlaunch_moc.cpp" line="436"/>
@@ -1318,7 +1316,7 @@ Välj en mapp som innehåller data från Heroes III: Complete Edition eller Hero
         <source>Unknown or unsupported Heroes III version found.
 Please select directory with Heroes III: Complete Edition or Heroes III: Shadow of Death.</source>
         <translation type="unfinished">Okänd eller ostödd version av Heroes III.
-Välj en mapp som innehåller data från Heroes III: Complete Edition eller Heroes III: Shadow of Death.</translation>
+Vänligen välj en mapp som innehåller data från Heroes III: Complete Edition eller Heroes III: Shadow of Death.</translation>
     </message>
 </context>
 <context>
@@ -1339,7 +1337,7 @@ Välj en mapp som innehåller data från Heroes III: Complete Edition eller Hero
     <message>
         <location filename="../languages.cpp" line="24"/>
         <source>Chinese</source>
-        <translation type="unfinished">kinesiska</translation>
+        <translation type="unfinished">Kinesiska</translation>
     </message>
     <message>
         <location filename="../languages.cpp" line="25"/>
@@ -1349,7 +1347,7 @@ Välj en mapp som innehåller data från Heroes III: Complete Edition eller Hero
     <message>
         <location filename="../languages.cpp" line="26"/>
         <source>Finnish</source>
-        <translation type="unfinished">finska</translation>
+        <translation type="unfinished">Finska</translation>
     </message>
     <message>
         <location filename="../languages.cpp" line="27"/>
@@ -1389,7 +1387,7 @@ Välj en mapp som innehåller data från Heroes III: Complete Edition eller Hero
     <message>
         <location filename="../languages.cpp" line="34"/>
         <source>Russian</source>
-        <translation type="unfinished">ryska</translation>
+        <translation type="unfinished">Ryska</translation>
     </message>
     <message>
         <location filename="../languages.cpp" line="35"/>
@@ -1432,12 +1430,12 @@ Välj en mapp som innehåller data från Heroes III: Complete Edition eller Hero
     <message>
         <location filename="../mainwindow_moc.ui" line="53"/>
         <source>Mods</source>
-        <translation type="unfinished">Mods</translation>
+        <translation type="unfinished">Moddar</translation>
     </message>
     <message>
         <location filename="../mainwindow_moc.ui" line="99"/>
         <source>Settings</source>
-        <translation type="unfinished">Parametrar</translation>
+        <translation type="unfinished">Inställningar</translation>
     </message>
     <message>
         <location filename="../mainwindow_moc.ui" line="145"/>
@@ -1498,7 +1496,7 @@ Orsak: %2</translation>
     <message>
         <location filename="../updatedialog_moc.ui" line="101"/>
         <source>Check for updates on startup</source>
-        <translation type="unfinished">Sök efter uppdateringar vid start</translation>
+        <translation type="unfinished">Sök efter uppdateringar vid uppstart</translation>
     </message>
     <message>
         <location filename="../updatedialog_moc.cpp" line="64"/>
@@ -1508,7 +1506,7 @@ Orsak: %2</translation>
     <message>
         <location filename="../updatedialog_moc.cpp" line="101"/>
         <source>Cannot read JSON from url or incorrect JSON data</source>
-        <translation type="unfinished">Det går inte att läsa JSON-data från URL eller fel JSON-data</translation>
+        <translation type="unfinished">Det går inte att läsa JSON-data från URL:en eller fel JSON-data</translation>
     </message>
 </context>
 </TS>

+ 3 - 0
lib/CStack.cpp

@@ -296,6 +296,9 @@ std::vector<BattleHex> CStack::meleeAttackHexes(const battle::Unit * attacker, c
 
 bool CStack::isMeleeAttackPossible(const battle::Unit * attacker, const battle::Unit * defender, BattleHex attackerPos, BattleHex defenderPos)
 {
+	if(defender->hasBonusOfType(BonusType::INVINCIBLE))
+		return false;
+		
 	return !meleeAttackHexes(attacker, defender, attackerPos, defenderPos).empty();
 }
 

+ 6 - 0
lib/battle/CBattleInfoCallback.cpp

@@ -685,6 +685,9 @@ bool CBattleInfoCallback::battleCanAttack(const battle::Unit * stack, const batt
 	if (!stack || !target)
 		return false;
 
+	if(target->hasBonusOfType(BonusType::INVINCIBLE))
+		return false;
+
 	if(!battleMatchOwner(stack, target))
 		return false;
 
@@ -730,6 +733,9 @@ bool CBattleInfoCallback::battleCanShoot(const battle::Unit * attacker, BattleHe
 	if(!attacker || !defender)
 		return false;
 
+	if(defender->hasBonusOfType(BonusType::INVINCIBLE))
+		return false;
+
 	if(battleMatchOwner(attacker, defender) && defender->alive())
 	{
 		if(battleCanShoot(attacker))

+ 1 - 0
lib/bonuses/BonusEnum.h

@@ -179,6 +179,7 @@ class JsonNode;
 	BONUS_NAME(RESOURCES_CONSTANT_BOOST) /*Bonus that does not account for propagation and gives extra resources per day. val - resource amount, subtype - resource type*/ \
 	BONUS_NAME(RESOURCES_TOWN_MULTIPLYING_BOOST) /*Bonus that does not account for propagation and gives extra resources per day with amount multiplied by number of owned towns. val - base resource amount to be multiplied times number of owned towns, subtype - resource type*/ \
 	BONUS_NAME(DISINTEGRATE) /* after death no corpse remains */ \
+	BONUS_NAME(INVINCIBLE) /* cannot be target of attacks or spells */ \
 	/* end of list */
 
 

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

@@ -719,7 +719,7 @@ std::shared_ptr<CFaction> CTownHandler::loadFromJson(const std::string & scope,
 	faction->identifier = identifier;
 
 	VLC->generaltexth->registerString(scope, faction->getNameTextID(), source["name"].String());
-	VLC->generaltexth->registerString(scope, faction->getDescriptionTranslated(), source["description"].String());
+	VLC->generaltexth->registerString(scope, faction->getDescriptionTextID(), source["description"].String());
 
 	faction->creatureBg120 = ImagePath::fromJson(source["creatureBackground"]["120px"]);
 	faction->creatureBg130 = ImagePath::fromJson(source["creatureBackground"]["130px"]);

+ 6 - 0
lib/mapObjects/CGCreature.cpp

@@ -22,6 +22,7 @@
 #include "../networkPacks/PacksForClientBattle.h"
 #include "../networkPacks/StackLocation.h"
 #include "../serializer/JsonSerializeFormat.h"
+#include "../entities/faction/CTownHandler.h"
 
 #include <vstd/RNG.h>
 
@@ -101,6 +102,11 @@ std::string CGCreature::getPopupText(const CGHeroInstance * hero) const
 
 	if (settings["general"]["enableUiEnhancements"].Bool())
 	{
+		std::string monsterLevel = VLC->generaltexth->translate("vcmi.adventureMap.monsterLevel");
+		boost::replace_first(monsterLevel, "%TOWN", (*VLC->townh)[VLC->creatures()->getById(getCreature())->getFaction()]->getNameTranslated());
+		boost::replace_first(monsterLevel, "%LEVEL", std::to_string(VLC->creatures()->getById(getCreature())->getLevel()));
+		hoverName += monsterLevel;
+
 		hoverName += VLC->generaltexth->translate("vcmi.adventureMap.monsterThreat.title");
 
 		int choice;

+ 4 - 1
lib/spells/BattleSpellMechanics.cpp

@@ -228,8 +228,11 @@ bool BattleSpellMechanics::canBeCastAt(const Target & target, Problem & problem)
 			mainTarget = battle()->battleGetUnitByPos(target.front().hexValue, true);
 		}
 
-		if (mainTarget && mainTarget == caster)
+		if(mainTarget && mainTarget == caster)
 			return false; // can't cast on self
+
+		if(mainTarget && mainTarget->hasBonusOfType(BonusType::INVINCIBLE))
+			return false;
 	}
 
 	return effects->applicable(problem, this, target, spellTarget);

+ 4 - 0
lib/spells/CSpellHandler.cpp

@@ -425,6 +425,10 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni
 			ret *= 100 + bearer->valOfBonuses(BonusType::MORE_DAMAGE_FROM_SPELL, BonusSubtypeID(id));
 			ret /= 100;
 		}
+
+		//invincible
+		if(bearer->hasBonusOfType(BonusType::INVINCIBLE))
+			ret = 0;
 	}
 	ret = caster->getSpellBonus(this, ret, affectedCreature);
 	return ret;

+ 19 - 17
server/CGameHandler.cpp

@@ -456,26 +456,28 @@ void CGameHandler::handleReceivedPack(CPackForServer * pack)
 	{
 		sendPackageResponse(false);
 	}
-
-	bool result;
-	try
-	{
-		ApplyGhNetPackVisitor applier(*this);
-		pack->visit(applier);
-		result = applier.getResult();
-	}
-	catch(ExceptionNotAllowedAction &)
+	else
 	{
-		result = false;
-	}
+		bool result;
+		try
+		{
+			ApplyGhNetPackVisitor applier(*this);
+			pack->visit(applier);
+			result = applier.getResult();
+		}
+		catch(ExceptionNotAllowedAction &)
+		{
+			result = false;
+		}
 
-	if(result)
-		logGlobal->trace("Message %s successfully applied!", typeid(*pack).name());
-	else
-		complain((boost::format("Got false in applying %s... that request must have been fishy!")
-			% typeid(*pack).name()).str());
+		if(result)
+			logGlobal->trace("Message %s successfully applied!", typeid(*pack).name());
+		else
+			complain((boost::format("Got false in applying %s... that request must have been fishy!")
+				% typeid(*pack).name()).str());
 
-	sendPackageResponse(true);
+		sendPackageResponse(true);
+	}
 	vstd::clear_pointer(pack);
 }