浏览代码

Fix potential compatibility with C++20 / C++23 mode

This fixes several issues with compatibility with C++20. C++23 was also
tested, but apparently it does not have any additional breaking changes
compared to C++20 (or we don't have those).

VCMI still uses C++17 as before - goal is only to make potential
transition easier.

There were 2 cases that are deprecated in C++20 that we use:
- Floating point operations on enums are deprecated
- `this` can no longer be captured when using default capture by value
`[=]`

Both of those should now be replaced with code that works fine in both C+
+17 and in C++20 mode
Ivan Savenko 7 月之前
父节点
当前提交
a8a6be7ac1

+ 14 - 14
AI/Nullkiller/AIGateway.cpp

@@ -163,7 +163,7 @@ void AIGateway::showTavernWindow(const CGObjectInstance * object, const CGHeroIn
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "TavernWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void AIGateway::showThievesGuildWindow(const CGObjectInstance * obj)
@@ -299,7 +299,7 @@ void AIGateway::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID her
 
 	status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->getNameTranslated() % firstHero->tempOwner % secondHero->getNameTranslated() % secondHero->tempOwner));
 
-	requestActionASAP([=]()
+	requestActionASAP([this, firstHero, secondHero, query]()
 	{
 		auto transferFrom2to1 = [this](const CGHeroInstance * h1, const CGHeroInstance * h2) -> void
 		{
@@ -338,7 +338,7 @@ void AIGateway::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedI
 
 	status.addQuery(queryID, "RecruitmentDialog");
 
-	requestActionASAP([=](){
+	requestActionASAP([this, dwelling, dst, queryID](){
 		recruitCreatures(dwelling, dst);
 		answerQuery(queryID, 0);
 	});
@@ -457,7 +457,7 @@ void AIGateway::showUniversityWindow(const IMarket * market, const CGHeroInstanc
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "UniversityWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void AIGateway::heroManaPointsChanged(const CGHeroInstance * hero)
@@ -533,7 +533,7 @@ void AIGateway::showMarketWindow(const IMarket * market, const CGHeroInstance *
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "MarketWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void AIGateway::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain)
@@ -589,7 +589,7 @@ void AIGateway::yourTurn(QueryID queryID)
 	NET_EVENT_HANDLER;
 	nullkiller->invalidatePathfinderData();
 	status.addQuery(queryID, "YourTurn");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 	status.startedTurn();
 	makingTurn = std::make_unique<boost::thread>(&AIGateway::makeTurn, this);
 }
@@ -602,7 +602,7 @@ void AIGateway::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, s
 	status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->getNameTranslated() % hero->level));
 	HeroPtr hPtr = hero;
 
-	requestActionASAP([=]()
+	requestActionASAP([this, hPtr, skills, queryID]()
 	{ 
 		int sel = 0;
 
@@ -624,7 +624,7 @@ void AIGateway::commanderGotLevel(const CCommanderInstance * commander, std::vec
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
 	status.addQuery(queryID, boost::str(boost::format("Commander %s of %s got level %d") % commander->name % commander->armyObj->nodeName() % (int)commander->level));
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void AIGateway::showBlockingDialog(const std::string & text, const std::vector<Component> & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept)
@@ -639,7 +639,7 @@ void AIGateway::showBlockingDialog(const std::string & text, const std::vector<C
 
 	if(!selection && cancel)
 	{
-		requestActionASAP([=]()
+		requestActionASAP([this, hero, target, askID]()
 		{
 			//yes&no -> always answer yes, we are a brave AI :)
 			bool answer = true;
@@ -687,7 +687,7 @@ void AIGateway::showBlockingDialog(const std::string & text, const std::vector<C
 		return;
 	}
 
-	requestActionASAP([=]()
+	requestActionASAP([this, selection, components, hero, askID]()
 	{
 		int sel = 0;
 
@@ -749,7 +749,7 @@ void AIGateway::showTeleportDialog(const CGHeroInstance * hero, TeleportChannelI
 		}
 	}
 
-	requestActionASAP([=]()
+	requestActionASAP([this, askID, chosenExit]()
 	{
 		answerQuery(askID, chosenExit);
 	});
@@ -766,7 +766,7 @@ void AIGateway::showGarrisonDialog(const CArmedInstance * up, const CGHeroInstan
 	status.addQuery(queryID, boost::str(boost::format("Garrison dialog with %s and %s") % s1 % s2));
 
 	//you can't request action from action-response thread
-	requestActionASAP([=]()
+	requestActionASAP([this, up, down, removableUnits, queryID]()
 	{
 		if(removableUnits && up->tempOwner == down->tempOwner && nullkiller->settings->isGarrisonTroopsUsageAllowed() && !cb->getStartInfo()->isRestorationOfErathiaCampaign())
 		{
@@ -781,7 +781,7 @@ void AIGateway::showMapObjectSelectDialog(QueryID askID, const Component & icon,
 {
 	NET_EVENT_HANDLER;
 	status.addQuery(askID, "Map object select query");
-	requestActionASAP([=](){ answerQuery(askID, selectedObject.getNum()); });
+	requestActionASAP([this, askID](){ answerQuery(askID, selectedObject.getNum()); });
 }
 
 bool AIGateway::makePossibleUpgrades(const CArmedInstance * obj)
@@ -1209,7 +1209,7 @@ void AIGateway::battleEnd(const BattleID & battleID, const BattleResult * br, Qu
 	{
 		status.addQuery(queryID, "Confirm battle query");
 
-		requestActionASAP([=]()
+		requestActionASAP([this, queryID]()
 			{
 				answerQuery(queryID, 0);
 			});

+ 9 - 5
AI/Nullkiller/Engine/FuzzyEngines.cpp

@@ -131,17 +131,21 @@ TacticalAdvantageEngine::TacticalAdvantageEngine()
 		castleWalls = new fl::InputVariable("CastleWalls");
 		engine.addInputVariable(castleWalls);
 		{
-			fl::Rectangle * none = new fl::Rectangle("NONE", CGTownInstance::NONE, CGTownInstance::NONE + (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f);
+			int wallsNone = CGTownInstance::NONE;
+			int wallsFort = CGTownInstance::FORT;
+			int wallsCitadel = CGTownInstance::CITADEL;
+			int wallsCastle = CGTownInstance::CASTLE;
+
+			fl::Rectangle * none = new fl::Rectangle("NONE", wallsNone, wallsNone + (wallsFort - wallsNone) * 0.5f);
 			castleWalls->addTerm(none);
 
-			fl::Trapezoid * medium = new fl::Trapezoid("MEDIUM", (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f, CGTownInstance::FORT,
-				CGTownInstance::CITADEL, CGTownInstance::CITADEL + (CGTownInstance::CASTLE - CGTownInstance::CITADEL) * 0.5f);
+			fl::Trapezoid * medium = new fl::Trapezoid("MEDIUM", (wallsFort - wallsNone) * 0.5f, wallsFort, wallsCitadel, wallsCitadel + (wallsCastle - wallsCitadel) * 0.5f);
 			castleWalls->addTerm(medium);
 
-			fl::Ramp * high = new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE);
+			fl::Ramp * high = new fl::Ramp("HIGH", wallsCitadel - 0.1, wallsCastle);
 			castleWalls->addTerm(high);
 
-			castleWalls->setRange(CGTownInstance::NONE, CGTownInstance::CASTLE);
+			castleWalls->setRange(wallsNone, wallsCastle);
 		}
 
 

+ 9 - 5
AI/VCAI/FuzzyEngines.cpp

@@ -143,17 +143,21 @@ TacticalAdvantageEngine::TacticalAdvantageEngine()
 		castleWalls = new fl::InputVariable("CastleWalls");
 		engine.addInputVariable(castleWalls);
 		{
-			fl::Rectangle * none = new fl::Rectangle("NONE", CGTownInstance::NONE, CGTownInstance::NONE + (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f);
+			int wallsNone = CGTownInstance::NONE;
+			int wallsFort = CGTownInstance::FORT;
+			int wallsCitadel = CGTownInstance::CITADEL;
+			int wallsCastle = CGTownInstance::CASTLE;
+
+			fl::Rectangle * none = new fl::Rectangle("NONE", wallsNone, wallsNone + (wallsFort - wallsNone) * 0.5f);
 			castleWalls->addTerm(none);
 
-			fl::Trapezoid * medium = new fl::Trapezoid("MEDIUM", (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f, CGTownInstance::FORT,
-				CGTownInstance::CITADEL, CGTownInstance::CITADEL + (CGTownInstance::CASTLE - CGTownInstance::CITADEL) * 0.5f);
+			fl::Trapezoid * medium = new fl::Trapezoid("MEDIUM", (wallsFort - wallsNone) * 0.5f, wallsFort, wallsCitadel, wallsCitadel + (wallsCastle - wallsCitadel) * 0.5f);
 			castleWalls->addTerm(medium);
 
-			fl::Ramp * high = new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE);
+			fl::Ramp * high = new fl::Ramp("HIGH", wallsCitadel - 0.1, wallsCastle);
 			castleWalls->addTerm(high);
 
-			castleWalls->setRange(CGTownInstance::NONE, CGTownInstance::CASTLE);
+			castleWalls->setRange(wallsNone, wallsCastle);
 		}
 
 

+ 12 - 12
AI/VCAI/VCAI.cpp

@@ -174,7 +174,7 @@ void VCAI::showTavernWindow(const CGObjectInstance * object, const CGHeroInstanc
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "TavernWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void VCAI::showThievesGuildWindow(const CGObjectInstance * obj)
@@ -311,7 +311,7 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
 
 	status.addQuery(query, boost::str(boost::format("Exchange between heroes %s (%d) and %s (%d)") % firstHero->getNameTranslated() % firstHero->tempOwner % secondHero->getNameTranslated() % secondHero->tempOwner));
 
-	requestActionASAP([=]()
+	requestActionASAP([this, firstHero, secondHero, query]()
 	{
 		float goalpriority1 = 0;
 		float goalpriority2 = 0;
@@ -370,7 +370,7 @@ void VCAI::showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstan
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "RecruitmentDialog");
-	requestActionASAP([=](){
+	requestActionASAP([this, dwelling, dst, queryID](){
 		recruitCreatures(dwelling, dst);
 		checkHeroArmy(dynamic_cast<const CGHeroInstance*>(dst));
 		answerQuery(queryID, 0);
@@ -532,7 +532,7 @@ void VCAI::showUniversityWindow(const IMarket * market, const CGHeroInstance * v
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "UniversityWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void VCAI::heroManaPointsChanged(const CGHeroInstance * hero)
@@ -600,7 +600,7 @@ void VCAI::showMarketWindow(const IMarket * market, const CGHeroInstance * visit
 	NET_EVENT_HANDLER;
 
 	status.addQuery(queryID, "MarketWindow");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void VCAI::showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions, bool showTerrain)
@@ -646,7 +646,7 @@ void VCAI::yourTurn(QueryID queryID)
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
 	status.addQuery(queryID, "YourTurn");
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 	status.startedTurn();
 	makingTurn = std::make_unique<boost::thread>(&VCAI::makeTurn, this);
 }
@@ -656,7 +656,7 @@ void VCAI::heroGotLevel(const CGHeroInstance * hero, PrimarySkill pskill, std::v
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
 	status.addQuery(queryID, boost::str(boost::format("Hero %s got level %d") % hero->getNameTranslated() % hero->level));
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void VCAI::commanderGotLevel(const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID)
@@ -664,7 +664,7 @@ void VCAI::commanderGotLevel(const CCommanderInstance * commander, std::vector<u
 	LOG_TRACE_PARAMS(logAi, "queryID '%i'", queryID);
 	NET_EVENT_HANDLER;
 	status.addQuery(queryID, boost::str(boost::format("Commander %s of %s got level %d") % commander->name % commander->armyObj->nodeName() % (int)commander->level));
-	requestActionASAP([=](){ answerQuery(queryID, 0); });
+	requestActionASAP([this, queryID](){ answerQuery(queryID, 0); });
 }
 
 void VCAI::showBlockingDialog(const std::string & text, const std::vector<Component> & components, QueryID askID, const int soundID, bool selection, bool cancel, bool safeToAutoaccept)
@@ -681,7 +681,7 @@ void VCAI::showBlockingDialog(const std::string & text, const std::vector<Compon
 	if(!selection && cancel) //yes&no -> always answer yes, we are a brave AI :)
 		sel = 1;
 
-	requestActionASAP([=]()
+	requestActionASAP([this, askID, sel]()
 	{
 		answerQuery(askID, sel);
 	});
@@ -726,7 +726,7 @@ void VCAI::showTeleportDialog(const CGHeroInstance * hero, TeleportChannelID cha
 		}
 	}
 
-	requestActionASAP([=]()
+	requestActionASAP([this, askID, chosenExit]()
 	{
 		answerQuery(askID, chosenExit);
 	});
@@ -743,7 +743,7 @@ void VCAI::showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance *
 	status.addQuery(queryID, boost::str(boost::format("Garrison dialog with %s and %s") % s1 % s2));
 
 	//you can't request action from action-response thread
-	requestActionASAP([=]()
+	requestActionASAP([this, down, up, removableUnits, queryID]()
 	{
 		if(removableUnits && !cb->getStartInfo()->isRestorationOfErathiaCampaign())
 			pickBestCreatures(down, up);
@@ -756,7 +756,7 @@ void VCAI::showMapObjectSelectDialog(QueryID askID, const Component & icon, cons
 {
 	NET_EVENT_HANDLER;
 	status.addQuery(askID, "Map object select query");
-	requestActionASAP([=](){ answerQuery(askID, selectedObject.getNum()); });
+	requestActionASAP([this, askID](){ answerQuery(askID, selectedObject.getNum()); });
 }
 
 void makePossibleUpgrades(const CArmedInstance * obj)

+ 0 - 1
Global.h

@@ -119,7 +119,6 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <chrono>
 #include <climits>
 #include <cmath>
-#include <codecvt>
 #include <condition_variable>
 #include <cstdio>
 #include <cstdlib>

+ 10 - 10
client/CPlayerInterface.cpp

@@ -519,7 +519,7 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill psk
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
 	ENGINE->sound().playSound(soundBase::heroNewLevel);
-	ENGINE->windows().createAndPushWindow<CLevelWindow>(hero, pskill, skills, [=](ui32 selection)
+	ENGINE->windows().createAndPushWindow<CLevelWindow>(hero, pskill, skills, [this, queryID](ui32 selection)
 	{
 		cb->selectionMade(selection, queryID);
 	});
@@ -530,7 +530,7 @@ void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander,
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
 	ENGINE->sound().playSound(soundBase::heroNewLevel);
-	ENGINE->windows().createAndPushWindow<CStackWindow>(commander, skills, [=](ui32 selection)
+	ENGINE->windows().createAndPushWindow<CStackWindow>(commander, skills, [this, queryID](ui32 selection)
 	{
 		cb->selectionMade(selection, queryID);
 	});
@@ -844,7 +844,7 @@ void CPlayerInterface::battleEnd(const BattleID & battleID, const BattleResult *
 
 			if (allowManualReplay || isAutoFightEndBattle)
 			{
-				wnd->resultCallback = [=](ui32 selection)
+				wnd->resultCallback = [this, queryID](ui32 selection)
 				{
 					cb->selectionMade(selection, queryID);
 				};
@@ -1095,7 +1095,7 @@ void CPlayerInterface::showBlockingDialog(const std::string &text, const std::ve
 		for (auto & component : components)
 			intComps.push_back(std::make_shared<CComponent>(component)); //will be deleted by close in window
 
-		showYesNoDialog(text, [=](){ cb->selectionMade(1, askID); }, [=](){ cb->selectionMade(0, askID); }, intComps);
+		showYesNoDialog(text, [this, askID](){ cb->selectionMade(1, askID); }, [this, askID](){ cb->selectionMade(0, askID); }, intComps);
 	}
 	else if (selection)
 	{
@@ -1144,12 +1144,12 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
 	};
 	std::stable_sort(objectGuiOrdered.begin(), objectGuiOrdered.end(), townComparator);
 
-	auto selectCallback = [=](int selection)
+	auto selectCallback = [this, askID](int selection)
 	{
 		cb->sendQueryReply(selection, askID);
 	};
 
-	auto cancelCallback = [=]()
+	auto cancelCallback = [this, askID]()
 	{
 		cb->sendQueryReply(std::nullopt, askID);
 	};
@@ -1272,7 +1272,7 @@ void CPlayerInterface::moveHero( const CGHeroInstance *h, const CGPath& path )
 void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	auto onEnd = [=](){ cb->selectionMade(0, queryID); };
+	auto onEnd = [this, queryID](){ cb->selectionMade(0, queryID); };
 
 	if (movementController->isHeroMovingThroughGarrison(down, up))
 	{
@@ -1381,11 +1381,11 @@ void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const C
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
-	auto recruitCb = [=](CreatureID id, int count)
+	auto recruitCb = [this, dwelling, dst](CreatureID id, int count)
 	{
 		cb->recruitCreatures(dwelling, dst, id, count, -1);
 	};
-	auto closeCb = [=]()
+	auto closeCb = [this, queryID]()
 	{
 		cb->selectionMade(0, queryID);
 	};
@@ -1410,7 +1410,7 @@ void CPlayerInterface::showShipyardDialog(const IShipyard *obj)
 	auto state = obj->shipyardStatus();
 	TResources cost;
 	obj->getBoatCost(cost);
-	ENGINE->windows().createAndPushWindow<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
+	ENGINE->windows().createAndPushWindow<CShipyardWindow>(cost, state, obj->getBoatType(), [this, obj](){ cb->buildBoat(obj); });
 }
 
 void CPlayerInterface::newObject( const CGObjectInstance * obj )

+ 1 - 1
client/adventureMap/CList.cpp

@@ -315,7 +315,7 @@ void CHeroList::CHeroItem::keyPressed(EShortcut key)
 
 	if(key == EShortcut::LIST_HERO_DISMISS)
 	{
-		GAME->interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[22], [=](){ GAME->interface()->cb->dismissHero(hero); }, nullptr);
+		GAME->interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[22], [this](){ GAME->interface()->cb->dismissHero(hero); }, nullptr);
 		return;
 	}
 

+ 9 - 9
client/battle/BattleInterface.cpp

@@ -348,7 +348,7 @@ void BattleInterface::battleFinished(const BattleResult& br, QueryID queryID)
 	}
 
 	auto wnd = std::make_shared<BattleResultWindow>(br, *(this->curInt));
-	wnd->resultCallback = [=](ui32 selection)
+	wnd->resultCallback = [this, queryID](ui32 selection)
 	{
 		curInt->cb->selectionMade(selection, queryID);
 	};
@@ -400,7 +400,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 
 		if(casterStack != nullptr )
 		{
-			addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
+			addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, casterStack, targetedTile, spell]()
 			{
 				stacksController->addNewAnim(new CastAnimation(*this, casterStack, targetedTile, getBattle()->battleGetStackByPos(targetedTile), spell));
 				displaySpellCast(spell, casterStack->getPosition());
@@ -411,14 +411,14 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 			auto hero = sc->side == BattleSide::DEFENDER ? defendingHero : attackingHero;
 			assert(hero);
 
-			addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]()
+			addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, hero, targetedTile, spell]()
 			{
 				stacksController->addNewAnim(new HeroCastAnimation(*this, hero, targetedTile, getBattle()->battleGetStackByPos(targetedTile), spell));
 			});
 		}
 	}
 
-	addToAnimationStage(EAnimationEvents::HIT, [=](){
+	addToAnimationStage(EAnimationEvents::HIT, [this, spell, targetedTile](){
 		displaySpellHit(spell, targetedTile);
 	});
 
@@ -429,7 +429,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 		assert(stack);
 		if(stack)
 		{
-			addToAnimationStage(EAnimationEvents::HIT, [=](){
+			addToAnimationStage(EAnimationEvents::HIT, [this, stack, spell](){
 				displaySpellEffect(spell, stack->getPosition());
 			});
 		}
@@ -439,14 +439,14 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 	{
 		auto stack = getBattle()->battleGetStackByID(elem, false);
 		assert(stack);
-		addToAnimationStage(EAnimationEvents::HIT, [=](){
+		addToAnimationStage(EAnimationEvents::HIT, [this, stack](){
 			effectsController->displayEffect(EBattleEffect::MAGIC_MIRROR, stack->getPosition());
 		});
 	}
 
 	if (!sc->resistedCres.empty())
 	{
-		addToAnimationStage(EAnimationEvents::HIT, [=](){
+		addToAnimationStage(EAnimationEvents::HIT, [](){
 			ENGINE->sound().playSound(AudioPath::builtin("MAGICRES"));
 		});
 	}
@@ -455,7 +455,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 	{
 		auto stack = getBattle()->battleGetStackByID(elem, false);
 		assert(stack);
-		addToAnimationStage(EAnimationEvents::HIT, [=](){
+		addToAnimationStage(EAnimationEvents::HIT, [this, stack](){
 			effectsController->displayEffect(EBattleEffect::RESISTANCE, stack->getPosition());
 		});
 	}
@@ -467,7 +467,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 		Point rightHero = Point(755, 30);
 		BattleSide side = sc->side;
 
-		addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
+		addToAnimationStage(EAnimationEvents::AFTER_HIT, [this, side, leftHero, rightHero](){
 			stacksController->addNewAnim(new EffectAnimation(*this, AnimationPath::builtin(side == BattleSide::DEFENDER ? "SP07_A.DEF" : "SP07_B.DEF"), leftHero));
 			stacksController->addNewAnim(new EffectAnimation(*this, AnimationPath::builtin(side == BattleSide::DEFENDER ? "SP07_B.DEF" : "SP07_A.DEF"), rightHero));
 		});

+ 17 - 17
client/battle/BattleStacksController.cpp

@@ -158,7 +158,7 @@ void BattleStacksController::stackReset(const CStack * stack)
 
 	if(stack->alive() && animation->isDeadOrDying())
 	{
-		owner.addToAnimationStage(EAnimationEvents::HIT, [=]()
+		owner.addToAnimationStage(EAnimationEvents::HIT, [this, stack]()
 		{
 			addNewAnim(new ResurrectionAnimation(owner, stack));
 		});
@@ -206,7 +206,7 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant)
 		// immediately make stack transparent, giving correct shifter time to start
 		setStackColorFilter(Colors::TRANSPARENCY, 0, stack, nullptr, true);
 
-		owner.addToAnimationStage(EAnimationEvents::HIT, [=]()
+		owner.addToAnimationStage(EAnimationEvents::HIT, [this, stack]()
 		{
 			addNewAnim(new ColorTransformAnimation(owner, stack, "summonFadeIn", nullptr));
 			if (stack->isClone())
@@ -416,7 +416,7 @@ void BattleStacksController::stackRemoved(uint32_t stackID)
 
 void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> attackedInfos)
 {
-	owner.addToAnimationStage(EAnimationEvents::HIT, [=](){
+	owner.addToAnimationStage(EAnimationEvents::HIT, [this](){
 		// remove any potentially erased petrification effect
 		removeExpiredColorFilters();
 	});
@@ -441,7 +441,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 		// if (needsReverse && !attackedInfo.defender->isFrozen())
 		if (needsReverse && stackAnimation[attackedInfo.defender->unitId()]->getType() != ECreatureAnimType::FROZEN)
 		{
-			owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [=]()
+			owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [this, attackedInfo]()
 			{
 				addNewAnim(new ReverseAnimation(owner, attackedInfo.defender, attackedInfo.defender->getPosition()));
 			});
@@ -455,7 +455,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 
 		EAnimationEvents usedEvent = useDefenceAnim ? EAnimationEvents::ATTACK : EAnimationEvents::HIT;
 
-		owner.addToAnimationStage(usedEvent, [=]()
+		owner.addToAnimationStage(usedEvent, [this, attackedInfo, useDeathAnim, useDefenceAnim]()
 		{
 			if (useDeathAnim)
 				addNewAnim(new DeathAnimation(owner, attackedInfo.defender, attackedInfo.indirectAttack));
@@ -483,7 +483,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 	{
 		if (attackedInfo.rebirth)
 		{
-			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
+			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [this, attackedInfo](){
 				owner.effectsController->displayEffect(EBattleEffect::RESURRECT, AudioPath::builtin("RESURECT"), attackedInfo.defender->getPosition());
 				addNewAnim(new ResurrectionAnimation(owner, attackedInfo.defender));
 			});
@@ -491,7 +491,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 
 		if (attackedInfo.killed && attackedInfo.defender->summoned)
 		{
-			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
+			owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [this, attackedInfo](){
 				addNewAnim(new ColorTransformAnimation(owner, attackedInfo.defender, "summonFadeOut", nullptr));
 				stackRemoved(attackedInfo.defender->unitId());
 			});
@@ -506,11 +506,11 @@ void BattleStacksController::stackTeleported(const CStack *stack, const BattleHe
 	assert(destHex.size() > 0);
 	//owner.checkForAnimations(); // NOTE: at this point spellcast animations were added, but not executed
 
-	owner.addToAnimationStage(EAnimationEvents::HIT, [=](){
+	owner.addToAnimationStage(EAnimationEvents::HIT, [this, stack](){
 		addNewAnim( new ColorTransformAnimation(owner, stack, "teleportFadeOut", nullptr) );
 	});
 
-	owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=](){
+	owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [this, stack, destHex](){
 		stackAnimation[stack->unitId()]->pos.moveTo(getStackPositionAtHex(destHex.back(), stack));
 		addNewAnim( new ColorTransformAnimation(owner, stack, "teleportFadeIn", nullptr) );
 	});
@@ -585,7 +585,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if (needsReverse)
 	{
-		owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [=]()
+		owner.addToAnimationStage(EAnimationEvents::MOVEMENT, [this, attacker]()
 		{
 			addNewAnim(new ReverseAnimation(owner, attacker, attacker->getPosition()));
 		});
@@ -593,7 +593,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if(info.lucky)
 	{
-		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
+		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, attacker, info]() {
 			owner.appendBattleLog(info.attacker->formatGeneralMessage(-45));
 			owner.effectsController->displayEffect(EBattleEffect::GOOD_LUCK, AudioPath::builtin("GOODLUCK"), attacker->getPosition());
 		});
@@ -601,7 +601,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if(info.unlucky)
 	{
-		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
+		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, attacker, info]() {
 			owner.appendBattleLog(info.attacker->formatGeneralMessage(-44));
 			owner.effectsController->displayEffect(EBattleEffect::BAD_LUCK, AudioPath::builtin("BADLUCK"), attacker->getPosition());
 		});
@@ -609,20 +609,20 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if(info.deathBlow)
 	{
-		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
+		owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, defender, info]() {
 			owner.appendBattleLog(info.attacker->formatGeneralMessage(365));
 			owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, AudioPath::builtin("DEATHBLO"), defender->getPosition());
 		});
 
 		for(auto elem : info.secondaryDefender)
 		{
-			owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [=]() {
+			owner.addToAnimationStage(EAnimationEvents::BEFORE_HIT, [this, elem]() {
 				owner.effectsController->displayEffect(EBattleEffect::DEATH_BLOW, elem->getPosition());
 			});
 		}
 	}
 
-	owner.addToAnimationStage(EAnimationEvents::ATTACK, [=]()
+	owner.addToAnimationStage(EAnimationEvents::ATTACK, [this, attacker, tile, defender, multiAttack, info]()
 	{
 		if (info.indirectAttack)
 		{
@@ -636,7 +636,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if (info.spellEffect != SpellID::NONE)
 	{
-		owner.addToAnimationStage(EAnimationEvents::HIT, [=]()
+		owner.addToAnimationStage(EAnimationEvents::HIT, [this, spellEffect, tile]()
 		{
 			owner.displaySpellHit(spellEffect.toSpell(), tile);
 		});
@@ -644,7 +644,7 @@ void BattleStacksController::stackAttacking( const StackAttackInfo & info )
 
 	if (info.lifeDrain)
 	{
-		owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [=]()
+		owner.addToAnimationStage(EAnimationEvents::AFTER_HIT, [this, attacker]()
 		{
 			owner.effectsController->displayEffect(EBattleEffect::DRAIN_LIFE, AudioPath::builtin("DRAINLIF"), attacker->getPosition(), 0.5);
 		});

+ 2 - 2
client/lobby/CBonusSelection.cpp

@@ -422,9 +422,9 @@ void CBonusSelection::startMap()
 	if (!GAME->server().validateGameStart())
 		return;
 
-	auto showPrologVideo = [=]()
+	auto showPrologVideo = [this]()
 	{
-		auto exitCb = [=]()
+		auto exitCb = []()
 		{
 			logGlobal->info("Starting scenario %d", static_cast<int>(GAME->server().campaignMap));
 			GAME->server().sendStartGame();

+ 1 - 1
client/lobby/CLobbyScreen.cpp

@@ -49,7 +49,7 @@ CLobbyScreen::CLobbyScreen(ESelectionScreen screenType, bool hideScreen)
 		tabSel->callOnSelect = std::bind(&IServerAPI::setMapInfo, &GAME->server(), _1, nullptr);
 
 		buttonSelect = std::make_shared<CButton>(Point(411, 80), AnimationPath::builtin("GSPBUTT.DEF"), LIBRARY->generaltexth->zelp[45], 0, EShortcut::LOBBY_SELECT_SCENARIO);
-		buttonSelect->addCallback([=]()
+		buttonSelect->addCallback([this]()
 		{
 			toggleTab(tabSel);
 			if (getMapInfo() && getMapInfo()->isRandomMap)

+ 1 - 1
client/lobby/CScenarioInfoScreen.cpp

@@ -46,7 +46,7 @@ CScenarioInfoScreen::CScenarioInfoScreen()
 	card->changeSelection();
 
 	card->iconDifficulty->setSelected(getCurrentDifficulty());
-	buttonBack = std::make_shared<CButton>(Point(584, 535), AnimationPath::builtin("SCNRBACK.DEF"), LIBRARY->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
+	buttonBack = std::make_shared<CButton>(Point(584, 535), AnimationPath::builtin("SCNRBACK.DEF"), LIBRARY->generaltexth->zelp[105], [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 }
 
 CScenarioInfoScreen::~CScenarioInfoScreen()

+ 1 - 1
client/lobby/CSelectionBase.cpp

@@ -102,7 +102,7 @@ CSelectionBase::CSelectionBase(ESelectionScreen type)
 	}
 	pos = background->center();
 	card = std::make_shared<InfoCard>();
-	buttonBack = std::make_shared<CButton>(Point(581, 535), AnimationPath::builtin("SCNRBACK.DEF"), LIBRARY->generaltexth->zelp[105], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
+	buttonBack = std::make_shared<CButton>(Point(581, 535), AnimationPath::builtin("SCNRBACK.DEF"), LIBRARY->generaltexth->zelp[105], [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 }
 
 void CSelectionBase::toggleTab(std::shared_ptr<CIntObject> tab)

+ 1 - 1
client/mainmenu/CCampaignScreen.cpp

@@ -83,7 +83,7 @@ std::shared_ptr<CButton> CCampaignScreen::createExitButton(const JsonNode & butt
 	if(!button["help"].isNull() && button["help"].Float() > 0)
 		help = LIBRARY->generaltexth->zelp[(size_t)button["help"].Float()];
 
-	return std::make_shared<CButton>(Point((int)button["x"].Float(), (int)button["y"].Float()), AnimationPath::fromJson(button["name"]), help, [=](){ close();}, EShortcut::GLOBAL_CANCEL);
+	return std::make_shared<CButton>(Point((int)button["x"].Float(), (int)button["y"].Float()), AnimationPath::fromJson(button["name"]), help, [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 }
 
 CCampaignScreen::CCampaignButton::CCampaignButton(const JsonNode & config, const JsonNode & parentConfig, std::string campaignSet)

+ 2 - 2
client/mainmenu/CMainMenu.cpp

@@ -500,7 +500,7 @@ CMultiMode::CMultiMode(ESelectionScreen ScreenType)
 	buttonHost = std::make_shared<CButton>(Point(373, 78 + 57 * 3), AnimationPath::builtin("MUBHOST.DEF"), CButton::tooltip(LIBRARY->generaltexth->translate("vcmi.mainMenu.hostTCP"), ""), std::bind(&CMultiMode::hostTCP, this, EShortcut::MAIN_MENU_HOST_GAME), EShortcut::MAIN_MENU_HOST_GAME);
 	buttonJoin = std::make_shared<CButton>(Point(373, 78 + 57 * 4), AnimationPath::builtin("MUBJOIN.DEF"), CButton::tooltip(LIBRARY->generaltexth->translate("vcmi.mainMenu.joinTCP"), ""), std::bind(&CMultiMode::joinTCP, this, EShortcut::MAIN_MENU_JOIN_GAME), EShortcut::MAIN_MENU_JOIN_GAME);
 
-	buttonCancel = std::make_shared<CButton>(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), LIBRARY->generaltexth->zelp[288], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
+	buttonCancel = std::make_shared<CButton>(Point(373, 424), AnimationPath::builtin("MUBCANC.DEF"), LIBRARY->generaltexth->zelp[288], [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 }
 
 void CMultiMode::openLobby()
@@ -581,7 +581,7 @@ CMultiPlayers::CMultiPlayers(const std::vector<std::string>& playerNames, ESelec
 	}
 
 	buttonOk = std::make_shared<CButton>(Point(95, 338), AnimationPath::builtin("MUBCHCK.DEF"), LIBRARY->generaltexth->zelp[560], std::bind(&CMultiPlayers::enterSelectionScreen, this), EShortcut::GLOBAL_ACCEPT);
-	buttonCancel = std::make_shared<CButton>(Point(205, 338), AnimationPath::builtin("MUBCANC.DEF"), LIBRARY->generaltexth->zelp[561], [=](){ close();}, EShortcut::GLOBAL_CANCEL);
+	buttonCancel = std::make_shared<CButton>(Point(205, 338), AnimationPath::builtin("MUBCANC.DEF"), LIBRARY->generaltexth->zelp[561], [this](){ close();}, EShortcut::GLOBAL_CANCEL);
 	statusBar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(7, 381, 348, 18), 7, 381));
 
 	for(int i = 0; i < playerNames.size(); i++)

+ 1 - 1
client/widgets/Buttons.cpp

@@ -549,7 +549,7 @@ void CToggleGroup::addToggle(int identifier, const std::shared_ptr<CToggleBase>
 		addChild(intObj.get());
 	}
 
-	button->addCallback([=] (bool on) { if (on) selectionChanged(identifier);});
+	button->addCallback([this, identifier] (bool on) { if (on) selectionChanged(identifier);});
 	button->setAllowDeselection(false);
 
 	if(buttons.count(identifier)>0)

+ 2 - 2
client/widgets/CGarrisonInt.cpp

@@ -153,7 +153,7 @@ std::function<void()> CGarrisonSlot::getDismiss() const
 		&& (getObj()->stacksCount() > 1 ||
 			!getObj()->needsLastStack());
 
-	return canDismiss ? [=]()
+	return canDismiss ? [this]()
 	{
 		GAME->interface()->cb->dismissCreature(getObj(), ID);
 	} : (std::function<void()>)nullptr;
@@ -169,7 +169,7 @@ bool CGarrisonSlot::viewInfo()
 	bool canUpgrade = getObj()->tempOwner == GAME->interface()->playerID && pom.canUpgrade(); //upgrade is possible
 	std::function<void(CreatureID)> upgr = nullptr;
 	auto dism = getDismiss();
-	if(canUpgrade) upgr = [=] (CreatureID newID) { GAME->interface()->cb->upgradeCreature(getObj(), ID, newID); };
+	if(canUpgrade) upgr = [this] (CreatureID newID) { GAME->interface()->cb->upgradeCreature(getObj(), ID, newID); };
 
 	owner->selectSlot(nullptr);
 	owner->setSplittingMode(false);

+ 3 - 3
client/windows/CCastleInterface.cpp

@@ -441,7 +441,7 @@ void CHeroGSlot::gesture(bool on, const Point & initialPosition, const Point & f
 		{ RadialMenuConfig::ITEM_SE, twoHeroes, "swapArtifacts", "vcmi.radialWheel.heroSwapArtifacts", [heroId, heroOtherId](){CExchangeController(heroId, heroOtherId).swapArtifacts(true, true);} }
 	};
 	RadialMenuConfig upgradeSlot = { RadialMenuConfig::ITEM_WW, true, "upgradeCreatures", "vcmi.radialWheel.upgradeCreatures", [upgradeAll](){ upgradeAll(); } };
-	RadialMenuConfig dismissSlot = { RadialMenuConfig::ITEM_WW, true, "dismissHero", "vcmi.radialWheel.heroDismiss", [this](){ GAME->interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[22], [=](){ GAME->interface()->cb->dismissHero(hero); }, nullptr); } };
+	RadialMenuConfig dismissSlot = { RadialMenuConfig::ITEM_WW, true, "dismissHero", "vcmi.radialWheel.heroDismiss", [this](){ GAME->interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[22], [this](){ GAME->interface()->cb->dismissHero(hero); }, nullptr); } };
 
 	if(upgradableSlots.isCreatureUpgradePossible)
 		menuElements.push_back(upgradeSlot);
@@ -1079,7 +1079,7 @@ void CCastleBuildings::enterDwelling(int level)
 		return;
 	}
 
-	auto recruitCb = [=](CreatureID id, int count)
+	auto recruitCb = [this, level](CreatureID id, int count)
 	{
 		GAME->interface()->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level);
 	};
@@ -1323,7 +1323,7 @@ void CCreaInfo::hover(bool on)
 void CCreaInfo::clickPressed(const Point & cursorPosition)
 {
 	int offset = GAME->interface()->castleInt? (-87) : 0;
-	auto recruitCb = [=](CreatureID id, int count)
+	auto recruitCb = [this](CreatureID id, int count)
 	{
 		GAME->interface()->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level);
 	};

+ 11 - 11
client/windows/CCreatureWindow.cpp

@@ -348,7 +348,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
 
 	if(parent->info->dismissInfo && parent->info->dismissInfo->callback)
 	{
-		auto onDismiss = [=]()
+		auto onDismiss = [this]()
 		{
 			parent->info->dismissInfo->callback();
 			parent->close();
@@ -372,12 +372,12 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
 		{
 			TResources totalCost = upgradeInfo.info.getAvailableUpgradeCosts().at(buttonIndex) * parent->info->creatureCount;
 
-			auto onUpgrade = [=]()
+			auto onUpgrade = [this, upgradeInfo, buttonIndex]()
 			{
 				upgradeInfo.callback(upgradeInfo.info.getAvailableUpgrades().at(buttonIndex));
 				parent->close();
 			};
-			auto onClick = [=]()
+			auto onClick = [totalCost, onUpgrade]()
 			{
 				std::vector<std::shared_ptr<CComponent>> resComps;
 				for(TResources::nziterator i(totalCost); i.valid(); i++)
@@ -427,7 +427,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset)
 		parent->switchButtons[parent->activeTab]->disable();
 	}
 
-	exit = std::make_shared<CButton>(Point(382, 5), AnimationPath::builtin("hsbtns.def"), LIBRARY->generaltexth->zelp[447], [=](){ parent->close(); }, EShortcut::GLOBAL_RETURN);
+	exit = std::make_shared<CButton>(Point(382, 5), AnimationPath::builtin("hsbtns.def"), LIBRARY->generaltexth->zelp[447], [this](){ parent->close(); }, EShortcut::GLOBAL_RETURN);
 }
 
 CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, int yOffset)
@@ -470,7 +470,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
 			if(parent->selectedSkill == index)
 				parent->setSelection(index, icon);
 
-			icon->callback = [=]()
+			icon->callback = [this, index, icon]()
 			{
 				parent->setSelection(index, icon);
 			};
@@ -503,7 +503,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
 			return skillID >= 100;
 		});
 
-		auto onCreate = [=](size_t index)->std::shared_ptr<CIntObject>
+		auto onCreate = [this](size_t index)->std::shared_ptr<CIntObject>
 		{
 			for(auto skillID : parent->info->levelupInfo->skills)
 			{
@@ -512,7 +512,7 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
 					const auto bonuses = LIBRARY->creh->skillRequirements[skillID-100].first;
 					const CStackInstance * stack = parent->info->commander;
 					auto icon = std::make_shared<CCommanderSkillIcon>(std::make_shared<CPicture>(stack->bonusToGraphics(bonuses[0])), true, [](){});
-					icon->callback = [=]()
+					icon->callback = [this, skillID, icon]()
 					{
 						parent->setSelection(skillID, icon);
 					};
@@ -533,8 +533,8 @@ CStackWindow::CommanderMainSection::CommanderMainSection(CStackWindow * owner, i
 		abilities = std::make_shared<CListBox>(onCreate, Point(38, 3+pos.h), Point(63, 0), 6, abilitiesCount);
 		abilities->setRedrawParent(true);
 
-		leftBtn = std::make_shared<CButton>(Point(10,  pos.h + 6), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [=](){ abilities->moveToPrev(); }, EShortcut::MOVE_LEFT);
-		rightBtn = std::make_shared<CButton>(Point(411, pos.h + 6), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [=](){ abilities->moveToNext(); }, EShortcut::MOVE_RIGHT);
+		leftBtn = std::make_shared<CButton>(Point(10,  pos.h + 6), AnimationPath::builtin("hsbtns3.def"), CButton::tooltip(), [this](){ abilities->moveToPrev(); }, EShortcut::MOVE_LEFT);
+		rightBtn = std::make_shared<CButton>(Point(411, pos.h + 6), AnimationPath::builtin("hsbtns5.def"), CButton::tooltip(), [this](){ abilities->moveToNext(); }, EShortcut::MOVE_RIGHT);
 
 		if(abilitiesCount <= 6)
 		{
@@ -694,7 +694,7 @@ CStackWindow::MainSection::MainSection(CStackWindow * owner, int yOffset, bool s
 			{
 				parent->stackArtifactButton = std::make_shared<CButton>(
 						Point(pos.x - 2 , pos.y + 46), AnimationPath::builtin("stackWindow/cancelButton"),
-						CButton::tooltipLocalized("vcmi.creatureWindow.returnArtifact"),	[=]()
+						CButton::tooltipLocalized("vcmi.creatureWindow.returnArtifact"),	[this]()
 				{
 					parent->removeStackArtifact(ArtifactPosition::CREATURE_SLOT);
 				});
@@ -905,7 +905,7 @@ void CStackWindow::initSections()
 
 	if(info->commander)
 	{
-		auto onCreate = [=](size_t index) -> std::shared_ptr<CIntObject>
+		auto onCreate = [this](size_t index) -> std::shared_ptr<CIntObject>
 		{
 			auto obj = switchTab(index);
 

+ 7 - 7
client/windows/CHeroWindow.cpp

@@ -83,21 +83,21 @@ CHeroWindow::CHeroWindow(const CGHeroInstance * hero)
 
 	statusbar = CGStatusBar::create(7, 559, ImagePath::builtin("ADROLLVR.bmp"), 660);
 
-	quitButton = std::make_shared<CButton>(Point(609, 516), AnimationPath::builtin("hsbtns.def"), CButton::tooltip(heroscrn[17]), [=](){ close(); }, EShortcut::GLOBAL_RETURN);
+	quitButton = std::make_shared<CButton>(Point(609, 516), AnimationPath::builtin("hsbtns.def"), CButton::tooltip(heroscrn[17]), [this](){ close(); }, EShortcut::GLOBAL_RETURN);
 
 	if(settings["general"]["enableUiEnhancements"].Bool())
 	{
-		questlogButton = std::make_shared<CButton>(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [=](){ GAME->interface()->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
-		backpackButton = std::make_shared<CButton>(Point(424, 429), AnimationPath::builtin("heroBackpack"), CButton::tooltipLocalized("vcmi.heroWindow.openBackpack"), [=](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK);
+		questlogButton = std::make_shared<CButton>(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [](){ GAME->interface()->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
+		backpackButton = std::make_shared<CButton>(Point(424, 429), AnimationPath::builtin("heroBackpack"), CButton::tooltipLocalized("vcmi.heroWindow.openBackpack"), [this](){ createBackpackWindow(); }, EShortcut::HERO_BACKPACK);
 		backpackButton->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("heroWindow/backpackButtonIcon")));
-		dismissButton = std::make_shared<CButton>(Point(534, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
+		dismissButton = std::make_shared<CButton>(Point(534, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [this](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
 	}
 	else
 	{
 		dismissLabel = std::make_shared<CTextBox>(LIBRARY->generaltexth->jktexts[8], Rect(370, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
 		questlogLabel = std::make_shared<CTextBox>(LIBRARY->generaltexth->jktexts[9], Rect(510, 430, 65, 35), 0, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE);
-		dismissButton = std::make_shared<CButton>(Point(454, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [=](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
-		questlogButton = std::make_shared<CButton>(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [=](){ GAME->interface()->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
+		dismissButton = std::make_shared<CButton>(Point(454, 429), AnimationPath::builtin("hsbtns2.def"), CButton::tooltip(heroscrn[28]), [this](){ dismissCurrent(); }, EShortcut::HERO_DISMISS);
+		questlogButton = std::make_shared<CButton>(Point(314, 429), AnimationPath::builtin("hsbtns4.def"), CButton::tooltip(heroscrn[0]), [](){ GAME->interface()->showQuestLog(); }, EShortcut::ADVENTURE_QUEST_LOG);
 	}
 
 	formations = std::make_shared<CToggleGroup>(0);
@@ -297,7 +297,7 @@ void CHeroWindow::update()
 	formations->resetCallback();
 	//setting formations
 	formations->setSelected(curHero->formation == EArmyFormation::TIGHT ? 1 : 0);
-	formations->addCallback([=](int value){ GAME->interface()->cb->setFormation(curHero, static_cast<EArmyFormation>(value));});
+	formations->addCallback([this](int value){ GAME->interface()->cb->setFormation(curHero, static_cast<EArmyFormation>(value));});
 
 	morale->set(curHero);
 	luck->set(curHero);

+ 1 - 1
client/windows/GUIClasses.cpp

@@ -1023,7 +1023,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, SecondarySkil
 	boost::replace_first(text, "%s", LIBRARY->skillh->getByIndex(SKILL)->getNameTranslated());
 	boost::replace_first(text, "%d", "2000");
 
-	confirm = std::make_shared<CButton>(Point(148, 299), AnimationPath::builtin("IBY6432.DEF"), CButton::tooltip(hoverText, text), [=](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT);
+	confirm = std::make_shared<CButton>(Point(148, 299), AnimationPath::builtin("IBY6432.DEF"), CButton::tooltip(hoverText, text), [this, SKILL](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT);
 	confirm->block(!available);
 
 	cancel = std::make_shared<CButton>(Point(252,299), AnimationPath::builtin("ICANCEL.DEF"), LIBRARY->generaltexth->zelp[631], [&](){ close(); }, EShortcut::GLOBAL_CANCEL);

+ 1 - 1
client/windows/QuickRecruitmentWindow.cpp

@@ -116,7 +116,7 @@ void QuickRecruitmentWindow::purchaseUnits()
 						level = i;
 				i++;
 			}
-			auto onRecruit = [=](CreatureID id, int count){ GAME->interface()->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level); };
+			auto onRecruit = [this, level](CreatureID id, int count){ GAME->interface()->cb->recruitCreatures(town, town->getUpperArmy(), id, count, level); };
 			CreatureID crid =  selected->creatureOnTheCard->getId();
 			SlotID dstslot = town -> getSlotFor(crid);
 			if(!dstslot.validSlot())

+ 2 - 2
lib/battle/CBattleInfoCallback.cpp

@@ -1761,9 +1761,9 @@ SpellID CBattleInfoCallback::getRandomBeneficialSpell(vstd::RNG & rand, const ba
 	};
 	std::vector<SpellID> beneficialSpells;
 
-	auto getAliveEnemy = [=](const std::function<bool(const CStack *)> & pred) -> const CStack *
+	auto getAliveEnemy = [&](const std::function<bool(const CStack *)> & pred) -> const CStack *
 	{
-		auto stacks = battleGetStacksIf([=](const CStack * stack)
+		auto stacks = battleGetStacksIf([&](const CStack * stack)
 		{
 			return pred(stack) && stack->unitOwner() != subject->unitOwner() && stack->isValidTarget(false);
 		});

+ 1 - 1
lib/battle/CPlayerBattleCallback.cpp

@@ -53,7 +53,7 @@ TStacks CPlayerBattleCallback::battleGetStacks(EStackOwnership whose, bool onlyA
 		ASSERT_IF_CALLED_WITH_PLAYER
 	}
 
-	return battleGetStacksIf([=](const CStack * s){
+	return battleGetStacksIf([&](const CStack * s){
 		const bool ownerMatches = (whose == MINE_AND_ENEMY)
 								|| (whose == ONLY_MINE && s->unitOwner() == getPlayerID())
 								|| (whose == ONLY_ENEMY && s->unitOwner() != getPlayerID());

+ 1 - 1
lib/gameState/CGameState.cpp

@@ -1264,7 +1264,7 @@ EVictoryLossCheckResult CGameState::checkForVictoryAndLoss(const PlayerColor & p
 	const MetaString messageLostSelf = MetaString::createFromTextID("core.genrltxt.7");
 	const MetaString messageLostOther = MetaString::createFromTextID("core.genrltxt.8");
 
-	auto evaluateEvent = [=](const EventCondition & condition)
+	auto evaluateEvent = [this, player](const EventCondition & condition)
 	{
 		return this->checkForVictory(player, condition);
 	};

+ 1 - 1
lib/spells/AdventureSpellMechanics.cpp

@@ -605,7 +605,7 @@ ESpellCastResult TownPortalMechanics::beginCast(SpellCastEnvironment * env, cons
 
 	if(!parameters.pos.valid() && parameters.caster->getSpellSchoolLevel(owner) >= 2)
 	{
-		auto queryCallback = [=](std::optional<int32_t> reply) -> void
+		auto queryCallback = [this, env, parameters](std::optional<int32_t> reply) -> void
 		{
 			if(reply.has_value())
 			{

+ 1 - 1
lib/spells/effects/Dispel.cpp

@@ -88,7 +88,7 @@ void Dispel::serializeJsonUnitEffect(JsonSerializeFormat & handler)
 
 std::shared_ptr<const BonusList> Dispel::getBonuses(const Mechanics * m, const battle::Unit * unit) const
 {
-	auto sel = [=](const Bonus * bonus)
+	auto sel = [this, m](const Bonus * bonus)
 	{
 		if(bonus->source == BonusSource::SPELL_EFFECT)
 		{

+ 6 - 2
lib/texts/TextOperations.cpp

@@ -211,8 +211,12 @@ void TextOperations::trimRightUnicode(std::string & text, const size_t amount)
 
 size_t TextOperations::getUnicodeCharactersCount(const std::string & text)
 {
-	std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
-	return conv.from_bytes(text).size(); 
+	size_t charactersCount = 0;
+
+	for (size_t i=0; i<text.size(); i += getUnicodeCharacterSize(text[i]))
+		charactersCount++;
+
+	return charactersCount;
 }
 
 std::string TextOperations::escapeString(std::string input)