Przeglądaj źródła

Merge pull request #5419 from IvanSavenko/game_engine

[1.7] Rename and reorganize global variables in client
Ivan Savenko 8 miesięcy temu
rodzic
commit
319d90cbb4
100 zmienionych plików z 1554 dodań i 1667 usunięć
  1. 1 1
      AI/BattleAI/AttackPossibility.cpp
  2. 2 2
      AI/BattleAI/BattleEvaluator.cpp
  3. 1 1
      AI/BattleAI/BattleExchangeVariant.cpp
  4. 1 1
      AI/Nullkiller/AIGateway.h
  5. 6 6
      AI/Nullkiller/AIUtility.cpp
  6. 1 1
      AI/Nullkiller/AIUtility.h
  7. 1 1
      AI/Nullkiller/Analyzers/ArmyManager.cpp
  8. 1 1
      AI/Nullkiller/Analyzers/ArmyManager.h
  9. 1 1
      AI/Nullkiller/Analyzers/HeroManager.h
  10. 1 1
      AI/Nullkiller/Behaviors/BuildingBehavior.h
  11. 1 1
      AI/Nullkiller/Behaviors/BuyArmyBehavior.h
  12. 1 1
      AI/Nullkiller/Behaviors/CaptureObjectsBehavior.h
  13. 1 1
      AI/Nullkiller/Behaviors/ClusterBehavior.h
  14. 1 1
      AI/Nullkiller/Behaviors/DefenceBehavior.h
  15. 1 1
      AI/Nullkiller/Behaviors/ExplorationBehavior.h
  16. 1 1
      AI/Nullkiller/Behaviors/GatherArmyBehavior.h
  17. 1 1
      AI/Nullkiller/Behaviors/RecruitHeroBehavior.h
  18. 1 1
      AI/Nullkiller/Behaviors/StartupBehavior.h
  19. 1 1
      AI/Nullkiller/Behaviors/StayAtTownBehavior.h
  20. 3 3
      AI/Nullkiller/Engine/PriorityEvaluator.cpp
  21. 1 1
      AI/Nullkiller/Engine/Settings.cpp
  22. 1 1
      AI/Nullkiller/Goals/AbstractGoal.cpp
  23. 1 1
      AI/Nullkiller/Goals/AbstractGoal.h
  24. 2 2
      AI/Nullkiller/Goals/CompleteQuest.cpp
  25. 1 1
      AI/Nullkiller/Helpers/ArmyFormation.h
  26. 1 1
      AI/Nullkiller/Helpers/ExplorationHelper.h
  27. 1 1
      AI/VCAI/AIUtility.cpp
  28. 1 1
      AI/VCAI/AIUtility.h
  29. 1 1
      AI/VCAI/ArmyManager.h
  30. 1 1
      AI/VCAI/BuildingManager.h
  31. 1 1
      AI/VCAI/Goals/AbstractGoal.cpp
  32. 1 1
      AI/VCAI/Goals/AbstractGoal.h
  33. 1 1
      AI/VCAI/Goals/CompleteQuest.h
  34. 2 2
      AI/VCAI/Goals/GatherTroops.cpp
  35. 5 5
      AI/VCAI/MapObjectsEvaluator.cpp
  36. 1 1
      AI/VCAI/ResourceManager.h
  37. 1 1
      AI/VCAI/VCAI.cpp
  38. 1 1
      AI/VCAI/VCAI.h
  39. 20 20
      client/ArtifactsUIController.cpp
  40. 0 108
      client/CGameInfo.cpp
  41. 0 99
      client/CGameInfo.h
  42. 4 4
      client/CMakeLists.txt
  43. 118 120
      client/CPlayerInterface.cpp
  44. 1 4
      client/CPlayerInterface.h
  45. 35 37
      client/CServerHandler.cpp
  46. 0 2
      client/CServerHandler.h
  47. 29 30
      client/Client.cpp
  48. 42 41
      client/ClientCommandManager.cpp
  49. 11 10
      client/GameChatHandler.cpp
  50. 83 72
      client/GameEngine.cpp
  51. 19 9
      client/GameEngine.h
  52. 60 0
      client/GameInstance.cpp
  53. 41 0
      client/GameInstance.h
  54. 40 40
      client/HeroMovementController.cpp
  55. 57 81
      client/NetPacksClient.cpp
  56. 21 21
      client/NetPacksLobbyClient.cpp
  57. 134 134
      client/adventureMap/AdventureMapInterface.cpp
  58. 94 94
      client/adventureMap/AdventureMapShortcuts.cpp
  59. 6 5
      client/adventureMap/AdventureMapWidget.cpp
  60. 11 10
      client/adventureMap/AdventureOptions.cpp
  61. 20 20
      client/adventureMap/CInGameConsole.cpp
  62. 43 43
      client/adventureMap/CInfoBar.cpp
  63. 1 1
      client/adventureMap/CInfoBar.h
  64. 48 48
      client/adventureMap/CList.cpp
  65. 14 14
      client/adventureMap/CMinimap.cpp
  66. 8 7
      client/adventureMap/CResDataBar.cpp
  67. 23 22
      client/adventureMap/MapAudioPlayer.cpp
  68. 13 13
      client/adventureMap/TurnTimerWidget.cpp
  69. 61 61
      client/battle/BattleActionsController.cpp
  70. 9 10
      client/battle/BattleAnimationClasses.cpp
  71. 3 3
      client/battle/BattleEffectsController.cpp
  72. 19 19
      client/battle/BattleFieldController.cpp
  73. 19 19
      client/battle/BattleInterface.cpp
  74. 53 53
      client/battle/BattleInterfaceClasses.cpp
  75. 6 7
      client/battle/BattleObstacleController.cpp
  76. 2 2
      client/battle/BattleOverlayLogVisualizer.cpp
  77. 2 3
      client/battle/BattleProjectileController.cpp
  78. 6 7
      client/battle/BattleSiegeController.cpp
  79. 8 9
      client/battle/BattleStacksController.cpp
  80. 45 45
      client/battle/BattleWindow.cpp
  81. 3 3
      client/battle/CreatureAnimation.cpp
  82. 20 22
      client/eventsSDL/InputHandler.cpp
  83. 24 28
      client/eventsSDL/InputSourceGameController.cpp
  84. 11 10
      client/eventsSDL/InputSourceKeyboard.cpp
  85. 18 18
      client/eventsSDL/InputSourceMouse.cpp
  86. 6 6
      client/eventsSDL/InputSourceText.cpp
  87. 38 39
      client/eventsSDL/InputSourceTouch.cpp
  88. 5 4
      client/globalLobby/GlobalLobbyAddChannelWindow.cpp
  89. 38 37
      client/globalLobby/GlobalLobbyClient.cpp
  90. 7 6
      client/globalLobby/GlobalLobbyInviteWindow.cpp
  91. 16 15
      client/globalLobby/GlobalLobbyLoginWindow.cpp
  92. 9 8
      client/globalLobby/GlobalLobbyRoomWindow.cpp
  93. 15 14
      client/globalLobby/GlobalLobbyServerSetup.cpp
  94. 15 15
      client/globalLobby/GlobalLobbyWidget.cpp
  95. 10 9
      client/globalLobby/GlobalLobbyWindow.cpp
  96. 11 11
      client/gui/CIntObject.cpp
  97. 1 1
      client/gui/CIntObject.h
  98. 17 15
      client/gui/CursorHandler.cpp
  99. 2 0
      client/gui/CursorHandler.h
  100. 7 7
      client/gui/EventDispatcher.cpp

+ 1 - 1
AI/BattleAI/AttackPossibility.cpp

@@ -38,7 +38,7 @@ void DamageCache::buildObstacleDamageCache(std::shared_ptr<HypotheticBattle> hb,
 		if(!spellObstacle || !obst->triggersEffects())
 			continue;
 
-		auto triggerAbility = VLC->spells()->getById(obst->getTrigger());
+		auto triggerAbility = LIBRARY->spells()->getById(obst->getTrigger());
 		auto triggerIsNegative = triggerAbility->isNegative() || triggerAbility->isDamage();
 
 		if(!triggerIsNegative)

+ 2 - 2
AI/BattleAI/BattleEvaluator.cpp

@@ -426,7 +426,7 @@ BattleAction BattleEvaluator::goTowardsNearest(const CStack * stack, const Battl
 		{
 			if(obst->triggersEffects())
 			{
-				auto triggerAbility =  VLC->spells()->getById(obst->getTrigger());
+				auto triggerAbility =  LIBRARY->spells()->getById(obst->getTrigger());
 				auto triggerIsNegative = triggerAbility->isNegative() || triggerAbility->isDamage();
 
 				if(triggerIsNegative)
@@ -494,7 +494,7 @@ bool BattleEvaluator::attemptCastingSpell(const CStack * activeStack)
 	//Get all spells we can cast
 	std::vector<const CSpell*> possibleSpells;
 
-	for (auto const & s : VLC->spellh->objects)
+	for (auto const & s : LIBRARY->spellh->objects)
 		if (s->canBeCast(cb->getBattle(battleID).get(), spells::Mode::HERO, hero))
 			possibleSpells.push_back(s.get());
 

+ 1 - 1
AI/BattleAI/BattleExchangeVariant.cpp

@@ -349,7 +349,7 @@ MoveTarget BattleExchangeEvaluator::findMoveTowardsUnreachable(
 		logAi->trace(
 			"Checking movement towards %d of %s",
 			enemy->getCount(),
-			VLC->creatures()->getById(enemy->creatureId())->getJsonKey());
+			LIBRARY->creatures()->getById(enemy->creatureId())->getJsonKey());
 
 		auto distance = dists.distToNearestNeighbour(activeStack, enemy);
 

+ 1 - 1
AI/Nullkiller/AIGateway.h

@@ -15,7 +15,7 @@
 #include "../../CCallback.h"
 #include "../../lib/CThreadHelper.h"
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/CCreatureHandler.h"
 #include "../../lib/mapObjects/MiscObjects.h"
 #include "../../lib/spells/CSpellHandler.h"

+ 6 - 6
AI/Nullkiller/AIUtility.cpp

@@ -328,9 +328,9 @@ double getArtifactBonusRelevance(const CGHeroInstance * hero, const std::shared_
 		uint64_t totalWeight = 0;
 		uint64_t knownWeight = 0;
 
-		for (auto spellID : VLC->spellh->getDefaultAllowed())
+		for (auto spellID : LIBRARY->spellh->getDefaultAllowed())
 		{
-			auto spell = spellID.toEntity(VLC);
+			auto spell = spellID.toEntity(LIBRARY);
 			if (!spell->hasSchool(school))
 				continue;
 
@@ -351,9 +351,9 @@ double getArtifactBonusRelevance(const CGHeroInstance * hero, const std::shared_
 		uint64_t totalWeight = 0;
 		uint64_t knownWeight = 0;
 
-		for (auto spellID : VLC->spellh->getDefaultAllowed())
+		for (auto spellID : LIBRARY->spellh->getDefaultAllowed())
 		{
-			auto spell = spellID.toEntity(VLC);
+			auto spell = spellID.toEntity(LIBRARY);
 			if (spell->getLevel() != level)
 				continue;
 
@@ -468,7 +468,7 @@ int32_t getArtifactBonusScoreImpl(const std::shared_ptr<Bonus> & bonus)
 		case BonusType::UNDEAD_RAISE_PERCENTAGE:
 			return bonus->val * 400;
 		case BonusType::GENERATE_RESOURCE:
-			return bonus->val * VLC->objh->resVals.at(bonus->subtype.as<GameResID>().getNum()) * 10;
+			return bonus->val * LIBRARY->objh->resVals.at(bonus->subtype.as<GameResID>().getNum()) * 10;
 		case BonusType::SPELL_DURATION:
 			return bonus->val * 200;
 		case BonusType::MAGIC_RESISTANCE:
@@ -569,7 +569,7 @@ int64_t getArtifactScoreForHero(const CGHeroInstance * hero, const CArtifactInst
 	if (artifact->isScroll())
 	{
 		auto spellID = artifact->getScrollSpellID();
-		auto spell = spellID.toEntity(VLC);
+		auto spell = spellID.toEntity(LIBRARY);
 
 		if (hero->getSpellsInSpellbook().count(spellID))
 			return 0;

+ 1 - 1
AI/Nullkiller/AIUtility.h

@@ -39,7 +39,7 @@
 
 /*********************** TBB.h ********************/
 
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/CCreatureHandler.h"
 #include "../../lib/spells/CSpellHandler.h"
 #include "../../lib/CStopWatch.h"

+ 1 - 1
AI/Nullkiller/Analyzers/ArmyManager.cpp

@@ -121,7 +121,7 @@ std::vector<SlotInfo>::iterator ArmyManager::getBestUnitForScout(std::vector<Slo
 		totalPower += unit.power;
 
 	int baseMovementCost = cb->getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
-	bool terrainHasPenalty = armyTerrain.hasValue() && armyTerrain.toEntity(VLC)->moveCost != baseMovementCost;
+	bool terrainHasPenalty = armyTerrain.hasValue() && armyTerrain.toEntity(LIBRARY)->moveCost != baseMovementCost;
 
 	// arbitrary threshold - don't give scout more than specified part of total AI value of our army
 	uint64_t maxUnitValue = totalPower / 100;

+ 1 - 1
AI/Nullkiller/Analyzers/ArmyManager.h

@@ -13,7 +13,7 @@
 #include "../AIUtility.h"
 
 #include "../../../lib/GameConstants.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 
 namespace NKAI
 {

+ 1 - 1
AI/Nullkiller/Analyzers/HeroManager.h

@@ -13,7 +13,7 @@
 #include "../AIUtility.h"
 
 #include "../../../lib/GameConstants.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 
 namespace NKAI
 {

+ 1 - 1
AI/Nullkiller/Behaviors/BuildingBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../AIUtility.h"
 #include "../Goals/CGoal.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/BuyArmyBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../AIUtility.h"
 #include "../Goals/CGoal.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/CaptureObjectsBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../AIUtility.h"
 #include "../Goals/CGoal.h"
 #include "../Pathfinding/AINodeStorage.h"

+ 1 - 1
AI/Nullkiller/Behaviors/ClusterBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/DefenceBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/ExplorationBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/GatherArmyBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/RecruitHeroBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/StartupBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/Nullkiller/Behaviors/StayAtTownBehavior.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "lib/VCMI_Lib.h"
+#include "lib/GameLibrary.h"
 #include "../Goals/CGoal.h"
 #include "../AIUtility.h"
 

+ 3 - 3
AI/Nullkiller/Engine/PriorityEvaluator.cpp

@@ -18,7 +18,7 @@
 #include "../../../lib/mapping/CMapDefines.h"
 #include "../../../lib/RoadHandler.h"
 #include "../../../lib/CCreatureHandler.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/StartInfo.h"
 #include "../../../CCallback.h"
 #include "../../../lib/filesystem/Filesystem.h"
@@ -309,7 +309,7 @@ uint64_t RewardEvaluator::getArmyReward(
 			{
 				for(auto artID : info.reward.artifacts)
 				{
-					const auto * art = dynamic_cast<const CArtifact *>(VLC->artifacts()->getById(artID));
+					const auto * art = dynamic_cast<const CArtifact *>(LIBRARY->artifacts()->getById(artID));
 
 					rewardValue += evaluateArtifactArmyValue(art);
 				}
@@ -694,7 +694,7 @@ float RewardEvaluator::getSkillReward(const CGObjectInstance * target, const CGH
 			{
 				for(auto spellID : info.reward.spells)
 				{
-					const spells::Spell * spell = VLC->spells()->getById(spellID);
+					const spells::Spell * spell = LIBRARY->spells()->getById(spellID);
 						
 					if(hero->canLearnSpell(spell) && !hero->spellbookContainsSpell(spellID))
 					{

+ 1 - 1
AI/Nullkiller/Engine/Settings.cpp

@@ -18,7 +18,7 @@
 #include "../../../lib/mapObjectConstructors/CBankInstanceConstructor.h"
 #include "../../../lib/mapObjects/MapObjects.h"
 #include "../../../lib/modding/CModHandler.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/filesystem/Filesystem.h"
 #include "../../../lib/json/JsonUtils.h"
 

+ 1 - 1
AI/Nullkiller/Goals/AbstractGoal.cpp

@@ -55,7 +55,7 @@ std::string AbstractGoal::toString() const
 		desc = "GATHER TROOPS";
 		break;
 	case GET_ART_TYPE:
-		desc = "GET ARTIFACT OF TYPE " + VLC->artifacts()->getByIndex(aid)->getNameTranslated();
+		desc = "GET ARTIFACT OF TYPE " + LIBRARY->artifacts()->getByIndex(aid)->getNameTranslated();
 		break;
 	case DIG_AT_TILE:
 		desc = "DIG AT TILE " + tile.toString();

+ 1 - 1
AI/Nullkiller/Goals/AbstractGoal.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/mapObjects/CGTownInstance.h"
 #include "../../../lib/mapObjects/CGHeroInstance.h"
 #include "../AIUtility.h"

+ 2 - 2
AI/Nullkiller/Goals/CompleteQuest.cpp

@@ -11,7 +11,7 @@
 #include "CompleteQuest.h"
 #include "../Behaviors/CaptureObjectsBehavior.h"
 #include "../AIGateway.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/texts/CGeneralTextHandler.h"
 
 namespace NKAI
@@ -91,7 +91,7 @@ std::string CompleteQuest::questToString() const
 {
 	if(isKeyMaster(q))
 	{
-		return "find " + VLC->generaltexth->tentColors[q.obj->subID] + " keymaster tent";
+		return "find " + LIBRARY->generaltexth->tentColors[q.obj->subID] + " keymaster tent";
 	}
 
 	if(q.quest->questName == CQuest::missionName(EQuestMission::NONE))

+ 1 - 1
AI/Nullkiller/Helpers/ArmyFormation.h

@@ -12,7 +12,7 @@
 #include "../AIUtility.h"
 
 #include "../../../lib/GameConstants.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 
 namespace NKAI
 {

+ 1 - 1
AI/Nullkiller/Helpers/ExplorationHelper.h

@@ -12,7 +12,7 @@
 #include "../AIUtility.h"
 
 #include "../../../lib/GameConstants.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../Goals/AbstractGoal.h"
 
 namespace NKAI

+ 1 - 1
AI/VCAI/AIUtility.cpp

@@ -224,7 +224,7 @@ creInfo infoFromDC(const dwellingContent & dc)
 	ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed
 	if (ci.creID != CreatureID::NONE)
 	{
-		ci.cre = VLC->creatures()->getById(ci.creID);
+		ci.cre = LIBRARY->creatures()->getById(ci.creID);
 		ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore.
 	}
 	else

+ 1 - 1
AI/VCAI/AIUtility.h

@@ -9,7 +9,7 @@
  */
 #pragma once
 
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/CCreatureHandler.h"
 #include "../../lib/spells/CSpellHandler.h"
 #include "../../lib/CStopWatch.h"

+ 1 - 1
AI/VCAI/ArmyManager.h

@@ -13,7 +13,7 @@
 #include "AIUtility.h"
 
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "VCAI.h"
 
 struct SlotInfo

+ 1 - 1
AI/VCAI/BuildingManager.h

@@ -13,7 +13,7 @@
 #include "AIUtility.h"
 
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "VCAI.h"
 
 struct DLL_EXPORT PotentialBuilding

+ 1 - 1
AI/VCAI/Goals/AbstractGoal.cpp

@@ -85,7 +85,7 @@ std::string AbstractGoal::name() const //TODO: virtualize
 	}
 	break;
 	case GET_ART_TYPE:
-		desc = "GET ARTIFACT OF TYPE " + VLC->artifacts()->getByIndex(aid)->getNameTranslated();
+		desc = "GET ARTIFACT OF TYPE " + LIBRARY->artifacts()->getByIndex(aid)->getNameTranslated();
 		break;
 	case VISIT_TILE:
 		desc = "VISIT TILE " + tile.toString();

+ 1 - 1
AI/VCAI/Goals/AbstractGoal.h

@@ -9,7 +9,7 @@
 */
 #pragma once
 
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/CCreatureHandler.h"
 #include "../AIUtility.h"
 

+ 1 - 1
AI/VCAI/Goals/CompleteQuest.h

@@ -10,7 +10,7 @@
 #pragma once
 
 #include "CGoal.h"
-#include "../../../lib/VCMI_Lib.h"
+#include "../../../lib/GameLibrary.h"
 #include "../../../lib/gameState/QuestInfo.h"
 
 namespace Goals

+ 2 - 2
AI/VCAI/Goals/GatherTroops.cpp

@@ -87,7 +87,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
 			continue;
 		}
 
-		auto creature = VLC->creatures()->getByIndex(objid);
+		auto creature = LIBRARY->creatures()->getByIndex(objid);
 		if(t->getFactionID() == creature->getFactionID()) //TODO: how to force AI to build unupgraded creatures? :O
 		{
 			auto tryFindCreature = [&]() -> std::optional<std::vector<CreatureID>>
@@ -135,7 +135,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
 			{
 				for(auto type : creature.second)
 				{
-					if(type.getNum() == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost()))
+					if(type.getNum() == objid && ai->ah->freeResources().canAfford(LIBRARY->creatures()->getById(type)->getFullRecruitCost()))
 						vstd::concatenate(solutions, ai->ah->howToVisitObj(obj));
 				}
 			}

+ 5 - 5
AI/VCAI/MapObjectsEvaluator.cpp

@@ -10,7 +10,7 @@
 #include "StdInc.h"
 #include "MapObjectsEvaluator.h"
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/CCreatureHandler.h"
 #include "../../lib/mapObjects/CompoundMapObjectID.h"
 #include "../../lib/mapObjectConstructors/AObjectTypeHandler.h"
@@ -31,11 +31,11 @@ MapObjectsEvaluator & MapObjectsEvaluator::getInstance()
 
 MapObjectsEvaluator::MapObjectsEvaluator()
 {
-	for(auto primaryID : VLC->objtypeh->knownObjects())
+	for(auto primaryID : LIBRARY->objtypeh->knownObjects())
 	{
-		for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
+		for(auto secondaryID : LIBRARY->objtypeh->knownSubObjects(primaryID))
 		{
-			auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
+			auto handler = LIBRARY->objtypeh->getHandlerFor(primaryID, secondaryID);
 			if(handler && !handler->isStaticObject())
 			{
 				if(handler->getAiValue() != std::nullopt)
@@ -83,7 +83,7 @@ std::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance *
 		{
 			for(auto & creatureID : creLevel.second)
 			{
-				auto creature = VLC->creatures()->getById(creatureID);
+				auto creature = LIBRARY->creatures()->getById(creatureID);
 				aiValue += (creature->getAIValue() * creature->getGrowth());
 			}
 		}

+ 1 - 1
AI/VCAI/ResourceManager.h

@@ -11,7 +11,7 @@
 
 #include "AIUtility.h"
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "VCAI.h"
 #include <boost/heap/binomial_heap.hpp>
 

+ 1 - 1
AI/VCAI/VCAI.cpp

@@ -1264,7 +1264,7 @@ void VCAI::recruitCreatures(const CGDwelling * d, const CArmedInstance * recruit
 		int count = d->creatures[i].first;
 		CreatureID creID = d->creatures[i].second.back();
 
-		vstd::amin(count, ah->freeResources() / VLC->creatures()->getById(creID)->getFullRecruitCost());
+		vstd::amin(count, ah->freeResources() / LIBRARY->creatures()->getById(creID)->getFullRecruitCost());
 		if(count > 0)
 			cb->recruitCreatures(d, recruiter, creID, count, i);
 	}

+ 1 - 1
AI/VCAI/VCAI.h

@@ -17,7 +17,7 @@
 #include "../../lib/CThreadHelper.h"
 
 #include "../../lib/GameConstants.h"
-#include "../../lib/VCMI_Lib.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/CCreatureHandler.h"
 #include "../../lib/mapObjects/MiscObjects.h"
 #include "../../lib/spells/CSpellHandler.h"

+ 20 - 20
client/ArtifactsUIController.cpp

@@ -10,7 +10,6 @@
  
 #include "StdInc.h"
 #include "ArtifactsUIController.h"
-#include "CGameInfo.h"
 #include "CPlayerInterface.h"
 
 #include "../CCallback.h"
@@ -18,7 +17,8 @@
 #include "../lib/texts/CGeneralTextHandler.h"
 #include "../lib/mapObjects/CGHeroInstance.h"
 
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/WindowHandler.h"
 #include "widgets/CComponent.h"
 #include "windows/CWindowWithArtifacts.h"
@@ -31,7 +31,7 @@ ArtifactsUIController::ArtifactsUIController()
 
 bool ArtifactsUIController::askToAssemble(const ArtifactLocation & al, const bool onlyEquipped, const bool checkIgnored)
 {
-	if(auto hero = LOCPLINT->cb->getHero(al.artHolder))
+	if(auto hero = GAME->interface()->cb->getHero(al.artHolder))
 	{
 		if(hero->getArt(al.slot) == nullptr)
 		{
@@ -50,7 +50,7 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
 	const auto art = hero->getArt(slot);
 	assert(art);
 
-	if(hero->tempOwner != LOCPLINT->playerID)
+	if(hero->tempOwner != GAME->interface()->playerID)
 		return false;
 
 	if(numOfArtsAskAssembleSession != 0)
@@ -63,7 +63,7 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
 				boost::mutex::scoped_lock askLock(askAssembleArtifactMutex);
 				for(const auto combinedArt : assemblyPossibilities)
 				{
-					boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+					boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 					if(checkIgnored)
 					{
 						if(vstd::contains(ignoredArtifacts, combinedArt->getId()))
@@ -76,17 +76,17 @@ bool ArtifactsUIController::askToAssemble(const CGHeroInstance * hero, const Art
 					message.appendEOL();
 					message.appendEOL();
 					if(combinedArt->isFused())
-						message.appendRawString(CGI->generaltexth->translate("vcmi.heroWindow.fusingArtifact.fusing"));
+						message.appendRawString(LIBRARY->generaltexth->translate("vcmi.heroWindow.fusingArtifact.fusing"));
 					else
-						message.appendRawString(CGI->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
+						message.appendRawString(LIBRARY->generaltexth->allTexts[732]); // You possess all of the components needed to assemble the
 					message.replaceName(ArtifactID(combinedArt->getId()));
-					LOCPLINT->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
+					GAME->interface()->showYesNoDialog(message.toString(), [&assembleConfirmed, hero, slot, combinedArt]()
 						{
 							assembleConfirmed = true;
-							LOCPLINT->cb.get()->assembleArtifacts(hero->id, slot, true, combinedArt->getId());
+							GAME->interface()->cb->assembleArtifacts(hero->id, slot, true, combinedArt->getId());
 						}, nullptr, {std::make_shared<CComponent>(ComponentType::ARTIFACT, combinedArt->getId())});
 
-					LOCPLINT->waitWhileDialog();
+					GAME->interface()->waitWhileDialog();
 					if(assembleConfirmed)
 						break;
 				}
@@ -103,7 +103,7 @@ bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const
 	const auto art = hero->getArt(slot);
 	assert(art);
 
-	if(hero->tempOwner != LOCPLINT->playerID)
+	if(hero->tempOwner != GAME->interface()->playerID)
 		return false;
 
 	if(art->hasParts())
@@ -114,10 +114,10 @@ bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const
 		MetaString message = MetaString::createFromTextID(art->getType()->getDescriptionTextID());
 		message.appendEOL();
 		message.appendEOL();
-		message.appendRawString(CGI->generaltexth->allTexts[733]); // Do you wish to disassemble this artifact?
-		LOCPLINT->showYesNoDialog(message.toString(), [hero, slot]()
+		message.appendRawString(LIBRARY->generaltexth->allTexts[733]); // Do you wish to disassemble this artifact?
+		GAME->interface()->showYesNoDialog(message.toString(), [hero, slot]()
 			{
-				LOCPLINT->cb->assembleArtifacts(hero->id, slot, false, ArtifactID());
+				GAME->interface()->cb->assembleArtifacts(hero->id, slot, false, ArtifactID());
 			}, nullptr);
 		return true;
 	}
@@ -126,9 +126,9 @@ bool ArtifactsUIController::askToDisassemble(const CGHeroInstance * hero, const
 
 void ArtifactsUIController::artifactRemoved()
 {
-	for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
+	for(const auto & artWin : ENGINE->windows().findWindows<CWindowWithArtifacts>())
 		artWin->update();
-	LOCPLINT->waitWhileDialog();
+	GAME->interface()->waitWhileDialog();
 }
 
 void ArtifactsUIController::artifactMoved()
@@ -138,11 +138,11 @@ void ArtifactsUIController::artifactMoved()
 		numOfMovedArts--;
 
 	if(numOfMovedArts == 0)
-		for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
+		for(const auto & artWin : ENGINE->windows().findWindows<CWindowWithArtifacts>())
 		{
 			artWin->update();
 		}
-	LOCPLINT->waitWhileDialog();
+	GAME->interface()->waitWhileDialog();
 }
 
 void ArtifactsUIController::bulkArtMovementStart(size_t totalNumOfArts, size_t possibleAssemblyNumOfArts)
@@ -159,12 +159,12 @@ void ArtifactsUIController::bulkArtMovementStart(size_t totalNumOfArts, size_t p
 
 void ArtifactsUIController::artifactAssembled()
 {
-	for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
+	for(const auto & artWin : ENGINE->windows().findWindows<CWindowWithArtifacts>())
 		artWin->update();
 }
 
 void ArtifactsUIController::artifactDisassembled()
 {
-	for(const auto & artWin : GH.windows().findWindows<CWindowWithArtifacts>())
+	for(const auto & artWin : ENGINE->windows().findWindows<CWindowWithArtifacts>())
 		artWin->update();
 }

+ 0 - 108
client/CGameInfo.cpp

@@ -1,108 +0,0 @@
-/*
- * CGameInfo.cpp, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
-#include "StdInc.h"
-#include "CGameInfo.h"
-
-#include "../lib/VCMI_Lib.h"
-
-CGameInfo * CGI;
-CClientState * CCS = nullptr;
-CServerHandler * CSH;
-
-
-CGameInfo::CGameInfo()
-{
-	globalServices = nullptr;
-}
-
-void CGameInfo::setFromLib()
-{
-	globalServices = VLC;
-	modh = VLC->modh;
-	generaltexth = VLC->generaltexth;
-	creh = VLC->creh;
-	townh = VLC->townh;
-	heroh = VLC->heroh;
-	objh = VLC->objh;
-	spellh = VLC->spellh;
-	skillh = VLC->skillh;
-	objtypeh = VLC->objtypeh;
-	terrainTypeHandler = VLC->terrainTypeHandler;
-	battleFieldHandler = VLC->battlefieldsHandler;
-	obstacleHandler = VLC->obstacleHandler;
-	//TODO: biomeHandler?
-}
-
-const ArtifactService * CGameInfo::artifacts() const
-{
-	return globalServices->artifacts();
-}
-
-const BattleFieldService * CGameInfo::battlefields() const
-{
-	return globalServices->battlefields();
-}
-
-const CreatureService * CGameInfo::creatures() const
-{
-	return globalServices->creatures();
-}
-
-const FactionService * CGameInfo::factions() const
-{
-	return globalServices->factions();
-}
-
-const HeroClassService * CGameInfo::heroClasses() const
-{
-	return globalServices->heroClasses();
-}
-
-const HeroTypeService * CGameInfo::heroTypes() const
-{
-	return globalServices->heroTypes();
-}
-
-#if SCRIPTING_ENABLED
-const scripting::Service * CGameInfo::scripts()  const
-{
-	return globalServices->scripts();
-}
-#endif
-
-const spells::Service * CGameInfo::spells()  const
-{
-	return globalServices->spells();
-}
-
-const SkillService * CGameInfo::skills() const
-{
-	return globalServices->skills();
-}
-
-const ObstacleService * CGameInfo::obstacles() const
-{
-	return globalServices->obstacles();
-}
-
-const IGameSettings * CGameInfo::engineSettings() const
-{
-	return globalServices->engineSettings();
-}
-
-spells::effects::Registry * CGameInfo::spellEffects()
-{
-	return nullptr;
-}
-
-const spells::effects::Registry * CGameInfo::spellEffects() const
-{
-	return globalServices->spellEffects();
-}

+ 0 - 99
client/CGameInfo.h

@@ -1,99 +0,0 @@
-/*
- * CGameInfo.h, part of VCMI engine
- *
- * Authors: listed in file AUTHORS in main folder
- *
- * License: GNU General Public License v2.0 or later
- * Full text of license available in license.txt file, in main folder
- *
- */
-#pragma once
-
-#include <vcmi/Services.h>
-
-#include "../lib/ConstTransitivePtr.h"
-
-VCMI_LIB_NAMESPACE_BEGIN
-
-class CModHandler;
-class CHeroHandler;
-class CCreatureHandler;
-class CSpellHandler;
-class CSkillHandler;
-class CObjectHandler;
-class CObjectClassesHandler;
-class CTownHandler;
-class CGeneralTextHandler;
-class CConsoleHandler;
-class CGameState;
-class BattleFieldHandler;
-class ObstacleHandler;
-class TerrainTypeHandler;
-
-class CMap;
-
-VCMI_LIB_NAMESPACE_END
-
-class CMapHandler;
-class ISoundPlayer;
-class IMusicPlayer;
-class CursorHandler;
-class IVideoPlayer;
-class CServerHandler;
-
-//a class for non-mechanical client GUI classes
-class CClientState
-{
-public:
-	ISoundPlayer * soundh;
-	IMusicPlayer * musich;
-	CConsoleHandler * consoleh;
-	CursorHandler * curh;
-	IVideoPlayer * videoh;
-};
-extern CClientState * CCS;
-
-/// CGameInfo class
-/// for allowing different functions for accessing game information
-class CGameInfo final : public Services
-{
-public:
-	const ArtifactService * artifacts() const override;
-	const CreatureService * creatures() const override;
-	const FactionService * factions() const override;
-	const HeroClassService * heroClasses() const override;
-	const HeroTypeService * heroTypes() const override;
-#if SCRIPTING_ENABLED
-	const scripting::Service * scripts() const override;
-#endif
-	const spells::Service * spells() const override;
-	const SkillService * skills() const override;
-	const BattleFieldService * battlefields() const override;
-	const ObstacleService * obstacles() const override;
-	const IGameSettings * engineSettings() const override;
-
-	const spells::effects::Registry * spellEffects() const override;
-	spells::effects::Registry * spellEffects() override;
-
-	std::shared_ptr<const CModHandler> modh;
-	std::shared_ptr<const BattleFieldHandler> battleFieldHandler;
-	std::shared_ptr<const CHeroHandler> heroh;
-	std::shared_ptr<const CCreatureHandler> creh;
-	std::shared_ptr<const CSpellHandler> spellh;
-	std::shared_ptr<const CSkillHandler> skillh;
-	std::shared_ptr<const CObjectHandler> objh;
-	std::shared_ptr<const TerrainTypeHandler> terrainTypeHandler;
-	std::shared_ptr<const CObjectClassesHandler> objtypeh;
-	std::shared_ptr<const ObstacleHandler> obstacleHandler;
-	std::shared_ptr<const CGeneralTextHandler> generaltexth;
-	std::shared_ptr<const CTownHandler> townh;
-
-	std::shared_ptr<CMapHandler> mh;
-
-	void setFromLib();
-
-	CGameInfo();
-private:
-	const Services * globalServices;
-};
-extern CGameInfo* CGI;

+ 4 - 4
client/CMakeLists.txt

@@ -37,7 +37,6 @@ set(vcmiclientcommon_SRCS
 	eventsSDL/InputSourceTouch.cpp
 	eventsSDL/InputSourceGameController.cpp
 
-	gui/CGuiHandler.cpp
 	gui/CIntObject.cpp
 	gui/CursorHandler.cpp
 	gui/EventDispatcher.cpp
@@ -180,7 +179,8 @@ set(vcmiclientcommon_SRCS
 	xBRZ/xbrz.cpp
 
 	ArtifactsUIController.cpp
-	CGameInfo.cpp
+	GameEngine.cpp
+	GameInstance.cpp
 	CPlayerInterface.cpp
 	PlayerLocalState.cpp
 	CServerHandler.cpp
@@ -233,7 +233,6 @@ set(vcmiclientcommon_HEADERS
 	eventsSDL/InputSourceTouch.h
 	eventsSDL/InputSourceGameController.h
 
-	gui/CGuiHandler.h
 	gui/CIntObject.h
 	gui/CursorHandler.h
 	gui/EventDispatcher.h
@@ -396,9 +395,10 @@ set(vcmiclientcommon_HEADERS
 	xBRZ/xbrz_tools.h
 
 	ArtifactsUIController.h
-	CGameInfo.h
 	CMT.h
 	CPlayerInterface.h
+	GameEngine.h
+	GameInstance.h
 	PlayerLocalState.h
 	CServerHandler.h
 	Client.h

+ 118 - 120
client/CPlayerInterface.cpp

@@ -12,7 +12,6 @@
 
 #include <vcmi/Artifact.h>
 
-#include "CGameInfo.h"
 #include "CServerHandler.h"
 #include "HeroMovementController.h"
 #include "PlayerLocalState.h"
@@ -30,7 +29,8 @@
 #include "eventsSDL/InputHandler.h"
 #include "eventsSDL/NotificationHandler.h"
 
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/CursorHandler.h"
 #include "gui/WindowHandler.h"
 
@@ -112,9 +112,7 @@
 // They all assume that interface mutex is locked.
 #define EVENT_HANDLER_CALLED_BY_CLIENT
 
-#define BATTLE_EVENT_POSSIBLE_RETURN	if (LOCPLINT != this) return; if (isAutoFightOn && !battleInt) return
-
-CPlayerInterface * LOCPLINT;
+#define BATTLE_EVENT_POSSIBLE_RETURN	if (GAME->interface() != this) return; if (isAutoFightOn && !battleInt) return
 
 std::shared_ptr<BattleInterface> CPlayerInterface::battleInt;
 
@@ -137,7 +135,7 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player):
 	
 {
 	logGlobal->trace("\tHuman player interface for player %s being constructed", Player.toString());
-	LOCPLINT = this;
+	GAME->setInterfaceInstance(this);
 	playerID=Player;
 	human=true;
 	battleInt.reset();
@@ -156,8 +154,8 @@ CPlayerInterface::~CPlayerInterface()
 	logGlobal->trace("\tHuman player interface for player %s being destructed", playerID.toString());
 	delete showingDialog;
 	delete cingconsole;
-	if (LOCPLINT == this)
-		LOCPLINT = nullptr;
+	if (GAME->interface() == this)
+		GAME->setInterfaceInstance(nullptr);
 }
 
 void CPlayerInterface::initGameInterface(std::shared_ptr<Environment> ENV, std::shared_ptr<CCallback> CB)
@@ -166,7 +164,7 @@ void CPlayerInterface::initGameInterface(std::shared_ptr<Environment> ENV, std::
 	env = ENV;
 
 	pathfinderCache = std::make_unique<PathfinderCache>(cb.get(), PathfinderOptions(cb.get()));
-	CCS->musich->loadTerrainMusicThemes();
+	ENGINE->music().loadTerrainMusicThemes();
 	initializeHeroTownList();
 
 	adventureInt.reset(new AdventureMapInterface());
@@ -187,10 +185,10 @@ void CPlayerInterface::closeAllDialogs()
 	// remove all active dialogs that do not expect query answer
 	while(true)
 	{
-		auto adventureWindow = GH.windows().topWindow<AdventureMapInterface>();
-		auto settingsWindow = GH.windows().topWindow<SettingsMainWindow>();
-		auto infoWindow = GH.windows().topWindow<CInfoWindow>();
-		auto topWindow = GH.windows().topWindow<WindowBase>();
+		auto adventureWindow = ENGINE->windows().topWindow<AdventureMapInterface>();
+		auto settingsWindow = ENGINE->windows().topWindow<SettingsMainWindow>();
+		auto infoWindow = ENGINE->windows().topWindow<CInfoWindow>();
+		auto topWindow = ENGINE->windows().topWindow<WindowBase>();
 
 		if(adventureWindow != nullptr)
 			break;
@@ -207,7 +205,7 @@ void CPlayerInterface::closeAllDialogs()
 		if (topWindow)
 			topWindow->close();
 		else
-			GH.windows().popWindows(1); // does not inherits from WindowBase, e.g. settings dialog
+			ENGINE->windows().popWindows(1); // does not inherits from WindowBase, e.g. settings dialog
 	}
 }
 
@@ -228,15 +226,15 @@ void CPlayerInterface::playerEndsTurn(PlayerColor player)
 
 void CPlayerInterface::playerStartsTurn(PlayerColor player)
 {
-	if(GH.windows().findWindows<AdventureMapInterface>().empty())
+	if(ENGINE->windows().findWindows<AdventureMapInterface>().empty())
 	{
 		// after map load - remove all active windows and replace them with adventure map
-		GH.windows().clear();
-		GH.windows().pushWindow(adventureInt);
+		ENGINE->windows().clear();
+		ENGINE->windows().pushWindow(adventureInt);
 	}
 
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	if (player != playerID && LOCPLINT == this)
+	if (player != playerID && GAME->interface() == this)
 	{
 		waitWhileDialog();
 
@@ -316,8 +314,8 @@ void CPlayerInterface::yourTurn(QueryID queryID)
 
 	bool hotseatWait = humanPlayersCount > 1;
 
-		LOCPLINT = this;
-		GH.curInt = this;
+		GAME->setInterfaceInstance(this);
+		ENGINE->curInt = this;
 
 		NotificationHandler::notify("Your turn");
 		if(settings["general"]["startTurnAutosave"].Bool())
@@ -330,7 +328,7 @@ void CPlayerInterface::yourTurn(QueryID queryID)
 			adventureInt->onHotseatWaitStarted(playerID);
 
 			makingTurn = true;
-			std::string msg = CGI->generaltexth->allTexts[13];
+			std::string msg = LIBRARY->generaltexth->allTexts[13];
 			boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
 			std::vector<std::shared_ptr<CComponent>> cmp;
 			cmp.push_back(std::make_shared<CComponent>(ComponentType::FLAG, playerID));
@@ -349,7 +347,7 @@ void CPlayerInterface::acceptTurn(QueryID queryID, bool hotseatWait)
 {
 	if (settings["session"]["autoSkip"].Bool())
 	{
-		while(auto iw = GH.windows().topWindow<CInfoWindow>())
+		while(auto iw = ENGINE->windows().topWindow<CInfoWindow>())
 			iw->close();
 	}
 
@@ -400,7 +398,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
-	if(LOCPLINT != this)
+	if(GAME->interface() != this)
 		return;
 
 	//FIXME: read once and store
@@ -447,7 +445,7 @@ void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectI
 	{
 		auto visitSound = visitedObj->getVisitSound(CRandomGenerator::getDefault());
 		if (visitSound)
-			CCS->soundh->playSound(visitSound.value());
+			ENGINE->sound().playSound(visitSound.value());
 	}
 }
 
@@ -457,7 +455,7 @@ void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
 	localState->addWanderingHero(hero);
 	adventureInt->onHeroChanged(hero);
 	if(castleInt)
-		CCS->soundh->playSound(soundBase::newBuilding);
+		ENGINE->sound().playSound(soundBase::newBuilding);
 }
 void CPlayerInterface::openTownWindow(const CGTownInstance * town)
 {
@@ -467,7 +465,7 @@ void CPlayerInterface::openTownWindow(const CGTownInstance * town)
 
 	auto newCastleInt = std::make_shared<CCastleInterface>(town);
 
-	GH.windows().pushWindow(newCastleInt);
+	ENGINE->windows().pushWindow(newCastleInt);
 }
 
 void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
@@ -475,7 +473,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, Prim
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	if (which == PrimarySkill::EXPERIENCE)
 	{
-		for(auto ctw : GH.windows().findWindows<IMarketHolder>())
+		for(auto ctw : ENGINE->windows().findWindows<IMarketHolder>())
 			ctw->updateExperience();
 	}
 	else
@@ -487,7 +485,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, Prim
 void CPlayerInterface::heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	for (auto cuw : GH.windows().findWindows<IMarketHolder>())
+	for (auto cuw : ENGINE->windows().findWindows<IMarketHolder>())
 		cuw->updateSecondarySkills();
 
 	localState->verifyPath(hero);
@@ -511,18 +509,18 @@ void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
 void CPlayerInterface::receivedResource()
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	for (auto mw : GH.windows().findWindows<IMarketHolder>())
+	for (auto mw : ENGINE->windows().findWindows<IMarketHolder>())
 		mw->updateResources();
 
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, PrimarySkill pskill, std::vector<SecondarySkill>& skills, QueryID queryID)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
-	CCS->soundh->playSound(soundBase::heroNewLevel);
-	GH.windows().createAndPushWindow<CLevelWindow>(hero, pskill, skills, [=](ui32 selection)
+	ENGINE->sound().playSound(soundBase::heroNewLevel);
+	ENGINE->windows().createAndPushWindow<CLevelWindow>(hero, pskill, skills, [=](ui32 selection)
 	{
 		cb->selectionMade(selection, queryID);
 	});
@@ -532,8 +530,8 @@ void CPlayerInterface::commanderGotLevel (const CCommanderInstance * commander,
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
-	CCS->soundh->playSound(soundBase::heroNewLevel);
-	GH.windows().createAndPushWindow<CStackWindow>(commander, skills, [=](ui32 selection)
+	ENGINE->sound().playSound(soundBase::heroNewLevel);
+	ENGINE->windows().createAndPushWindow<CStackWindow>(commander, skills, [=](ui32 selection)
 	{
 		cb->selectionMade(selection, queryID);
 	});
@@ -559,15 +557,15 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	adventureInt->onHeroChanged(nullptr);
 	adventureInt->onTownChanged(town);
 
-	for (auto cgh : GH.windows().findWindows<IGarrisonHolder>())
+	for (auto cgh : ENGINE->windows().findWindows<IGarrisonHolder>())
 		if (cgh->holdsGarrison(town))
 			cgh->updateGarrisons();
 
-	for (auto ki : GH.windows().findWindows<CKingdomInterface>())
+	for (auto ki : ENGINE->windows().findWindows<CKingdomInterface>())
 		ki->townChanged(town);
 
 	// Perform totalRedraw to update hero list on adventure map, if any dialogs are open
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town)
@@ -617,11 +615,11 @@ void CPlayerInterface::garrisonsChanged(std::vector<const CArmedInstance *> objs
 		}
 	}
 
-	for (auto cgh : GH.windows().findWindows<IGarrisonHolder>())
+	for (auto cgh : ENGINE->windows().findWindows<IGarrisonHolder>())
 		if (cgh->holdsGarrisons(objs))
 			cgh->updateGarrisons();
 
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void CPlayerInterface::buildChanged(const CGTownInstance *town, BuildingID buildingID, int what) //what: 1 - built, 2 - demolished
@@ -647,10 +645,10 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, BuildingID build
 		}
 
 		// Perform totalRedraw in order to force redraw of updated town list icon from adventure map
-		GH.windows().totalRedraw();
+		ENGINE->windows().totalRedraw();
 	}
 
-	for (auto cgh : GH.windows().findWindows<ITownHolder>())
+	for (auto cgh : ENGINE->windows().findWindows<ITownHolder>())
 		cgh->buildChanged();
 }
 
@@ -811,7 +809,7 @@ void CPlayerInterface::activeStack(const BattleID & battleID, const CStack * sta
 		{
 			//FIXME: we want client rendering to proceed while AI is making actions
 			// so unlock mutex while AI is busy since this might take quite a while, especially if hero has many spells
-			auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+			auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 			autofightingAI->activeStack(battleID, stack);
 			return;
 		}
@@ -855,7 +853,7 @@ void CPlayerInterface::battleEnd(const BattleID & battleID, const BattleResult *
 			
 			isAutoFightEndBattle = false;
 
-			GH.windows().pushWindow(wnd);
+			ENGINE->windows().pushWindow(wnd);
 			// #1490 - during AI turn when quick combat is on, we need to display the message and wait for user to close it.
 			// Otherwise NewTurn causes freeze.
 			waitWhileDialog();
@@ -906,7 +904,7 @@ void CPlayerInterface::battleTriggerEffect(const BattleID & battleID, const Batt
 
 	if(bte.effect == vstd::to_underlying(BonusType::MANA_DRAIN))
 	{
-		const CGHeroInstance * manaDrainedHero = LOCPLINT->cb->getHero(ObjectInstanceID(bte.additionalInfo));
+		const CGHeroInstance * manaDrainedHero = GAME->interface()->cb->getHero(ObjectInstanceID(bte.additionalInfo));
 		battleInt->windowObject->heroManaPointsChanged(manaDrainedHero);
 	}
 }
@@ -1007,12 +1005,12 @@ void CPlayerInterface::showInfoDialog(EInfoWindowMode type, const std::string &t
 		// abort movement, if any. Strictly speaking unnecessary, but prevents some edge cases, like movement sound on visiting Magi Hut with "show messages in status window" on
 		movementController->requestMovementAbort();
 
-		if (makingTurn && GH.windows().count() > 0 && LOCPLINT == this)
-			CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
+		if (makingTurn && ENGINE->windows().count() > 0 && GAME->interface() == this)
+			ENGINE->sound().playSound(static_cast<soundBase::soundID>(soundID));
 		return;
 	}
 
-	if (settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
+	if (settings["session"]["autoSkip"].Bool() && !ENGINE->isKeyboardShiftDown())
 	{
 		return;
 	}
@@ -1039,21 +1037,21 @@ void CPlayerInterface::showInfoDialog(const std::string & text, std::shared_ptr<
 
 void CPlayerInterface::showInfoDialog(const std::string &text, const std::vector<std::shared_ptr<CComponent>> & components, int soundID)
 {
-	LOG_TRACE_PARAMS(logGlobal, "player=%s, text=%s, is LOCPLINT=%d", playerID % text % (this==LOCPLINT));
+	LOG_TRACE_PARAMS(logGlobal, "player=%s, text=%s, is GAME->interface()=%d", playerID % text % (this==GAME->interface()));
 	waitWhileDialog();
 
-	if (settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
+	if (settings["session"]["autoSkip"].Bool() && !ENGINE->isKeyboardShiftDown())
 	{
 		return;
 	}
 	std::shared_ptr<CInfoWindow> temp = CInfoWindow::create(text, playerID, components);
 
-	if ((makingTurn || (battleInt && battleInt->curInt && battleInt->curInt.get() == this)) && GH.windows().count() > 0 && LOCPLINT == this)
+	if ((makingTurn || (battleInt && battleInt->curInt && battleInt->curInt.get() == this)) && ENGINE->windows().count() > 0 && GAME->interface() == this)
 	{
-		CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
+		ENGINE->sound().playSound(static_cast<soundBase::soundID>(soundID));
 		showingDialog->setBusy();
 		movementController->requestMovementAbort(); // interrupt movement to show dialog
-		GH.windows().pushWindow(temp);
+		ENGINE->windows().pushWindow(temp);
 	}
 	else
 	{
@@ -1074,7 +1072,7 @@ void CPlayerInterface::showInfoDialogAndWait(std::vector<Component> & components
 void CPlayerInterface::showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, const std::vector<std::shared_ptr<CComponent>> & components)
 {
 	movementController->requestMovementAbort();
-	LOCPLINT->showingDialog->setBusy();
+	GAME->interface()->showingDialog->setBusy();
 	CInfoWindow::showYesNoDialog(text, components, onYes, onNo, playerID);
 }
 
@@ -1084,7 +1082,7 @@ void CPlayerInterface::showBlockingDialog(const std::string &text, const std::ve
 	waitWhileDialog();
 
 	movementController->requestMovementAbort();
-	CCS->soundh->playSound(static_cast<soundBase::soundID>(soundID));
+	ENGINE->sound().playSound(static_cast<soundBase::soundID>(soundID));
 
 	if (!selection && cancel) //simple yes/no dialog
 	{
@@ -1116,9 +1114,9 @@ void CPlayerInterface::showBlockingDialog(const std::string &text, const std::ve
 		int charperline = 35;
 		if (pom.size() > 1)
 			charperline = 50;
-		GH.windows().createAndPushWindow<CSelWindow>(text, playerID, charperline, intComps, pom, askID);
-		intComps[0]->clickPressed(GH.getCursorPosition());
-		intComps[0]->clickReleased(GH.getCursorPosition());
+		ENGINE->windows().createAndPushWindow<CSelWindow>(text, playerID, charperline, intComps, pom, askID);
+		intComps[0]->clickPressed(ENGINE->getCursorPosition());
+		intComps[0]->clickReleased(ENGINE->getCursorPosition());
 	}
 }
 
@@ -1179,7 +1177,7 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
 		const CGTownInstance * t = dynamic_cast<const CGTownInstance *>(cb->getObj(obj));
 		if(t)
 		{
-			auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
+			auto image = ENGINE->renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
 			image->scaleTo(Point(35, 23), EScalingAlgorithm::NEAREST);
 			images.push_back(image);
 		}
@@ -1187,9 +1185,9 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
 
 	auto wnd = std::make_shared<CObjectListWindow>(tempList, localIcon, localTitle, localDescription, selectCallback, 0, images);
 	wnd->onExit = cancelCallback;
-	wnd->onPopup = [this, objectGuiOrdered](int index) { CRClickPopup::createAndPush(cb->getObj(objectGuiOrdered[index]), GH.getCursorPosition()); };
-	wnd->onClicked = [this, objectGuiOrdered](int index) { adventureInt->centerOnObject(cb->getObj(objectGuiOrdered[index])); GH.windows().totalRedraw(); };
-	GH.windows().pushWindow(wnd);
+	wnd->onPopup = [this, objectGuiOrdered](int index) { CRClickPopup::createAndPush(cb->getObj(objectGuiOrdered[index]), ENGINE->getCursorPosition()); };
+	wnd->onClicked = [this, objectGuiOrdered](int index) { adventureInt->centerOnObject(cb->getObj(objectGuiOrdered[index])); ENGINE->windows().totalRedraw(); };
+	ENGINE->windows().pushWindow(wnd);
 }
 
 void CPlayerInterface::tileRevealed(const std::unordered_set<int3> &pos)
@@ -1207,7 +1205,7 @@ void CPlayerInterface::tileHidden(const std::unordered_set<int3> &pos)
 
 void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
 {
-	GH.windows().createAndPushWindow<CHeroWindow>(hero);
+	ENGINE->windows().createAndPushWindow<CHeroWindow>(hero);
 }
 
 void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
@@ -1215,21 +1213,21 @@ void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	if (const CGTownInstance * townObj = dynamic_cast<const CGTownInstance*>(town))
 	{
-		for (auto fortScreen : GH.windows().findWindows<CFortScreen>())
+		for (auto fortScreen : ENGINE->windows().findWindows<CFortScreen>())
 			fortScreen->creaturesChangedEventHandler();
 
-		for (auto castleInterface : GH.windows().findWindows<CCastleInterface>())
+		for (auto castleInterface : ENGINE->windows().findWindows<CCastleInterface>())
 			if(castleInterface->town == town)
 				castleInterface->creaturesChangedEventHandler();
 
 		if (townObj)
-			for (auto ki : GH.windows().findWindows<CKingdomInterface>())
+			for (auto ki : ENGINE->windows().findWindows<CKingdomInterface>())
 				ki->townChanged(townObj);
 	}
-	else if(town && GH.windows().count() > 0 && (town->ID == Obj::CREATURE_GENERATOR1
+	else if(town && ENGINE->windows().count() > 0 && (town->ID == Obj::CREATURE_GENERATOR1
 		||  town->ID == Obj::CREATURE_GENERATOR4  ||  town->ID == Obj::WAR_MACHINE_FACTORY))
 	{
-		for (auto crw : GH.windows().findWindows<CRecruitmentWindow>())
+		for (auto crw : ENGINE->windows().findWindows<CRecruitmentWindow>())
 			if (crw->dwelling == town)
 				crw->availableCreaturesChanged();
 	}
@@ -1252,7 +1250,7 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
 void CPlayerInterface::moveHero( const CGHeroInstance *h, const CGPath& path )
 {
 	LOG_TRACE(logGlobal);
-	if (!LOCPLINT->makingTurn)
+	if (!GAME->interface()->makingTurn)
 		return;
 
 	assert(h);
@@ -1287,7 +1285,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
 
 	auto cgw = std::make_shared<CGarrisonWindow>(up, down, removableUnits);
 	cgw->quit->addCallback(onEnd);
-	GH.windows().pushWindow(cgw);
+	ENGINE->windows().pushWindow(cgw);
 }
 
 void CPlayerInterface::requestRealized( PackageApplied *pa )
@@ -1307,7 +1305,7 @@ void CPlayerInterface::showHeroExchange(ObjectInstanceID hero1, ObjectInstanceID
 void CPlayerInterface::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	GH.windows().createAndPushWindow<CExchangeWindow>(hero1, hero2, query);
+	ENGINE->windows().createAndPushWindow<CExchangeWindow>(hero1, hero2, query);
 }
 
 void CPlayerInterface::beforeObjectPropertyChanged(const SetObjectProperty * sop)
@@ -1392,18 +1390,18 @@ void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const C
 	{
 		cb->selectionMade(0, queryID);
 	};
-	GH.windows().createAndPushWindow<CRecruitmentWindow>(dwelling, level, dst, recruitCb, closeCb);
+	ENGINE->windows().createAndPushWindow<CRecruitmentWindow>(dwelling, level, dst, recruitCb, closeCb);
 }
 
 void CPlayerInterface::waitWhileDialog()
 {
-	if (GH.amIGuiThread())
+	if (ENGINE->amIGuiThread())
 	{
 		logGlobal->warn("Cannot wait for dialogs in gui thread (deadlock risk)!");
 		return;
 	}
 
-	auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+	auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 	showingDialog->waitWhileBusy();
 }
 
@@ -1413,7 +1411,7 @@ void CPlayerInterface::showShipyardDialog(const IShipyard *obj)
 	auto state = obj->shipyardStatus();
 	TResources cost;
 	obj->getBoatCost(cost);
-	GH.windows().createAndPushWindow<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
+	ENGINE->windows().createAndPushWindow<CShipyardWindow>(cost, state, obj->getBoatType(), [=](){ cb->buildBoat(obj); });
 }
 
 void CPlayerInterface::newObject( const CGObjectInstance * obj )
@@ -1421,10 +1419,10 @@ void CPlayerInterface::newObject( const CGObjectInstance * obj )
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	//we might have built a boat in shipyard in opened town screen
 	if (obj->ID == Obj::BOAT
-		&& LOCPLINT->castleInt
-		&&  obj->visitablePos() == LOCPLINT->castleInt->town->bestLocation())
+		&& GAME->interface()->castleInt
+		&&  obj->visitablePos() == GAME->interface()->castleInt->town->bestLocation())
 	{
-		LOCPLINT->castleInt->addBuilding(BuildingID::SHIP);
+		GAME->interface()->castleInt->addBuilding(BuildingID::SHIP);
 	}
 }
 
@@ -1432,18 +1430,18 @@ void CPlayerInterface::centerView (int3 pos, int focusTime)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 	waitWhileDialog();
-	CCS->curh->hide();
+	ENGINE->cursor().hide();
 	adventureInt->centerOnTile(pos);
 	if (focusTime)
 	{
-		GH.windows().totalRedraw();
+		ENGINE->windows().totalRedraw();
 		{
 			IgnoreEvents ignore(*this);
-			auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+			auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 			boost::this_thread::sleep_for(boost::chrono::milliseconds(focusTime));
 		}
 	}
-	CCS->curh->show();
+	ENGINE->cursor().show();
 }
 
 void CPlayerInterface::objectRemoved(const CGObjectInstance * obj, const PlayerColor & initiator)
@@ -1455,10 +1453,10 @@ void CPlayerInterface::objectRemoved(const CGObjectInstance * obj, const PlayerC
 		if (removalSound)
 		{
 			waitWhileDialog();
-			CCS->soundh->playSound(removalSound.value());
+			ENGINE->sound().playSound(removalSound.value());
 		}
 	}
-	CGI->mh->waitForOngoingAnimations();
+	GAME->map().waitForOngoingAnimations();
 
 	if(obj->ID == Obj::HERO && obj->tempOwner == playerID)
 	{
@@ -1471,7 +1469,7 @@ void CPlayerInterface::objectRemoved(const CGObjectInstance * obj, const PlayerC
 		const CGTownInstance * t = static_cast<const CGTownInstance *>(obj);
 		townRemoved(t);
 	}
-	GH.fakeMouseMove();
+	ENGINE->fakeMouseMove();
 }
 
 void CPlayerInterface::objectRemovedAfter()
@@ -1483,7 +1481,7 @@ void CPlayerInterface::objectRemovedAfter()
 	if (castleInt)
 		castleInt->updateGarrisons();
 
-	for (auto ki : GH.windows().findWindows<CKingdomInterface>())
+	for (auto ki : ENGINE->windows().findWindows<CKingdomInterface>())
 		ki->heroRemoved();
 }
 
@@ -1491,13 +1489,13 @@ void CPlayerInterface::playerBlocked(int reason, bool start)
 {
 	if(reason == PlayerBlocked::EReason::UPCOMING_BATTLE)
 	{
-		if(CSH->howManyPlayerInterfaces() > 1 && LOCPLINT != this && LOCPLINT->makingTurn == false)
+		if(GAME->server().howManyPlayerInterfaces() > 1 && GAME->interface() != this && GAME->interface()->makingTurn == false)
 		{
 			//one of our players who isn't last in order got attacked not by our another player (happens for example in hotseat mode)
-			LOCPLINT = this;
-			GH.curInt = this;
+			GAME->setInterfaceInstance(this);
+			ENGINE->curInt = this;
 			adventureInt->onCurrentPlayerChanged(playerID);
-			std::string msg = CGI->generaltexth->translate("vcmi.adventureMap.playerAttacked");
+			std::string msg = LIBRARY->generaltexth->translate("vcmi.adventureMap.playerAttacked");
 			boost::replace_first(msg, "%s", cb->getStartInfo()->playerInfos.find(playerID)->second.name);
 			std::vector<std::shared_ptr<CComponent>> cmp;
 			cmp.push_back(std::make_shared<CComponent>(ComponentType::FLAG, playerID));
@@ -1515,22 +1513,22 @@ void CPlayerInterface::update()
 	boost::shared_lock gsLock(CGameState::mutex);
 
 	// While mutexes were locked away we may be have stopped being the active interface
-	if (LOCPLINT != this)
+	if (GAME->interface() != this)
 		return;
 
 	//if there are any waiting dialogs, show them
 	if (makingTurn && !dialogs.empty() && !showingDialog->isBusy())
 	{
 		showingDialog->setBusy();
-		GH.windows().pushWindow(dialogs.front());
+		ENGINE->windows().pushWindow(dialogs.front());
 		dialogs.pop_front();
 	}
 
 	assert(adventureInt);
 
 	// Handles mouse and key input
-	GH.handleEvents();
-	GH.windows().simpleRedraw();
+	ENGINE->handleEvents();
+	ENGINE->windows().simpleRedraw();
 }
 
 void CPlayerInterface::endNetwork()
@@ -1576,13 +1574,13 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
 	if (player == playerID)
 	{
 		if (victoryLossCheckResult.loss())
-			showInfoDialog(CGI->generaltexth->allTexts[95]);
+			showInfoDialog(LIBRARY->generaltexth->allTexts[95]);
 
-		assert(GH.curInt == LOCPLINT);
-		auto previousInterface = LOCPLINT; //without multiple player interfaces some of lines below are useless, but for hotseat we wanna swap player interface temporarily
+		assert(ENGINE->curInt == GAME->interface());
+		auto previousInterface = GAME->interface(); //without multiple player interfaces some of lines below are useless, but for hotseat we wanna swap player interface temporarily
 
-		LOCPLINT = this; //this is needed for dialog to show and avoid freeze, dialog showing logic should be reworked someday
-		GH.curInt = this; //waiting for dialogs requires this to get events
+		GAME->setInterfaceInstance(this); //this is needed for dialog to show and avoid freeze, dialog showing logic should be reworked someday
+		ENGINE->curInt = this; //waiting for dialogs requires this to get events
 
 		if(!makingTurn)
 		{
@@ -1593,8 +1591,8 @@ void CPlayerInterface::gameOver(PlayerColor player, const EVictoryLossCheckResul
 		else
 			waitForAllDialogs();
 
-		GH.curInt = previousInterface;
-		LOCPLINT = previousInterface;
+		ENGINE->curInt = previousInterface;
+		GAME->setInterfaceInstance(previousInterface);
 	}
 }
 
@@ -1612,7 +1610,7 @@ void CPlayerInterface::showPuzzleMap()
 	double ratio = 0;
 	int3 grailPos = cb->getGrailPos(&ratio);
 
-	GH.windows().createAndPushWindow<CPuzzleWindow>(grailPos, ratio);
+	ENGINE->windows().createAndPushWindow<CPuzzleWindow>(grailPos, ratio);
 }
 
 void CPlayerInterface::viewWorldMap()
@@ -1624,15 +1622,15 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, SpellID sp
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
 
-	if(GH.windows().topWindow<CSpellWindow>())
-		GH.windows().popWindows(1);
+	if(ENGINE->windows().topWindow<CSpellWindow>())
+		ENGINE->windows().popWindows(1);
 
 	if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
 		localState->erasePath(caster);
 
 	auto castSoundPath = spellID.toSpell()->getCastSound();
 	if(!castSoundPath.empty())
-		CCS->soundh->playSound(castSoundPath);
+		ENGINE->sound().playSound(castSoundPath);
 }
 
 void CPlayerInterface::tryDigging(const CGHeroInstance * h)
@@ -1664,7 +1662,7 @@ void CPlayerInterface::tryDigging(const CGHeroInstance * h)
 	if(msgToShow < 0)
 		cb->dig(h);
 	else
-		showInfoDialog(CGI->generaltexth->allTexts[msgToShow]);
+		showInfoDialog(LIBRARY->generaltexth->allTexts[msgToShow]);
 }
 
 void CPlayerInterface::battleNewRoundFirst(const BattleID & battleID)
@@ -1683,17 +1681,17 @@ void CPlayerInterface::showMarketWindow(const IMarket * market, const CGHeroInst
 	};
 
 	if(market->allowsTrade(EMarketMode::ARTIFACT_EXP) && visitor->getAlignment() != EAlignment::EVIL)
-		GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::ARTIFACT_EXP);
+		ENGINE->windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::ARTIFACT_EXP);
 	else if(market->allowsTrade(EMarketMode::CREATURE_EXP) && visitor->getAlignment() != EAlignment::GOOD)
-		GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::CREATURE_EXP);
+		ENGINE->windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, EMarketMode::CREATURE_EXP);
 	else if(market->allowsTrade(EMarketMode::CREATURE_UNDEAD))
-		GH.windows().createAndPushWindow<CTransformerWindow>(market, visitor, onWindowClosed);
+		ENGINE->windows().createAndPushWindow<CTransformerWindow>(market, visitor, onWindowClosed);
 	else if (!market->availableModes().empty())
 		for(auto mode = EMarketMode::RESOURCE_RESOURCE; mode != EMarketMode::MARKET_AFTER_LAST_PLACEHOLDER; mode = vstd::next(mode, 1))
 		{
 			if(vstd::contains(market->availableModes(), mode))
 			{
-				GH.windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, mode);
+				ENGINE->windows().createAndPushWindow<CMarketWindow>(market, visitor, onWindowClosed, mode);
 				break;
 			}
 		}
@@ -1707,19 +1705,19 @@ void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroI
 	auto onWindowClosed = [this, queryID](){
 		cb->selectionMade(0, queryID);
 	};
-	GH.windows().createAndPushWindow<CUniversityWindow>(visitor, BuildingID::NONE, market, onWindowClosed);
+	ENGINE->windows().createAndPushWindow<CUniversityWindow>(visitor, BuildingID::NONE, market, onWindowClosed);
 }
 
 void CPlayerInterface::showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	GH.windows().createAndPushWindow<CHillFortWindow>(visitor, object);
+	ENGINE->windows().createAndPushWindow<CHillFortWindow>(visitor, object);
 }
 
 void CPlayerInterface::availableArtifactsChanged(const CGBlackMarket * bm)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	for (auto cmw : GH.windows().findWindows<IMarketHolder>())
+	for (auto cmw : ENGINE->windows().findWindows<IMarketHolder>())
 		cmw->updateArtifacts();
 }
 
@@ -1730,19 +1728,19 @@ void CPlayerInterface::showTavernWindow(const CGObjectInstance * object, const C
 		if (queryID != QueryID::NONE)
 			cb->selectionMade(0, queryID);
 	};
-	GH.windows().createAndPushWindow<CTavernWindow>(object, onWindowClosed);
+	ENGINE->windows().createAndPushWindow<CTavernWindow>(object, onWindowClosed);
 }
 
 void CPlayerInterface::showThievesGuildWindow (const CGObjectInstance * obj)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	GH.windows().createAndPushWindow<CThievesGuildWindow>(obj);
+	ENGINE->windows().createAndPushWindow<CThievesGuildWindow>(obj);
 }
 
 void CPlayerInterface::showQuestLog()
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	GH.windows().createAndPushWindow<CQuestLog>(LOCPLINT->cb->getMyQuests());
+	ENGINE->windows().createAndPushWindow<CQuestLog>(GAME->interface()->cb->getMyQuests());
 }
 
 void CPlayerInterface::showShipyardDialogOrProblemPopup(const IShipyard *obj)
@@ -1808,7 +1806,7 @@ void CPlayerInterface::waitForAllDialogs()
 
 	while(!dialogs.empty())
 	{
-		auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 		boost::this_thread::sleep_for(boost::chrono::milliseconds(5));
 	}
 	waitWhileDialog();
@@ -1817,10 +1815,10 @@ void CPlayerInterface::waitForAllDialogs()
 void CPlayerInterface::proposeLoadingGame()
 {
 	showYesNoDialog(
-		CGI->generaltexth->allTexts[68],
+		LIBRARY->generaltexth->allTexts[68],
 		[]()
 		{
-			CSH->endGameplay();
+			GAME->server().endGameplay();
 			CMM->menu->switchToTab("load");
 		},
 		nullptr
@@ -1835,12 +1833,12 @@ bool CPlayerInterface::capturedAllEvents()
 		return true;
 	}
 
-	bool needToLockAdventureMap = adventureInt && adventureInt->isActive() && CGI->mh->hasOngoingAnimations();
+	bool needToLockAdventureMap = adventureInt && adventureInt->isActive() && GAME->map().hasOngoingAnimations();
 	bool quickCombatOngoing = isAutoFightOn && !battleInt;
 
 	if (ignoreEvents || needToLockAdventureMap || quickCombatOngoing )
 	{
-		GH.input().ignoreEventsUntilInput();
+		ENGINE->input().ignoreEventsUntilInput();
 		return true;
 	}
 

+ 1 - 4
client/CPlayerInterface.h

@@ -170,7 +170,7 @@ protected: // Call-ins from server, should not be called directly, but only via
 	void yourTacticPhase(const BattleID & battleID, int distance) override;
 	std::optional<BattleAction> makeSurrenderRetreatDecision(const BattleID & battleID, const BattleStateInfoForRetreat & battleState) override;
 
-public: // public interface for use by client via LOCPLINT access
+public: // public interface for use by client via GAME->interface() access
 
 	// part of GameInterface that is also used by client code
 	void showPuzzleMap() override;
@@ -231,6 +231,3 @@ private:
 	void initializeHeroTownList();
 	int getLastIndex(std::string namePrefix);
 };
-
-/// Provides global access to instance of interface of currently active player
-extern CPlayerInterface * LOCPLINT;

+ 35 - 37
client/CServerHandler.cpp

@@ -11,11 +11,10 @@
 
 #include "CServerHandler.h"
 #include "Client.h"
-#include "CGameInfo.h"
 #include "ServerRunner.h"
 #include "GameChatHandler.h"
 #include "CPlayerInterface.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
 #include "gui/WindowHandler.h"
 
 #include "globalLobby/GlobalLobbyClient.h"
@@ -27,7 +26,6 @@
 #include "media/CMusicHandler.h"
 #include "media/IVideoPlayer.h"
 
-
 #include "mainmenu/CMainMenu.h"
 #include "mainmenu/CPrologEpilogVideo.h"
 #include "mainmenu/CHighScoreScreen.h"
@@ -71,7 +69,7 @@ CServerHandler::~CServerHandler()
 			serverRunner->wait();
 		serverRunner.reset();
 		{
-			auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+			auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 			threadNetwork.join();
 		}
 	}
@@ -88,7 +86,7 @@ void CServerHandler::endNetwork()
 		client->endNetwork();
 	networkHandler->stop();
 	{
-		auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 		threadNetwork.join();
 	}
 }
@@ -144,7 +142,7 @@ void CServerHandler::resetStateForLobby(EStartMode mode, ESelectionScreen screen
 	{
 		std::string playerName = settings["general"]["playerName"].String();
 		if(playerName == "Player")
-			playerName = CGI->generaltexth->translate("core.genrltxt.434");
+			playerName = LIBRARY->generaltexth->translate("core.genrltxt.434");
 		localPlayerNames.push_back(playerName);
 	}
 
@@ -218,7 +216,7 @@ void CServerHandler::connectToServer(const std::string & addr, const ui16 port)
 void CServerHandler::onConnectionFailed(const std::string & errorMessage)
 {
 	assert(getState() == EClientState::CONNECTING);
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	if (isServerLocal())
 	{
@@ -230,21 +228,21 @@ void CServerHandler::onConnectionFailed(const std::string & errorMessage)
 	{
 		// remote server refused connection - show error message
 		setState(EClientState::NONE);
-		CInfoWindow::showInfoDialog(CGI->generaltexth->translate("vcmi.mainMenu.serverConnectionFailed"), {});
+		CInfoWindow::showInfoDialog(LIBRARY->generaltexth->translate("vcmi.mainMenu.serverConnectionFailed"), {});
 	}
 }
 
 void CServerHandler::onTimer()
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	if(getState() == EClientState::CONNECTION_CANCELLED)
 	{
 		logNetwork->info("Connection aborted by player!");
 		serverRunner->wait();
 		serverRunner.reset();
-		if (GH.windows().topWindow<CSimpleJoinScreen>() != nullptr)
-			GH.windows().popWindows(1);
+		if (ENGINE->windows().topWindow<CSimpleJoinScreen>() != nullptr)
+			ENGINE->windows().popWindows(1);
 		return;
 	}
 
@@ -256,7 +254,7 @@ void CServerHandler::onConnectionEstablished(const NetworkConnectionPtr & netCon
 {
 	assert(getState() == EClientState::CONNECTING);
 
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	networkConnection = netConnection;
 
@@ -278,7 +276,7 @@ void CServerHandler::applyPackOnLobbyScreen(CPackForLobby & pack)
 {
 	ApplyOnLobbyScreenNetPackVisitor visitor(*this, dynamic_cast<CLobbyScreen *>(SEL));
 	pack.visit(visitor);
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 std::set<PlayerColor> CServerHandler::getHumanColors()
@@ -546,9 +544,9 @@ void CServerHandler::sendGuiAction(ui8 action) const
 void CServerHandler::sendRestartGame() const
 {
 	if(si->campState && !si->campState->getLoadingBackground().empty())
-		GH.windows().createAndPushWindow<CLoadingScreen>(si->campState->getLoadingBackground());
+		ENGINE->windows().createAndPushWindow<CLoadingScreen>(si->campState->getLoadingBackground());
 	else
-		GH.windows().createAndPushWindow<CLoadingScreen>();
+		ENGINE->windows().createAndPushWindow<CLoadingScreen>();
 	
 	LobbyRestartGame endGame;
 	sendLobbyPack(endGame);
@@ -566,12 +564,12 @@ bool CServerHandler::validateGameStart(bool allowOnlyAI) const
 		std::string errorMsg;
 		if(!e.whatMissing().empty())
 		{
-			errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
+			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToEnable") + '\n';
 			errorMsg += e.whatMissing();
 		}
 		if(!e.whatExcessive().empty())
 		{
-			errorMsg += VLC->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
+			errorMsg += LIBRARY->generaltexth->translate("vcmi.server.errors.modsToDisable") + '\n';
 			errorMsg += e.whatExcessive();
 		}
 		showServerError(errorMsg);
@@ -594,9 +592,9 @@ void CServerHandler::sendStartGame(bool allowOnlyAI) const
 	if(!settings["session"]["headless"].Bool())
 	{
 		if(si->campState && !si->campState->getLoadingBackground().empty())
-			GH.windows().createAndPushWindow<CLoadingScreen>(si->campState->getLoadingBackground());
+			ENGINE->windows().createAndPushWindow<CLoadingScreen>(si->campState->getLoadingBackground());
 		else
-			GH.windows().createAndPushWindow<CLoadingScreen>();
+			ENGINE->windows().createAndPushWindow<CLoadingScreen>();
 	}
 	
 	LobbyPrepareStartGame lpsg;
@@ -653,7 +651,7 @@ void CServerHandler::showHighScoresAndEndGameplay(PlayerColor player, bool victo
 
 		endGameplay();
 		CMM->menu->switchToTab("main");
-		GH.windows().createAndPushWindow<CHighScoreInputScreen>(victory, scenarioHighScores, statistic);
+		ENGINE->windows().createAndPushWindow<CHighScoreInputScreen>(victory, scenarioHighScores, statistic);
 	}
 }
 
@@ -669,14 +667,14 @@ void CServerHandler::endGameplay()
 
 	if(CMM)
 	{
-		GH.curInt = CMM.get();
+		ENGINE->curInt = CMM.get();
 		CMM->enable();
 		CMM->playMusic();
 	}
 	else
 	{
 		auto mainMenu = CMainMenu::create();
-		GH.curInt = mainMenu.get();
+		ENGINE->curInt = mainMenu.get();
 		mainMenu->playMusic();
 	}
 }
@@ -713,29 +711,29 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
 			entry->Bool() = true;
 		}
 
-		GH.windows().pushWindow(CMM);
-		GH.windows().pushWindow(CMM->menu);
+		ENGINE->windows().pushWindow(CMM);
+		ENGINE->windows().pushWindow(CMM->menu);
 
 		if(!ourCampaign->isCampaignFinished())
 			CMM->openCampaignLobby(ourCampaign);
 		else
 		{
 			CMM->openCampaignScreen(ourCampaign->campaignSet);
-			if(!ourCampaign->getOutroVideo().empty() && CCS->videoh->open(ourCampaign->getOutroVideo(), 1))
+			if(!ourCampaign->getOutroVideo().empty() && ENGINE->video().open(ourCampaign->getOutroVideo(), 1))
 			{
-				CCS->musich->stopMusic();
-				GH.windows().createAndPushWindow<VideoWindow>(ourCampaign->getOutroVideo(), ourCampaign->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : ourCampaign->getVideoRim(), false, 1, [campaignScoreCalculator, statistic](bool skipped){
-					GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
+				ENGINE->music().stopMusic();
+				ENGINE->windows().createAndPushWindow<VideoWindow>(ourCampaign->getOutroVideo(), ourCampaign->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : ourCampaign->getVideoRim(), false, 1, [campaignScoreCalculator, statistic](bool skipped){
+					ENGINE->windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
 				});
 			}
 			else
-				GH.windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
+				ENGINE->windows().createAndPushWindow<CHighScoreInputScreen>(true, *campaignScoreCalculator, statistic);
 		}
 	};
 
 	if(epilogue.hasPrologEpilog)
 	{
-		GH.windows().createAndPushWindow<CPrologEpilogVideo>(epilogue, finisher);
+		ENGINE->windows().createAndPushWindow<CPrologEpilogVideo>(epilogue, finisher);
 	}
 	else
 	{
@@ -745,8 +743,8 @@ void CServerHandler::startCampaignScenario(HighScoreParameter param, std::shared
 
 void CServerHandler::showServerError(const std::string & txt) const
 {
-	if(auto w = GH.windows().topWindow<CLoadingScreen>())
-		GH.windows().popWindow(w);
+	if(auto w = ENGINE->windows().topWindow<CLoadingScreen>())
+		ENGINE->windows().popWindow(w);
 	
 	CInfoWindow::showInfoDialog(txt, {});
 }
@@ -803,7 +801,7 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
 
 	boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
 
-	while(!settings["session"]["headless"].Bool() && !GH.windows().topWindow<CLobbyScreen>())
+	while(!settings["session"]["headless"].Bool() && !ENGINE->windows().topWindow<CLobbyScreen>())
 		boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
 
 	while(!mi || mapInfo->fileURI != mi->fileURI)
@@ -857,7 +855,7 @@ public:
 
 void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<std::byte> & message)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	if(getState() == EClientState::DISCONNECTING)
 		return;
@@ -869,7 +867,7 @@ void CServerHandler::onPacketReceived(const std::shared_ptr<INetworkConnection>
 
 void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	if (connection != networkConnection)
 	{
@@ -894,7 +892,7 @@ void CServerHandler::onDisconnected(const std::shared_ptr<INetworkConnection> &
 	{
 		endGameplay();
 		CMM->menu->switchToTab("main");
-		showServerError(CGI->generaltexth->translate("vcmi.server.errors.disconnected"));
+		showServerError(LIBRARY->generaltexth->translate("vcmi.server.errors.disconnected"));
 	}
 	else
 	{
@@ -923,7 +921,7 @@ void CServerHandler::waitForServerShutdown()
 	{
 		if (getState() == EClientState::CONNECTING)
 		{
-			showServerError(CGI->generaltexth->translate("vcmi.server.errors.existingProcess"));
+			showServerError(LIBRARY->generaltexth->translate("vcmi.server.errors.existingProcess"));
 			setState(EClientState::CONNECTION_CANCELLED); // stop attempts to reconnect
 		}
 		logNetwork->error("Error: server failed to close correctly or crashed!");

+ 0 - 2
client/CServerHandler.h

@@ -215,5 +215,3 @@ public:
 	void visitForLobby(CPackForLobby & lobbyPack);
 	void visitForClient(CPackForClient & clientPack);
 };
-
-extern CServerHandler * CSH;

+ 29 - 30
client/Client.cpp

@@ -11,14 +11,14 @@
 #include "Global.h"
 #include "Client.h"
 
-#include "CGameInfo.h"
 #include "CPlayerInterface.h"
 #include "PlayerLocalState.h"
 #include "CServerHandler.h"
 #include "ClientNetPackVisitors.h"
 #include "adventureMap/AdventureMapInterface.h"
 #include "battle/BattleInterface.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/WindowHandler.h"
 #include "mapView/mapHandler.h"
 
@@ -58,7 +58,7 @@ CPlayerEnvironment::CPlayerEnvironment(PlayerColor player_, CClient * cl_, std::
 
 const Services * CPlayerEnvironment::services() const
 {
-	return VLC;
+	return LIBRARY;
 }
 
 vstd::CLoggerBase * CPlayerEnvironment::logger() const
@@ -91,7 +91,7 @@ CClient::~CClient() = default;
 
 const Services * CClient::services() const
 {
-	return VLC; //todo: this should be CGI
+	return LIBRARY; //todo: this should be LIBRARY
 }
 
 const CClient::BattleCb * CClient::battle(const BattleID & battleID) const
@@ -116,18 +116,18 @@ events::EventBus * CClient::eventBus() const
 
 void CClient::newGame(CGameState * initializedGameState)
 {
-	CSH->th->update();
+	GAME->server().th->update();
 	CMapService mapService;
 	assert(initializedGameState);
 	gs = initializedGameState;
-	gs->preInit(VLC, this);
-	logNetwork->trace("\tCreating gamestate: %i", CSH->th->getDiff());
+	gs->preInit(LIBRARY, this);
+	logNetwork->trace("\tCreating gamestate: %i", GAME->server().th->getDiff());
 	if(!initializedGameState)
 	{
 		Load::ProgressAccumulator progressTracking;
-		gs->init(&mapService, CSH->si.get(), progressTracking, settings["general"]["saveRandomMaps"].Bool());
+		gs->init(&mapService, GAME->server().si.get(), progressTracking, settings["general"]["saveRandomMaps"].Bool());
 	}
-	logNetwork->trace("Initializing GameState (together): %d ms", CSH->th->getDiff());
+	logNetwork->trace("Initializing GameState (together): %d ms", GAME->server().th->getDiff());
 
 	initMapHandler();
 	reinitScripting();
@@ -142,8 +142,8 @@ void CClient::loadGame(CGameState * initializedGameState)
 	logNetwork->info("Game state was transferred over network, loading.");
 	gs = initializedGameState;
 
-	gs->preInit(VLC, this);
-	gs->updateOnLoad(CSH->si.get());
+	gs->preInit(LIBRARY, this);
+	gs->updateOnLoad(GAME->server().si.get());
 	logNetwork->info("Game loaded, initialize interfaces.");
 
 	initMapHandler();
@@ -168,8 +168,7 @@ void CClient::save(const std::string & fname)
 
 void CClient::endNetwork()
 {
-	if (CGI->mh)
-		CGI->mh->endNetwork();
+	GAME->map().endNetwork();
 
 	if (CPlayerInterface::battleInt)
 		CPlayerInterface::battleInt->endNetwork();
@@ -192,12 +191,12 @@ void CClient::endGame()
 	for(auto & i : playerint)
 		i.second->finish();
 
-	GH.curInt = nullptr;
+	ENGINE->curInt = nullptr;
 	{
 		logNetwork->info("Ending current game!");
 		removeGUI();
 
-		CGI->mh.reset();
+		GAME->setMapInstance(nullptr);
 		vstd::clear_pointer(gs);
 
 		logNetwork->info("Deleted mapHandler and gameState.");
@@ -219,8 +218,8 @@ void CClient::initMapHandler()
 	// During loading CPlayerInterface from serialized state it's depend on MH
 	if(!settings["session"]["headless"].Bool())
 	{
-		CGI->mh = std::make_shared<CMapHandler>(gs->map);
-		logNetwork->trace("Creating mapHandler: %d ms", CSH->th->getDiff());
+		GAME->setMapInstance(std::make_unique<CMapHandler>(gs->map));
+		logNetwork->trace("Creating mapHandler: %d ms", GAME->server().th->getDiff());
 	}
 }
 
@@ -228,7 +227,7 @@ void CClient::initPlayerEnvironments()
 {
 	playerEnvironments.clear();
 
-	auto allPlayers = CSH->getAllClientPlayers(CSH->logicConnection->connectionID);
+	auto allPlayers = GAME->server().getAllClientPlayers(GAME->server().logicConnection->connectionID);
 	bool hasHumanPlayer = false;
 	for(auto & color : allPlayers)
 	{
@@ -258,7 +257,7 @@ void CClient::initPlayerInterfaces()
 	for(auto & playerInfo : gs->scenarioOps->playerInfos)
 	{
 		PlayerColor color = playerInfo.first;
-		if(!vstd::contains(CSH->getAllClientPlayers(CSH->logicConnection->connectionID), color))
+		if(!vstd::contains(GAME->server().getAllClientPlayers(GAME->server().logicConnection->connectionID), color))
 			continue;
 
 		if(!vstd::contains(playerint, color))
@@ -288,10 +287,10 @@ void CClient::initPlayerInterfaces()
 		installNewPlayerInterface(std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR), PlayerColor::SPECTATOR, true);
 	}
 
-	if(CSH->getAllClientPlayers(CSH->logicConnection->connectionID).count(PlayerColor::NEUTRAL))
+	if(GAME->server().getAllClientPlayers(GAME->server().logicConnection->connectionID).count(PlayerColor::NEUTRAL))
 		installNewBattleInterface(CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String()), PlayerColor::NEUTRAL);
 
-	logNetwork->trace("Initialized player interfaces %d ms", CSH->th->getDiff());
+	logNetwork->trace("Initialized player interfaces %d ms", GAME->server().th->getDiff());
 }
 
 std::string CClient::aiNameForPlayer(const PlayerSettings & ps, bool battleAI, bool alliedToHuman) const
@@ -372,7 +371,7 @@ int CClient::sendRequest(const CPackForServer & request, PlayerColor player)
 	waitingRequest.pushBack(requestID);
 	request.requestID = requestID;
 	request.player = player;
-	CSH->logicConnection->sendPack(request);
+	GAME->server().logicConnection->sendPack(request);
 	if(vstd::contains(playerint, player))
 		playerint[player]->requestSent(&request, requestID);
 
@@ -483,7 +482,7 @@ void CClient::startPlayerBattleAction(const BattleID & battleID, PlayerColor col
 	if (!battleint->human)
 	{
 		// we want to avoid locking gamestate and causing UI to freeze while AI is making turn
-		auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 		battleint->activeStack(battleID, gs->getBattle(battleID)->battleGetStackByID(gs->getBattle(battleID)->activeStack, false));
 	}
 	else
@@ -519,33 +518,33 @@ void CClient::reinitScripting()
 void CClient::removeGUI() const
 {
 	// CClient::endGame
-	GH.curInt = nullptr;
-	GH.windows().clear();
+	ENGINE->curInt = nullptr;
+	ENGINE->windows().clear();
 	adventureInt.reset();
 	logGlobal->info("Removed GUI.");
 
-	LOCPLINT = nullptr;
+	GAME->setInterfaceInstance(nullptr);
 }
 
 #ifdef VCMI_ANDROID
 extern "C" JNIEXPORT jboolean JNICALL Java_eu_vcmi_vcmi_NativeMethods_tryToSaveTheGame(JNIEnv * env, jclass cls)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	logGlobal->info("Received emergency save game request");
-	if(!LOCPLINT || !LOCPLINT->cb)
+	if(!GAME->interface() || !GAME->interface()->cb)
 	{
 		logGlobal->info("... but no active player interface found!");
 		return false;
 	}
 
-	if (!CSH || !CSH->logicConnection)
+	if (!GAME->server().logicConnection)
 	{
 		logGlobal->info("... but no active connection found!");
 		return false;
 	}
 
-	LOCPLINT->cb->save("Saves/_Android_Autosave");
+	GAME->interface()->cb->save("Saves/_Android_Autosave");
 	return true;
 }
 #endif

+ 42 - 41
client/ClientCommandManager.cpp

@@ -15,7 +15,8 @@
 #include "CPlayerInterface.h"
 #include "PlayerLocalState.h"
 #include "CServerHandler.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/WindowHandler.h"
 #include "render/IRenderHandler.h"
 #include "ClientNetPackVisitors.h"
@@ -50,7 +51,7 @@ void ClientCommandManager::handleQuitCommand()
 
 void ClientCommandManager::handleSaveCommand(std::istringstream & singleWordBuffer)
 {
-	if(!CSH->client)
+	if(!GAME->server().client)
 	{
 		printCommandMessage("Game is not in playing state");
 		return;
@@ -58,7 +59,7 @@ void ClientCommandManager::handleSaveCommand(std::istringstream & singleWordBuff
 
 	std::string saveFilename;
 	singleWordBuffer >> saveFilename;
-	CSH->client->save(saveFilename);
+	GAME->server().client->save(saveFilename);
 	printCommandMessage("Game saved as: " + saveFilename);
 }
 
@@ -67,16 +68,16 @@ void ClientCommandManager::handleLoadCommand(std::istringstream& singleWordBuffe
 	// TODO: this code should end the running game and manage to call startGame instead
 	//std::string fname;
 	//singleWordBuffer >> fname;
-	//CSH->client->loadGame(fname);
+	//GAME->server().client->loadGame(fname);
 }
 
 void ClientCommandManager::handleGoSoloCommand()
 {
 	Settings session = settings.write["session"];
 
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
-	if(!CSH->client)
+	if(!GAME->server().client)
 	{
 		printCommandMessage("Game is not in playing state");
 		return;
@@ -85,30 +86,30 @@ void ClientCommandManager::handleGoSoloCommand()
 	if(session["aiSolo"].Bool())
 	{
 		// unlikely it will work but just in case to be consistent
-		for(auto & color : CSH->getAllClientPlayers(CSH->logicConnection->connectionID))
+		for(auto & color : GAME->server().getAllClientPlayers(GAME->server().logicConnection->connectionID))
 		{
-			if(color.isValidPlayer() && CSH->client->getStartInfo()->playerInfos.at(color).isControlledByHuman())
+			if(color.isValidPlayer() && GAME->server().client->getStartInfo()->playerInfos.at(color).isControlledByHuman())
 			{
-				CSH->client->installNewPlayerInterface(std::make_shared<CPlayerInterface>(color), color);
+				GAME->server().client->installNewPlayerInterface(std::make_shared<CPlayerInterface>(color), color);
 			}
 		}
 	}
 	else
 	{
-		PlayerColor currentColor = LOCPLINT->playerID;
-		CSH->client->removeGUI();
+		PlayerColor currentColor = GAME->interface()->playerID;
+		GAME->server().client->removeGUI();
 		
-		for(auto & color : CSH->getAllClientPlayers(CSH->logicConnection->connectionID))
+		for(auto & color : GAME->server().getAllClientPlayers(GAME->server().logicConnection->connectionID))
 		{
-			if(color.isValidPlayer() && CSH->client->getStartInfo()->playerInfos.at(color).isControlledByHuman())
+			if(color.isValidPlayer() && GAME->server().client->getStartInfo()->playerInfos.at(color).isControlledByHuman())
 			{
-				auto AiToGive = CSH->client->aiNameForPlayer(*CSH->client->getPlayerSettings(color), false, false);
+				auto AiToGive = GAME->server().client->aiNameForPlayer(*GAME->server().client->getPlayerSettings(color), false, false);
 				printCommandMessage("Player " + color.toString() + " will be lead by " + AiToGive, ELogLevel::INFO);
-				CSH->client->installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), color);
+				GAME->server().client->installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), color);
 			}
 		}
 
-		GH.windows().totalRedraw();
+		ENGINE->windows().totalRedraw();
 		giveTurn(currentColor);
 	}
 
@@ -127,19 +128,19 @@ void ClientCommandManager::handleControlaiCommand(std::istringstream& singleWord
 	singleWordBuffer >> colorName;
 	boost::to_lower(colorName);
 
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
-	if(!CSH->client)
+	if(!GAME->server().client)
 	{
 		printCommandMessage("Game is not in playing state");
 		return;
 	}
 
 	PlayerColor color;
-	if(LOCPLINT)
-		color = LOCPLINT->playerID;
+	if(GAME->interface())
+		color = GAME->interface()->playerID;
 
-	for(auto & elem : CSH->client->gameState()->players)
+	for(auto & elem : GAME->server().client->gameState()->players)
 	{
 		if(!elem.first.isValidPlayer()
 			|| elem.second.human
@@ -148,11 +149,11 @@ void ClientCommandManager::handleControlaiCommand(std::istringstream& singleWord
 			continue;
 		}
 
-		CSH->client->removeGUI();
-		CSH->client->installNewPlayerInterface(std::make_shared<CPlayerInterface>(elem.first), elem.first);
+		GAME->server().client->removeGUI();
+		GAME->server().client->installNewPlayerInterface(std::make_shared<CPlayerInterface>(elem.first), elem.first);
 	}
 
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 	if(color != PlayerColor::NEUTRAL)
 		giveTurn(color);
 }
@@ -181,13 +182,13 @@ void ClientCommandManager::handleSetBattleAICommand(std::istringstream& singleWo
 
 void ClientCommandManager::handleRedrawCommand()
 {
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void ClientCommandManager::handleTranslateGameCommand(bool onlyMissing)
 {
 	std::map<std::string, std::map<std::string, std::string>> textsByMod;
-	VLC->generaltexth->exportAllTexts(textsByMod, onlyMissing);
+	LIBRARY->generaltexth->exportAllTexts(textsByMod, onlyMissing);
 
 	const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / ( onlyMissing ? "translationMissing" : "translation");
 	boost::filesystem::create_directories(outPath);
@@ -266,7 +267,7 @@ void ClientCommandManager::handleTranslateMapsCommand()
 	}
 
 	std::map<std::string, std::map<std::string, std::string>> textsByMod;
-	VLC->generaltexth->exportAllTexts(textsByMod, false);
+	LIBRARY->generaltexth->exportAllTexts(textsByMod, false);
 
 	const boost::filesystem::path outPath = VCMIDirs::get().userExtractedPath() / "translation";
 	boost::filesystem::create_directories(outPath);
@@ -307,7 +308,7 @@ void ClientCommandManager::handleGetConfigCommand()
 
 	for(auto contentName : contentNames)
 	{
-		auto const & handler = *VLC->modh->content;
+		auto const & handler = *LIBRARY->modh->content;
 		auto const & content = handler[contentName];
 
 		auto contentOutPath = outPath / contentName;
@@ -345,7 +346,7 @@ void ClientCommandManager::handleGetScriptsCommand()
 
 	boost::filesystem::create_directories(outPath);
 
-	for(const auto & kv : VLC->scriptHandler->objects)
+	for(const auto & kv : LIBRARY->scriptHandler->objects)
 	{
 		std::string name = kv.first;
 		boost::algorithm::replace_all(name,":","_");
@@ -393,7 +394,7 @@ void ClientCommandManager::handleDef2bmpCommand(std::istringstream& singleWordBu
 {
 	std::string URI;
 	singleWordBuffer >> URI;
-	auto anim = GH.renderHandler().loadAnimation(AnimationPath::builtin(URI), EImageBlitMode::SIMPLE);
+	auto anim = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin(URI), EImageBlitMode::SIMPLE);
 	anim->exportBitmaps(VCMIDirs::get().userExtractedPath());
 }
 
@@ -436,12 +437,12 @@ void ClientCommandManager::handleBonusesCommand(std::istringstream & singleWordB
 		ss << b;
 		return ss.str();
 	};
-		printCommandMessage("Bonuses of " + LOCPLINT->localState->getCurrentArmy()->getObjectName() + "\n");
-		printCommandMessage(format(*LOCPLINT->localState->getCurrentArmy()->getAllBonuses(Selector::all, Selector::all)) + "\n");
+		printCommandMessage("Bonuses of " + GAME->interface()->localState->getCurrentArmy()->getObjectName() + "\n");
+		printCommandMessage(format(*GAME->interface()->localState->getCurrentArmy()->getAllBonuses(Selector::all, Selector::all)) + "\n");
 
 	printCommandMessage("\nInherited bonuses:\n");
 	TCNodes parents;
-		LOCPLINT->localState->getCurrentArmy()->getParents(parents);
+		GAME->interface()->localState->getCurrentArmy()->getParents(parents);
 	for(const CBonusSystemNode *parent : parents)
 	{
 		printCommandMessage(std::string("\nBonuses from ") + typeid(*parent).name() + "\n" + format(*parent->getAllBonuses(Selector::all, Selector::all)) + "\n");
@@ -457,7 +458,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
 
 	if(what == "hs")
 	{
-		for(const CGHeroInstance* h : LOCPLINT->cb->getHeroesInfo())
+		for(const CGHeroInstance* h : GAME->interface()->cb->getHeroesInfo())
 			if(h->getHeroTypeID().getNum() == id1)
 				if(const CArtifactInstance* a = h->getArt(ArtifactPosition(id2)))
 					printCommandMessage(a->nodeName());
@@ -466,7 +467,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
 
 void ClientCommandManager::handleMpCommand()
 {
-	if(const CGHeroInstance* h = LOCPLINT->localState->getCurrentHero())
+	if(const CGHeroInstance* h = GAME->interface()->localState->getCurrentHero())
 		printCommandMessage(std::to_string(h->movementPointsRemaining()) + "; max: " + std::to_string(h->movementPointsLimit(true)) + "/" + std::to_string(h->movementPointsLimit(false)) + "\n");
 }
 
@@ -509,7 +510,7 @@ void ClientCommandManager::handleVsLog(std::istringstream & singleWordBuffer)
 
 void ClientCommandManager::handleGenerateAssets()
 {
-	GH.renderHandler().exportGeneratedAssets();
+	ENGINE->renderHandler().exportGeneratedAssets();
 	printCommandMessage("All assets generated");
 }
 
@@ -542,10 +543,10 @@ void ClientCommandManager::printCommandMessage(const std::string &commandMessage
 
 	if(currentCallFromIngameConsole)
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
-		if(LOCPLINT && LOCPLINT->cingconsole)
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
+		if(GAME->interface() && GAME->interface()->cingconsole)
 		{
-			LOCPLINT->cingconsole->addMessage("", "System", commandMessage);
+			GAME->interface()->cingconsole->addMessage("", "System", commandMessage);
 		}
 	}
 }
@@ -556,7 +557,7 @@ void ClientCommandManager::giveTurn(const PlayerColor &colorIdentifier)
 	yt.player = colorIdentifier;
 	yt.queryID = QueryID::NONE;
 
-	ApplyClientNetPackVisitor visitor(*CSH->client, *CSH->client->gameState());
+	ApplyClientNetPackVisitor visitor(*GAME->server().client, *GAME->server().client->gameState());
 	yt.visit(visitor);
 }
 
@@ -626,7 +627,7 @@ void ClientCommandManager::processCommand(const std::string & message, bool call
 	else if(commandName == "tell")
 		handleTellCommand(singleWordBuffer);
 
-	else if(commandName == "mp" && LOCPLINT)
+	else if(commandName == "mp" && GAME->interface())
 		handleMpCommand();
 
 	else if (commandName == "set")

+ 11 - 10
client/GameChatHandler.cpp

@@ -10,6 +10,7 @@
 #include "StdInc.h"
 
 #include "GameChatHandler.h"
+#include "GameInstance.h"
 #include "CServerHandler.h"
 #include "CPlayerInterface.h"
 #include "PlayerLocalState.h"
@@ -23,7 +24,7 @@
 #include "../lib/networkPacks/PacksForLobby.h"
 #include "../lib/mapObjects/CArmedInstance.h"
 #include "../lib/CConfigHandler.h"
-#include "../lib/VCMI_Lib.h"
+#include "../lib/GameLibrary.h"
 #include "../lib/texts/CGeneralTextHandler.h"
 #include "../lib/texts/TextOperations.h"
 
@@ -39,8 +40,8 @@ void GameChatHandler::resetMatchState()
 
 void GameChatHandler::sendMessageGameplay(const std::string & messageText)
 {
-	LOCPLINT->cb->sendMessage(messageText, LOCPLINT->localState->getCurrentArmy());
-	CSH->getGlobalLobby().sendMatchChatMessage(messageText);
+	GAME->interface()->cb->sendMessage(messageText, GAME->interface()->localState->getCurrentArmy());
+	GAME->server().getGlobalLobby().sendMatchChatMessage(messageText);
 }
 
 void GameChatHandler::sendMessageLobby(const std::string & senderName, const std::string & messageText)
@@ -50,8 +51,8 @@ void GameChatHandler::sendMessageLobby(const std::string & senderName, const std
 	txt.appendRawString(messageText);
 	lcm.message = txt;
 	lcm.playerName = senderName;
-	CSH->sendLobbyPack(lcm);
-	CSH->getGlobalLobby().sendMatchChatMessage(messageText);
+	GAME->server().sendLobbyPack(lcm);
+	GAME->server().getGlobalLobby().sendMatchChatMessage(messageText);
 }
 
 void GameChatHandler::onNewLobbyMessageReceived(const std::string & senderName, const std::string & messageText)
@@ -90,20 +91,20 @@ void GameChatHandler::onNewGameMessageReceived(PlayerColor sender, const std::st
 	std::string playerName = "<UNKNOWN>";
 
 	if (sender.isValidPlayer())
-		playerName = LOCPLINT->cb->getStartInfo()->playerInfos.at(sender).name;
+		playerName = GAME->interface()->cb->getStartInfo()->playerInfos.at(sender).name;
 
 	if (sender.isSpectator())
-		playerName = VLC->generaltexth->translate("vcmi.lobby.login.spectator");
+		playerName = LIBRARY->generaltexth->translate("vcmi.lobby.login.spectator");
 
 	chatHistory.push_back({playerName, messageText, timeFormatted});
 
-	LOCPLINT->cingconsole->addMessage(timeFormatted, playerName, messageText);
+	GAME->interface()->cingconsole->addMessage(timeFormatted, playerName, messageText);
 }
 
 void GameChatHandler::onNewSystemMessageReceived(const std::string & messageText)
 {
 	chatHistory.push_back({"System", messageText, TextOperations::getCurrentFormattedTimeLocal()});
 
-	if(LOCPLINT && !settings["session"]["hideSystemMessages"].Bool())
-		LOCPLINT->cingconsole->addMessage(TextOperations::getCurrentFormattedTimeLocal(), "System", messageText);
+	if(GAME->interface() && !settings["session"]["hideSystemMessages"].Bool())
+		GAME->interface()->cingconsole->addMessage(TextOperations::getCurrentFormattedTimeLocal(), "System", messageText);
 }

+ 83 - 72
client/gui/CGuiHandler.cpp → client/GameEngine.cpp

@@ -1,5 +1,5 @@
 /*
- * CGuiHandler.cpp, part of VCMI engine
+ * GameEngine.cpp, part of VCMI engine
  *
  * Authors: listed in file AUTHORS in main folder
  *
@@ -8,51 +8,57 @@
  *
  */
 #include "StdInc.h"
-#include "CGuiHandler.h"
-
-#include "CIntObject.h"
-#include "CursorHandler.h"
-#include "ShortcutHandler.h"
-#include "FramerateManager.h"
-#include "WindowHandler.h"
-#include "EventDispatcher.h"
-#include "../eventsSDL/InputHandler.h"
-
-#include "../CGameInfo.h"
-#include "../adventureMap/AdventureMapInterface.h"
-#include "../render/Canvas.h"
-#include "../render/Colors.h"
-#include "../render/Graphics.h"
-#include "../render/IFont.h"
-#include "../render/EFont.h"
-#include "../renderSDL/ScreenHandler.h"
-#include "../renderSDL/RenderHandler.h"
-#include "../CPlayerInterface.h"
-#include "../battle/BattleInterface.h"
-
-#include "../../lib/CThreadHelper.h"
-#include "../../lib/CConfigHandler.h"
+#include "GameEngine.h"
+
+#include "gui/CIntObject.h"
+#include "gui/CursorHandler.h"
+#include "gui/ShortcutHandler.h"
+#include "gui/FramerateManager.h"
+#include "gui/WindowHandler.h"
+#include "gui/EventDispatcher.h"
+#include "eventsSDL/InputHandler.h"
+
+#include "media/CMusicHandler.h"
+#include "media/CSoundHandler.h"
+#include "media/CVideoHandler.h"
+#include "media/CEmptyVideoPlayer.h"
+
+#include "CPlayerInterface.h"
+#include "adventureMap/AdventureMapInterface.h"
+#include "render/Canvas.h"
+#include "render/Colors.h"
+#include "render/Graphics.h"
+#include "render/IFont.h"
+#include "render/EFont.h"
+#include "renderSDL/ScreenHandler.h"
+#include "renderSDL/RenderHandler.h"
+#include "CMT.h"
+#include "GameInstance.h"
+#include "battle/BattleInterface.h"
+
+#include "../lib/CThreadHelper.h"
+#include "../lib/CConfigHandler.h"
 
 #include <SDL_render.h>
 
-CGuiHandler GH;
+std::unique_ptr<GameEngine> ENGINE;
 
 static thread_local bool inGuiThread = false;
 
 ObjectConstruction::ObjectConstruction(CIntObject *obj)
 {
-	GH.createdObj.push_front(obj);
-	GH.captureChildren = true;
+	ENGINE->createdObj.push_front(obj);
+	ENGINE->captureChildren = true;
 }
 
 ObjectConstruction::~ObjectConstruction()
 {
-	assert(!GH.createdObj.empty());
-	GH.createdObj.pop_front();
-	GH.captureChildren = !GH.createdObj.empty();
+	assert(!ENGINE->createdObj.empty());
+	ENGINE->createdObj.pop_front();
+	ENGINE->captureChildren = !ENGINE->createdObj.empty();
 }
 
-void CGuiHandler::init()
+void GameEngine::init()
 {
 	inGuiThread = true;
 
@@ -63,40 +69,45 @@ void CGuiHandler::init()
 	shortcutsHandlerInstance = std::make_unique<ShortcutHandler>();
 	inputHandlerInstance = std::make_unique<InputHandler>(); // Must be after windowHandlerInstance and shortcutsHandlerInstance
 	framerateManagerInstance = std::make_unique<FramerateManager>(settings["video"]["targetfps"].Integer());
+
+#ifndef ENABLE_VIDEO
+	videoPlayerInstance = std::make_unique<CEmptyVideoPlayer>();
+#else
+	if (settings["session"]["disableVideo"].Bool())
+		videoPlayerInstance = std::make_unique<CEmptyVideoPlayer>();
+	else
+		videoPlayerInstance = std::make_unique<CVideoPlayer>();
+#endif
+
+	soundPlayerInstance = std::make_unique<CSoundHandler>();
+	musicPlayerInstance = std::make_unique<CMusicHandler>();
+	sound().setVolume((ui32)settings["general"]["sound"].Float());
+	music().setVolume((ui32)settings["general"]["music"].Float());
+	cursorHandlerInstance = std::make_unique<CursorHandler>();
 }
 
-void CGuiHandler::handleEvents()
+void GameEngine::handleEvents()
 {
 	events().dispatchTimer(framerate().getElapsedMilliseconds());
 
 	//player interface may want special event handling
-	if(nullptr != LOCPLINT && LOCPLINT->capturedAllEvents())
+	if(GAME->interface() && GAME->interface()->capturedAllEvents())
 		return;
 
 	input().processEvents();
 }
 
-void CGuiHandler::fakeMouseMove()
+void GameEngine::fakeMouseMove()
 {
 	dispatchMainThread([](){
-		GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
+		ENGINE->events().dispatchMouseMoved(Point(0, 0), ENGINE->getCursorPosition());
 	});
 }
 
-void CGuiHandler::startTextInput(const Rect & whereInput)
-{
-	input().startTextInput(whereInput);
-}
-
-void CGuiHandler::stopTextInput()
-{
-	input().stopTextInput();
-}
-
-void CGuiHandler::renderFrame()
+void GameEngine::renderFrame()
 {
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 		if (nullptr != curInt)
 			curInt->update();
@@ -107,21 +118,21 @@ void CGuiHandler::renderFrame()
 		screenHandlerInstance->updateScreenTexture();
 
 		windows().onFrameRendered();
-		CCS->curh->update();
+		ENGINE->cursor().update();
 	}
 
 	screenHandlerInstance->presentScreenTexture();
 	framerate().framerateDelay(); // holds a constant FPS
 }
 
-CGuiHandler::CGuiHandler()
+GameEngine::GameEngine()
 	: captureChildren(false)
 	, curInt(nullptr)
 	, fakeStatusBar(std::make_shared<EmptyStatusBar>())
 {
 }
 
-CGuiHandler::~CGuiHandler()
+GameEngine::~GameEngine()
 {
 	// enforce deletion order on shutdown
 	// all UI elements including adventure map must be destroyed before Gui Handler
@@ -129,51 +140,51 @@ CGuiHandler::~CGuiHandler()
 	adventureInt.reset();
 }
 
-ShortcutHandler & CGuiHandler::shortcuts()
+ShortcutHandler & GameEngine::shortcuts()
 {
 	assert(shortcutsHandlerInstance);
 	return *shortcutsHandlerInstance;
 }
 
-FramerateManager & CGuiHandler::framerate()
+FramerateManager & GameEngine::framerate()
 {
 	assert(framerateManagerInstance);
 	return *framerateManagerInstance;
 }
 
-bool CGuiHandler::isKeyboardCtrlDown() const
+bool GameEngine::isKeyboardCtrlDown() const
 {
 	return inputHandlerInstance->isKeyboardCtrlDown();
 }
 
-bool CGuiHandler::isKeyboardCmdDown() const
+bool GameEngine::isKeyboardCmdDown() const
 {
 	return inputHandlerInstance->isKeyboardCmdDown();
 }
 
-bool CGuiHandler::isKeyboardAltDown() const
+bool GameEngine::isKeyboardAltDown() const
 {
 	return inputHandlerInstance->isKeyboardAltDown();
 }
 
-bool CGuiHandler::isKeyboardShiftDown() const
+bool GameEngine::isKeyboardShiftDown() const
 {
 	return inputHandlerInstance->isKeyboardShiftDown();
 }
 
-const Point & CGuiHandler::getCursorPosition() const
+const Point & GameEngine::getCursorPosition() const
 {
 	return inputHandlerInstance->getCursorPosition();
 }
 
-Point CGuiHandler::screenDimensions() const
+Point GameEngine::screenDimensions() const
 {
 	return screenHandlerInstance->getLogicalResolution();
 }
 
-void CGuiHandler::drawFPSCounter()
+void GameEngine::drawFPSCounter()
 {
-	Canvas target = GH.screenHandler().getScreenCanvas();
+	Canvas target = screenHandler().getScreenCanvas();
 	Rect targetArea(0, screenDimensions().y - 20, 48, 11);
 	std::string fps = std::to_string(framerate().getFramerate())+" FPS";
 
@@ -181,43 +192,43 @@ void CGuiHandler::drawFPSCounter()
 	target.drawText(targetArea.center(), EFonts::FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, fps);
 }
 
-bool CGuiHandler::amIGuiThread()
+bool GameEngine::amIGuiThread()
 {
 	return inGuiThread;
 }
 
-void CGuiHandler::dispatchMainThread(const std::function<void()> & functor)
+void GameEngine::dispatchMainThread(const std::function<void()> & functor)
 {
 	inputHandlerInstance->dispatchMainThread(functor);
 }
 
-IScreenHandler & CGuiHandler::screenHandler()
+IScreenHandler & GameEngine::screenHandler()
 {
 	return *screenHandlerInstance;
 }
 
-IRenderHandler & CGuiHandler::renderHandler()
+IRenderHandler & GameEngine::renderHandler()
 {
 	return *renderHandlerInstance;
 }
 
-EventDispatcher & CGuiHandler::events()
+EventDispatcher & GameEngine::events()
 {
 	return *eventDispatcherInstance;
 }
 
-InputHandler & CGuiHandler::input()
+InputHandler & GameEngine::input()
 {
 	return *inputHandlerInstance;
 }
 
-WindowHandler & CGuiHandler::windows()
+WindowHandler & GameEngine::windows()
 {
 	assert(windowHandlerInstance);
 	return *windowHandlerInstance;
 }
 
-std::shared_ptr<IStatusBar> CGuiHandler::statusbar()
+std::shared_ptr<IStatusBar> GameEngine::statusbar()
 {
 	auto locked = currentStatusBar.lock();
 
@@ -227,16 +238,16 @@ std::shared_ptr<IStatusBar> CGuiHandler::statusbar()
 	return locked;
 }
 
-void CGuiHandler::setStatusbar(std::shared_ptr<IStatusBar> newStatusBar)
+void GameEngine::setStatusbar(std::shared_ptr<IStatusBar> newStatusBar)
 {
 	currentStatusBar = newStatusBar;
 }
 
-void CGuiHandler::onScreenResize(bool resolutionChanged)
+void GameEngine::onScreenResize(bool resolutionChanged)
 {
 	if(resolutionChanged)
 		screenHandler().onScreenResize();
 
 	windows().onScreenResize();
-	CCS->curh->onScreenResize();
+	ENGINE->cursor().onScreenResize();
 }

+ 19 - 9
client/gui/CGuiHandler.h → client/GameEngine.h

@@ -1,5 +1,5 @@
 /*
- * CGuiHandler.h, part of VCMI engine
+ * GameEngine.h, part of VCMI engine
  *
  * Authors: listed in file AUTHORS in main folder
  *
@@ -26,9 +26,12 @@ class IScreenHandler;
 class WindowHandler;
 class EventDispatcher;
 class InputHandler;
+class ISoundPlayer;
+class IMusicPlayer;
+class CursorHandler;
+class IVideoPlayer;
 
-// Handles GUI logic and drawing
-class CGuiHandler
+class GameEngine
 {
 private:
 	/// Fake no-op version status bar, for use in windows that have no status bar
@@ -46,6 +49,11 @@ private:
 	std::unique_ptr<EventDispatcher> eventDispatcherInstance;
 	std::unique_ptr<InputHandler> inputHandlerInstance;
 
+	std::unique_ptr<ISoundPlayer> soundPlayerInstance;
+	std::unique_ptr<IMusicPlayer> musicPlayerInstance;
+	std::unique_ptr<CursorHandler> cursorHandlerInstance;
+	std::unique_ptr<IVideoPlayer> videoPlayerInstance;
+
 public:
 	boost::mutex interfaceMutex;
 
@@ -57,6 +65,11 @@ public:
 	EventDispatcher & events();
 	InputHandler & input();
 
+	ISoundPlayer & sound() { return *soundPlayerInstance; }
+	IMusicPlayer & music() { return *musicPlayerInstance; }
+	CursorHandler & cursor() { return *cursorHandlerInstance; }
+	IVideoPlayer & video() { return *videoPlayerInstance; }
+
 	/// Returns current logical screen dimensions
 	/// May not match size of window if user has UI scaling different from 100%
 	Point screenDimensions() const;
@@ -74,9 +87,6 @@ public:
 	/// returns true if Shift is currently pressed down
 	bool isKeyboardShiftDown() const;
 
-	void startTextInput(const Rect & where);
-	void stopTextInput();
-
 	IScreenHandler & screenHandler();
 	IRenderHandler & renderHandler();
 	WindowHandler & windows();
@@ -92,8 +102,8 @@ public:
 	bool captureChildren; //all newly created objects will get their parents from stack and will be added to parents children list
 	std::list<CIntObject *> createdObj; //stack of objs being created
 
-	CGuiHandler();
-	~CGuiHandler();
+	GameEngine();
+	~GameEngine();
 
 	void init();
 	void renderFrame();
@@ -111,4 +121,4 @@ public:
 	void dispatchMainThread(const std::function<void()> & functor);
 };
 
-extern CGuiHandler GH; //global gui handler
+extern std::unique_ptr<GameEngine> ENGINE; //global gui handler

+ 60 - 0
client/GameInstance.cpp

@@ -0,0 +1,60 @@
+/*
+ * GameInstance.cpp, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#include "StdInc.h"
+#include "GameInstance.h"
+
+#include "CServerHandler.h"
+#include "mapView/mapHandler.h"
+
+std::unique_ptr<GameInstance> GAME = nullptr;
+
+GameInstance::GameInstance()
+	: serverInstance(std::make_unique<CServerHandler>())
+	, interfaceInstance(nullptr)
+{
+}
+
+GameInstance::~GameInstance() = default;
+
+CServerHandler & GameInstance::server()
+{
+	if (!serverInstance)
+		throw std::runtime_error("Invalid access to GameInstance::server");
+
+	return *serverInstance;
+}
+
+CMapHandler & GameInstance::map()
+{
+	if (!mapInstance)
+		throw std::runtime_error("Invalid access to GameInstance::map");
+
+	return *mapInstance;
+}
+
+CPlayerInterface * GameInstance::interface()
+{
+	return interfaceInstance;
+}
+
+void GameInstance::setServerInstance(std::unique_ptr<CServerHandler> ptr)
+{
+	serverInstance = std::move(ptr);
+}
+
+void GameInstance::setMapInstance(std::unique_ptr<CMapHandler> ptr)
+{
+	mapInstance = std::move(ptr);
+}
+
+void GameInstance::setInterfaceInstance(CPlayerInterface * ptr)
+{
+	interfaceInstance = std::move(ptr);
+}

+ 41 - 0
client/GameInstance.h

@@ -0,0 +1,41 @@
+/*
+ * GameInstance.h, part of VCMI engine
+ *
+ * Authors: listed in file AUTHORS in main folder
+ *
+ * License: GNU General Public License v2.0 or later
+ * Full text of license available in license.txt file, in main folder
+ *
+ */
+#pragma once
+
+class CServerHandler;
+class GlobalLobbyClient;
+class CPlayerInterface;
+class CMapHandler;
+
+VCMI_LIB_NAMESPACE_BEGIN
+class INetworkHandler;
+VCMI_LIB_NAMESPACE_END
+
+class GameInstance : boost::noncopyable
+{
+	std::unique_ptr<CServerHandler> serverInstance;
+	std::unique_ptr<CMapHandler> mapInstance;
+	CPlayerInterface * interfaceInstance;
+
+public:
+	GameInstance();
+	~GameInstance();
+
+	CServerHandler & server();
+	CMapHandler & map();
+
+	CPlayerInterface * interface();
+
+	void setServerInstance(std::unique_ptr<CServerHandler> ptr);
+	void setMapInstance(std::unique_ptr<CMapHandler> ptr);
+	void setInterfaceInstance(CPlayerInterface * ptr);
+};
+
+extern std::unique_ptr<GameInstance> GAME;

+ 40 - 40
client/HeroMovementController.cpp

@@ -10,12 +10,12 @@
 #include "StdInc.h"
 #include "HeroMovementController.h"
 
-#include "CGameInfo.h"
 #include "CPlayerInterface.h"
 #include "PlayerLocalState.h"
 #include "adventureMap/AdventureMapInterface.h"
 #include "eventsSDL/InputHandler.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/CursorHandler.h"
 #include "mapView/mapHandler.h"
 #include "media/ISoundPlayer.h"
@@ -36,10 +36,10 @@ bool HeroMovementController::isHeroMovingThroughGarrison(const CGHeroInstance *
 	if(!duringMovement)
 		return false;
 
-	if(!LOCPLINT->localState->hasPath(hero))
+	if(!GAME->interface()->localState->hasPath(hero))
 		return false;
 
-	if(garrison->visitableAt(LOCPLINT->localState->getPath(hero).lastNode().coord))
+	if(garrison->visitableAt(GAME->interface()->localState->getPath(hero).lastNode().coord))
 		return false; // hero want to enter garrison, not pass through it
 
 	return true;
@@ -70,7 +70,7 @@ void HeroMovementController::showTeleportDialog(const CGHeroInstance * hero, Tel
 {
 	if (impassable || exits.empty()) //FIXME: why we even have this dialog in such case?
 	{
-		LOCPLINT->cb->selectionMade(-1, askID);
+		GAME->interface()->cb->selectionMade(-1, askID);
 		return;
 	}
 
@@ -80,14 +80,14 @@ void HeroMovementController::showTeleportDialog(const CGHeroInstance * hero, Tel
 	assert(waitingForQueryApplyReply == false);
 	waitingForQueryApplyReply = true;
 
-	if(!LOCPLINT->localState->hasPath(hero))
+	if(!GAME->interface()->localState->hasPath(hero))
 	{
 		// Hero enters teleporter without specifying exit - select it randomly
-		LOCPLINT->cb->selectionMade(-1, askID);
+		GAME->interface()->cb->selectionMade(-1, askID);
 		return;
 	}
 
-	const auto & heroPath = LOCPLINT->localState->getPath(hero);
+	const auto & heroPath = GAME->interface()->localState->getPath(hero);
 	const auto & nextNode = heroPath.nextNode();
 
 	for(size_t i = 0; i < exits.size(); ++i)
@@ -95,15 +95,15 @@ void HeroMovementController::showTeleportDialog(const CGHeroInstance * hero, Tel
 		if(exits[i].second == nextNode.coord)
 		{
 			// Remove this node from path - it will be covered by teleportation
-			//LOCPLINT->localState->removeLastNode(hero);
-			LOCPLINT->cb->selectionMade(i, askID);
+			//GAME->interface()->localState->removeLastNode(hero);
+			GAME->interface()->cb->selectionMade(i, askID);
 			return;
 		}
 	}
 
 	// may happen when hero has path but does not moves alongside it
 	// for example, while standing on teleporter set path that does not leads throught teleporter and press space
-	LOCPLINT->cb->selectionMade(-1, askID);
+	GAME->interface()->cb->selectionMade(-1, askID);
 	return;
 }
 
@@ -112,17 +112,17 @@ void HeroMovementController::updatePath(const CGHeroInstance * hero, const TryMo
 	// Once hero moved (or attempted to move) we need to update path
 	// to make sure that it is still valid or remove it completely if destination has been reached
 
-	if(hero->tempOwner != LOCPLINT->playerID)
+	if(hero->tempOwner != GAME->interface()->playerID)
 		return;
 
-	if(!LOCPLINT->localState->hasPath(hero))
+	if(!GAME->interface()->localState->hasPath(hero))
 		return; // may happen when hero teleports
 
-	assert(LOCPLINT->makingTurn);
+	assert(GAME->interface()->makingTurn);
 
-	bool directlyAttackingCreature = details.attackedFrom.has_value() && LOCPLINT->localState->getPath(hero).lastNode().coord == details.attackedFrom;
+	bool directlyAttackingCreature = details.attackedFrom.has_value() && GAME->interface()->localState->getPath(hero).lastNode().coord == details.attackedFrom;
 
-	int3 desiredTarget = LOCPLINT->localState->getPath(hero).nextNode().coord;
+	int3 desiredTarget = GAME->interface()->localState->getPath(hero).nextNode().coord;
 	int3 actualTarget = hero->convertToVisitablePos(details.end);
 
 	//don't erase path when revisiting with spacebar
@@ -134,16 +134,16 @@ void HeroMovementController::updatePath(const CGHeroInstance * hero, const TryMo
 		{
 			//invalidate path - movement was not along current path
 			//possible reasons: teleport, visit of object with "blocking visit" property
-			LOCPLINT->localState->erasePath(hero);
+			GAME->interface()->localState->erasePath(hero);
 		}
 		else
 		{
 			//movement along desired path - remove one node and keep rest of path
-			LOCPLINT->localState->removeLastNode(hero);
+			GAME->interface()->localState->removeLastNode(hero);
 		}
 
 		if(directlyAttackingCreature)
-			LOCPLINT->localState->erasePath(hero);
+			GAME->interface()->localState->erasePath(hero);
 	}
 }
 
@@ -154,18 +154,18 @@ void HeroMovementController::onTryMoveHero(const CGHeroInstance * hero, const Tr
 
 	if(details.result == TryMoveHero::EMBARK || details.result == TryMoveHero::DISEMBARK)
 	{
-		if (hero->tempOwner == LOCPLINT->playerID)
+		if (hero->tempOwner == GAME->interface()->playerID)
 		{
 			auto removalSound = hero->getRemovalSound(CRandomGenerator::getDefault());
 			if (removalSound)
-				CCS->soundh->playSound(removalSound.value());
+				ENGINE->sound().playSound(removalSound.value());
 		}
 	}
 
 	bool directlyAttackingCreature =
 		details.attackedFrom.has_value() &&
-		LOCPLINT->localState->hasPath(hero) &&
-		LOCPLINT->localState->getPath(hero).lastNode().coord == details.attackedFrom;
+		GAME->interface()->localState->hasPath(hero) &&
+		GAME->interface()->localState->getPath(hero).lastNode().coord == details.attackedFrom;
 
 	std::unordered_set<int3> changedTiles {
 		hero->convertToVisitablePos(details.start),
@@ -185,7 +185,7 @@ void HeroMovementController::onTryMoveHero(const CGHeroInstance * hero, const Tr
 
 	// We are in network thread
 	// Block netpack processing until movement animation is over
-	CGI->mh->waitForOngoingAnimations();
+	GAME->map().waitForOngoingAnimations();
 
 	//move finished
 	adventureInt->onHeroChanged(hero);
@@ -235,15 +235,15 @@ void HeroMovementController::onMoveHeroApplied()
 	if(waitingForQueryApplyReply)
 		return;
 
-	if(GH.input().ignoreEventsUntilInput())
+	if(ENGINE->input().ignoreEventsUntilInput())
 		stoppingMovement = true;
 
 	assert(currentlyMovingHero);
 	const auto * hero = currentlyMovingHero;
 
-	bool canMove = LOCPLINT->localState->hasPath(hero) && LOCPLINT->localState->getPath(hero).nextNode().turns == 0 && !LOCPLINT->showingDialog->isBusy();
+	bool canMove = GAME->interface()->localState->hasPath(hero) && GAME->interface()->localState->getPath(hero).nextNode().turns == 0 && !GAME->interface()->showingDialog->isBusy();
 	bool wantStop = stoppingMovement;
-	bool canStop = !canMove || canHeroStopAtNode(LOCPLINT->localState->getPath(hero).currNode());
+	bool canStop = !canMove || canHeroStopAtNode(GAME->interface()->localState->getPath(hero).currNode());
 
 	if(!canMove || (wantStop && canStop))
 	{
@@ -251,7 +251,7 @@ void HeroMovementController::onMoveHeroApplied()
 	}
 	else
 	{
-		sendMovementRequest(hero, LOCPLINT->localState->getPath(hero));
+		sendMovementRequest(hero, GAME->interface()->localState->getPath(hero));
 	}
 }
 
@@ -270,7 +270,7 @@ void HeroMovementController::endMove(const CGHeroInstance * hero)
 	currentlyMovingHero = nullptr;
 	stopMovementSound();
 	adventureInt->onHeroChanged(hero);
-	CCS->curh->show();
+	ENGINE->cursor().show();
 }
 
 AudioPath HeroMovementController::getMovementSoundFor(const CGHeroInstance * hero, int3 posPrev, int3 posNext, EPathNodeAction moveType)
@@ -288,8 +288,8 @@ AudioPath HeroMovementController::getMovementSoundFor(const CGHeroInstance * her
 	if(hero->hasBonusOfType(BonusType::FLYING_MOVEMENT))
 		return AudioPath::builtin("HORSE10.wav");
 
-	auto prevTile = LOCPLINT->cb->getTile(posPrev);
-	auto nextTile = LOCPLINT->cb->getTile(posNext);
+	auto prevTile = GAME->interface()->cb->getTile(posPrev);
+	auto nextTile = GAME->interface()->cb->getTile(posNext);
 
 	bool movingOnRoad = prevTile->hasRoad() && nextTile->hasRoad();
 
@@ -309,10 +309,10 @@ void HeroMovementController::updateMovementSound(const CGHeroInstance * h, int3
 		currentMovementSoundName = newSoundName;
 
 		if(currentMovementSoundChannel != -1)
-			CCS->soundh->stopSound(currentMovementSoundChannel);
+			ENGINE->sound().stopSound(currentMovementSoundChannel);
 
 		if(!currentMovementSoundName.empty())
-			currentMovementSoundChannel = CCS->soundh->playSound(currentMovementSoundName, -1, true);
+			currentMovementSoundChannel = ENGINE->sound().playSound(currentMovementSoundName, -1, true);
 		else
 			currentMovementSoundChannel = -1;
 	}
@@ -321,7 +321,7 @@ void HeroMovementController::updateMovementSound(const CGHeroInstance * h, int3
 void HeroMovementController::stopMovementSound()
 {
 	if(currentMovementSoundChannel != -1)
-		CCS->soundh->stopSound(currentMovementSoundChannel);
+		ENGINE->sound().stopSound(currentMovementSoundChannel);
 	currentMovementSoundChannel = -1;
 	currentMovementSoundName = AudioPath();
 }
@@ -344,7 +344,7 @@ void HeroMovementController::requestMovementStart(const CGHeroInstance * h, cons
 	duringMovement = true;
 	currentlyMovingHero = h;
 
-	CCS->curh->hide();
+	ENGINE->cursor().hide();
 	sendMovementRequest(h, path);
 }
 
@@ -365,7 +365,7 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
 	{
 		stopMovementSound();
 		logGlobal->trace("Requesting hero teleportation to %s", nextNode.coord.toString());
-		LOCPLINT->cb->moveHero(h, h->pos, false);
+		GAME->interface()->cb->moveHero(h, h->pos, false);
 		return;
 	}
 
@@ -380,7 +380,7 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
 		bool useTransit = nextNode.layer == EPathfindingLayer::AIR || nextNode.layer == EPathfindingLayer::WATER;
 		int3 nextCoord = h->convertFromVisitablePos(nextNode.coord);
 
-		LOCPLINT->cb->moveHero(h, nextCoord, useTransit);
+		GAME->interface()->cb->moveHero(h, nextCoord, useTransit);
 		return;
 	}
 
@@ -405,10 +405,10 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
 		int3 coord = h->convertFromVisitablePos(node.coord);
 		pathToMove.push_back(coord);
 
-		if (LOCPLINT->cb->guardingCreaturePosition(node.coord) != int3(-1, -1, -1))
+		if (GAME->interface()->cb->guardingCreaturePosition(node.coord) != int3(-1, -1, -1))
 			break; // we reached zone-of-control of wandering monster
 
-		if (!LOCPLINT->cb->getVisitableObjs(node.coord).empty())
+		if (!GAME->interface()->cb->getVisitableObjs(node.coord).empty())
 			break; // we reached event, garrison or some other visitable object - end this movement batch
 	}
 
@@ -416,6 +416,6 @@ void HeroMovementController::sendMovementRequest(const CGHeroInstance * h, const
 	if (!pathToMove.empty())
 	{
 		updateMovementSound(h, currNode.coord, nextNode.coord, nextNode.action);
-		LOCPLINT->cb->moveHero(h, pathToMove, useTransitAtStart);
+		GAME->interface()->cb->moveHero(h, pathToMove, useTransitAtStart);
 	}
 }

+ 57 - 81
client/NetPacksClient.cpp

@@ -12,7 +12,6 @@
 
 #include "Client.h"
 #include "CPlayerInterface.h"
-#include "CGameInfo.h"
 #include "windows/GUIClasses.h"
 #include "windows/CCastleInterface.h"
 #include "mapView/mapHandler.h"
@@ -20,7 +19,8 @@
 #include "adventureMap/CInGameConsole.h"
 #include "battle/BattleInterface.h"
 #include "battle/BattleWindow.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/WindowHandler.h"
 #include "widgets/MiscWidgets.h"
 #include "CMT.h"
@@ -32,7 +32,7 @@
 #include "../lib/filesystem/FileInfo.h"
 #include "../lib/serializer/Connection.h"
 #include "../lib/texts/CGeneralTextHandler.h"
-#include "../lib/VCMI_Lib.h"
+#include "../lib/GameLibrary.h"
 #include "../lib/mapping/CMap.h"
 #include "../lib/VCMIDirs.h"
 #include "../lib/spells/CSpellHandler.h"
@@ -109,7 +109,7 @@ void callBattleInterfaceIfPresentForBothSides(CClient & cl, const BattleID & bat
 
 	callOnlyThatBattleInterface(cl, cl.gameState()->getBattle(battleID)->getSide(BattleSide::ATTACKER).color, ptr, std::forward<Args2>(args)...);
 	callOnlyThatBattleInterface(cl, cl.gameState()->getBattle(battleID)->getSide(BattleSide::DEFENDER).color, ptr, std::forward<Args2>(args)...);
-	if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool() && LOCPLINT->battleInt)
+	if(settings["session"]["spectate"].Bool() && !settings["session"]["spectate-skip-battle"].Bool() && GAME->interface()->battleInt)
 	{
 		callOnlyThatBattleInterface(cl, PlayerColor::SPECTATOR, ptr, std::forward<Args2>(args)...);
 	}
@@ -161,7 +161,7 @@ void ApplyClientNetPackVisitor::visitSetMana(SetMana & pack)
 	if(settings["session"]["headless"].Bool())
 		return;
 
-	for(auto window : GH.windows().findWindows<BattleWindow>())
+	for(auto window : ENGINE->windows().findWindows<BattleWindow>())
 		window->heroManaPointsChanged(h);
 }
 
@@ -173,7 +173,7 @@ void ApplyClientNetPackVisitor::visitSetMovePoints(SetMovePoints & pack)
 
 void ApplyClientNetPackVisitor::visitSetResearchedSpells(SetResearchedSpells & pack)
 {
-	for(const auto & win : GH.windows().findWindows<CMageGuildScreen>())
+	for(const auto & win : ENGINE->windows().findWindows<CMageGuildScreen>())
 		win->updateSpells(pack.tid);
 }
 
@@ -181,9 +181,9 @@ void ApplyClientNetPackVisitor::visitFoWChange(FoWChange & pack)
 {
 	for(auto &i : cl.playerint)
 	{
-		if(cl.getPlayerRelations(i.first, pack.player) == PlayerRelations::SAME_PLAYER && pack.waitForDialogs && LOCPLINT == i.second.get())
+		if(cl.getPlayerRelations(i.first, pack.player) == PlayerRelations::SAME_PLAYER && pack.waitForDialogs && GAME->interface() == i.second.get())
 		{
-			LOCPLINT->waitWhileDialog();
+			GAME->interface()->waitWhileDialog();
 		}
 		if(cl.getPlayerRelations(i.first, pack.player) != PlayerRelations::ENEMIES)
 		{
@@ -382,21 +382,15 @@ void ApplyClientNetPackVisitor::visitGiveBonus(GiveBonus & pack)
 void ApplyFirstClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
 {
 	CGObjectInstance *obj = gs.getObjInstance(pack.objid);
-	if(CGI && CGI->mh)
-	{
-		CGI->mh->onObjectFadeOut(obj, pack.initiator);
-		CGI->mh->waitForOngoingAnimations();
-	}
+	GAME->map().onObjectFadeOut(obj, pack.initiator);
+	GAME->map().waitForOngoingAnimations();
 }
 
 void ApplyClientNetPackVisitor::visitChangeObjPos(ChangeObjPos & pack)
 {
 	CGObjectInstance *obj = gs.getObjInstance(pack.objid);
-	if(CGI && CGI->mh)
-	{
-		CGI->mh->onObjectFadeIn(obj, pack.initiator);
-		CGI->mh->waitForOngoingAnimations();
-	}
+	GAME->map().onObjectFadeIn(obj, pack.initiator);
+	GAME->map().waitForOngoingAnimations();
 	callAllInterfaces(cl, &CGameInterface::invalidatePaths);
 }
 
@@ -405,18 +399,18 @@ void ApplyClientNetPackVisitor::visitPlayerEndsGame(PlayerEndsGame & pack)
 	callAllInterfaces(cl, &IGameEventsReceiver::gameOver, pack.player, pack.victoryLossCheckResult);
 
 	bool localHumanWinsGame = vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && pack.victoryLossCheckResult.victory();
-	bool lastHumanEndsGame = CSH->howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
+	bool lastHumanEndsGame = GAME->server().howManyPlayerInterfaces() == 1 && vstd::contains(cl.playerint, pack.player) && cl.getPlayerState(pack.player)->human && !settings["session"]["spectate"].Bool();
 
 	if(lastHumanEndsGame || localHumanWinsGame)
 	{
 		assert(adventureInt);
 		if(adventureInt)
 		{
-			GH.windows().popWindows(GH.windows().count());
+			ENGINE->windows().popWindows(ENGINE->windows().count());
 			adventureInt.reset();
 		}
 
-		CSH->showHighScoresAndEndGameplay(pack.player, pack.victoryLossCheckResult.victory(), pack.statistic);
+		GAME->server().showHighScoresAndEndGameplay(pack.player, pack.victoryLossCheckResult.victory(), pack.statistic);
 	}
 
 	// In auto testing pack.mode we always close client if red pack.player won or lose
@@ -446,14 +440,14 @@ void ApplyClientNetPackVisitor::visitPlayerReinitInterface(PlayerReinitInterface
 	
 	for(auto player : pack.players)
 	{
-		auto & plSettings = CSH->si->getIthPlayersSettings(player);
+		auto & plSettings = GAME->server().si->getIthPlayersSettings(player);
 		if(pack.playerConnectionId == PlayerSettings::PLAYER_AI)
 		{
 			plSettings.connectedPlayerIDs.clear();
 			cl.initPlayerEnvironments();
 			initInterfaces();
 		}
-		else if(pack.playerConnectionId == CSH->logicConnection->connectionID)
+		else if(pack.playerConnectionId == GAME->server().logicConnection->connectionID)
 		{
 			plSettings.connectedPlayerIDs.insert(pack.playerConnectionId);
 			cl.playerint.clear();
@@ -486,8 +480,7 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
 {
 	const CGObjectInstance *o = cl.getObj(pack.objectID);
 
-	if(CGI->mh)
-		CGI->mh->onObjectFadeOut(o, pack.initiator);
+	GAME->map().onObjectFadeOut(o, pack.initiator);
 
 	//notify interfaces about removal
 	for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
@@ -498,8 +491,7 @@ void ApplyFirstClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
 			i->second->objectRemoved(o, pack.initiator);
 	}
 
-	if(CGI->mh)
-		CGI->mh->waitForOngoingAnimations();
+	GAME->map().waitForOngoingAnimations();
 }
 
 void ApplyClientNetPackVisitor::visitRemoveObject(RemoveObject & pack)
@@ -514,21 +506,17 @@ void ApplyFirstClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 {
 	CGHeroInstance *h = gs.getHero(pack.id);
 
-	if(CGI->mh)
+	switch (pack.result)
 	{
-		switch (pack.result)
-		{
-			case TryMoveHero::EMBARK:
-				CGI->mh->onBeforeHeroEmbark(h, pack.start, pack.end);
-				break;
-			case TryMoveHero::TELEPORTATION:
-				CGI->mh->onBeforeHeroTeleported(h, pack.start, pack.end);
-				break;
-			case TryMoveHero::DISEMBARK:
-				CGI->mh->onBeforeHeroDisembark(h, pack.start, pack.end);
-				break;
-		}
-		CGI->mh->waitForOngoingAnimations();
+		case TryMoveHero::EMBARK:
+			GAME->map().onBeforeHeroEmbark(h, pack.start, pack.end);
+			break;
+		case TryMoveHero::TELEPORTATION:
+			GAME->map().onBeforeHeroTeleported(h, pack.start, pack.end);
+			break;
+		case TryMoveHero::DISEMBARK:
+			GAME->map().onBeforeHeroDisembark(h, pack.start, pack.end);
+			break;
 	}
 }
 
@@ -537,23 +525,20 @@ void ApplyClientNetPackVisitor::visitTryMoveHero(TryMoveHero & pack)
 	const CGHeroInstance *h = cl.getHero(pack.id);
 	callAllInterfaces(cl, &CGameInterface::invalidatePaths);
 
-	if(CGI->mh)
+	switch(pack.result)
 	{
-		switch(pack.result)
-		{
-			case TryMoveHero::SUCCESS:
-				CGI->mh->onHeroMoved(h, pack.start, pack.end);
-				break;
-			case TryMoveHero::EMBARK:
-				CGI->mh->onAfterHeroEmbark(h, pack.start, pack.end);
-				break;
-			case TryMoveHero::TELEPORTATION:
-				CGI->mh->onAfterHeroTeleported(h, pack.start, pack.end);
-				break;
-			case TryMoveHero::DISEMBARK:
-				CGI->mh->onAfterHeroDisembark(h, pack.start, pack.end);
-				break;
-		}
+		case TryMoveHero::SUCCESS:
+			GAME->map().onHeroMoved(h, pack.start, pack.end);
+			break;
+		case TryMoveHero::EMBARK:
+			GAME->map().onAfterHeroEmbark(h, pack.start, pack.end);
+			break;
+		case TryMoveHero::TELEPORTATION:
+			GAME->map().onAfterHeroTeleported(h, pack.start, pack.end);
+			break;
+		case TryMoveHero::DISEMBARK:
+			GAME->map().onAfterHeroDisembark(h, pack.start, pack.end);
+			break;
 	}
 
 	PlayerColor player = h->tempOwner;
@@ -586,12 +571,10 @@ void ApplyClientNetPackVisitor::visitNewStructures(NewStructures & pack)
 	}
 
 	// invalidate section of map view with our object and force an update
-	if(CGI->mh)
-	{
-		CGI->mh->onObjectInstantRemove(town, town->getOwner());
-		CGI->mh->onObjectInstantAdd(town, town->getOwner());
-	}
+	GAME->map().onObjectInstantRemove(town, town->getOwner());
+	GAME->map().onObjectInstantAdd(town, town->getOwner());
 }
+
 void ApplyClientNetPackVisitor::visitRazeStructures(RazeStructures & pack)
 {
 	CGTownInstance * town = gs.getTown(pack.tid);
@@ -601,11 +584,8 @@ void ApplyClientNetPackVisitor::visitRazeStructures(RazeStructures & pack)
 	}
 
 	// invalidate section of map view with our object and force an update
-	if(CGI->mh)
-	{
-		CGI->mh->onObjectInstantRemove(town, town->getOwner());
-		CGI->mh->onObjectInstantAdd(town, town->getOwner());
-	}
+	GAME->map().onObjectInstantRemove(town, town->getOwner());
+	GAME->map().onObjectInstantAdd(town, town->getOwner());
 }
 
 void ApplyClientNetPackVisitor::visitSetAvailableCreatures(SetAvailableCreatures & pack)
@@ -655,15 +635,13 @@ void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
 		if(const CGTownInstance *t = gs.getTown(pack.tid))
 			callInterfaceIfPresent(cl, h->getOwner(), &IGameEventsReceiver::heroInGarrisonChange, t);
 	}
-	if(CGI->mh)
-		CGI->mh->onObjectInstantAdd(h, h->getOwner());
+	GAME->map().onObjectInstantAdd(h, h->getOwner());
 }
 
 void ApplyClientNetPackVisitor::visitGiveHero(GiveHero & pack)
 {
 	CGHeroInstance *h = gs.getHero(pack.id);
-	if(CGI->mh)
-		CGI->mh->onObjectInstantAdd(h, h->getOwner());
+	GAME->map().onObjectInstantAdd(h, h->getOwner());
 	callInterfaceIfPresent(cl, h->tempOwner, &IGameEventsReceiver::heroCreated, h);
 }
 
@@ -689,10 +667,10 @@ void ApplyFirstClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty &
 	}
 
 	// invalidate section of map view with our object and force an update with new flag color
-	if(pack.what == ObjProperty::OWNER && CGI->mh)
+	if(pack.what == ObjProperty::OWNER)
 	{
 		auto object = gs.getObjInstance(pack.id);
-		CGI->mh->onObjectInstantRemove(object, object->getOwner());
+		GAME->map().onObjectInstantRemove(object, object->getOwner());
 	}
 }
 
@@ -706,10 +684,10 @@ void ApplyClientNetPackVisitor::visitSetObjectProperty(SetObjectProperty & pack)
 	}
 
 	// invalidate section of map view with our object and force an update with new flag color
-	if(pack.what == ObjProperty::OWNER && CGI->mh)
+	if(pack.what == ObjProperty::OWNER)
 	{
 		auto object = gs.getObjInstance(pack.id);
-		CGI->mh->onObjectInstantAdd(object, object->getOwner());
+		GAME->map().onObjectInstantAdd(object, object->getOwner());
 	}
 }
 
@@ -913,7 +891,7 @@ void ApplyClientNetPackVisitor::visitSystemMessage(SystemMessage & pack)
 	// usually used to receive error messages from server
 	logNetwork->error("System message: %s", pack.text.toString());
 
-	CSH->getGameChat().onNewSystemMessageReceived(pack.text.toString());
+	GAME->server().getGameChat().onNewSystemMessageReceived(pack.text.toString());
 }
 
 void ApplyClientNetPackVisitor::visitPlayerBlocked(PlayerBlocked & pack)
@@ -945,7 +923,7 @@ void ApplyClientNetPackVisitor::visitPlayerMessageClient(PlayerMessageClient & p
 {
 	logNetwork->debug("pack.player %s sends a message: %s", pack.player.toString(), pack.text);
 
-	CSH->getGameChat().onNewGameMessageReceived(pack.player, pack.text);
+	GAME->server().getGameChat().onNewGameMessageReceived(pack.player, pack.text);
 }
 
 void ApplyClientNetPackVisitor::visitAdvmapSpellCast(AdvmapSpellCast & pack)
@@ -1046,8 +1024,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
 	callAllInterfaces(cl, &CGameInterface::invalidatePaths);
 
 	const CGObjectInstance *obj = pack.newObject;
-	if(CGI->mh)
-		CGI->mh->onObjectFadeIn(obj, pack.initiator);
+	GAME->map().onObjectFadeIn(obj, pack.initiator);
 
 	for(auto i=cl.playerint.begin(); i!=cl.playerint.end(); i++)
 	{
@@ -1055,8 +1032,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
 			i->second->newObject(obj);
 	}
 
-	if(CGI->mh)
-		CGI->mh->waitForOngoingAnimations();
+	GAME->map().waitForOngoingAnimations();
 }
 
 void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts & pack)

+ 21 - 21
client/NetPacksLobbyClient.cpp

@@ -25,9 +25,9 @@
 
 #include "CServerHandler.h"
 #include "GameChatHandler.h"
-#include "CGameInfo.h"
 #include "Client.h"
-#include "gui/CGuiHandler.h"
+#include "GameEngine.h"
+#include "GameInstance.h"
 #include "gui/WindowHandler.h"
 #include "widgets/Buttons.h"
 #include "widgets/TextControls.h"
@@ -55,10 +55,10 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
 		}
 		else if(!settings["session"]["headless"].Bool())
 		{
-			if (GH.windows().topWindow<CSimpleJoinScreen>())
-				GH.windows().popWindows(1);
+			if (ENGINE->windows().topWindow<CSimpleJoinScreen>())
+				ENGINE->windows().popWindows(1);
 
-			if (!GH.windows().findWindows<GlobalLobbyServerSetup>().empty())
+			if (!ENGINE->windows().findWindows<GlobalLobbyServerSetup>().empty())
 			{
 				assert(handler.serverMode == EServerMode::LOBBY_HOST);
 				// announce opened game room
@@ -72,14 +72,14 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientCon
 					handler.getGlobalLobby().sendOpenRoom("public", roomPlayerLimit);
 			}
 
-			while (!GH.windows().findWindows<GlobalLobbyWindow>().empty())
+			while (!ENGINE->windows().findWindows<GlobalLobbyWindow>().empty())
 			{
 				// if global lobby is open, pop all dialogs on top of it as well as lobby itself
-				GH.windows().popWindows(1);
+				ENGINE->windows().popWindows(1);
 			}
 
 			bool hideScreen = handler.campaignStateToSend && (!handler.campaignStateToSend->campaignSet.empty() || handler.campaignStateToSend->lastScenario());
-			GH.windows().createAndPushWindow<CLobbyScreen>(handler.screenType, hideScreen);
+			ENGINE->windows().createAndPushWindow<CLobbyScreen>(handler.screenType, hideScreen);
 		}
 		handler.setState(EClientState::LOBBY);
 	}
@@ -96,11 +96,11 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientDisconnected(LobbyClient
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
 {
-	if(auto w = GH.windows().topWindow<CLoadingScreen>())
-		GH.windows().popWindow(w);
+	if(auto w = ENGINE->windows().topWindow<CLoadingScreen>())
+		ENGINE->windows().popWindow(w);
 	
-	if(GH.windows().count() > 0)
-		GH.windows().popWindows(1);
+	if(ENGINE->windows().count() > 0)
+		ENGINE->windows().popWindows(1);
 }
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyChatMessage(LobbyChatMessage & pack)
@@ -171,7 +171,7 @@ void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pac
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
 {
-	if(auto w = GH.windows().topWindow<CLoadingScreen>())
+	if(auto w = ENGINE->windows().topWindow<CLoadingScreen>())
 	{
 		w->finish();
 		w->tick(0);
@@ -181,7 +181,7 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbyLoadProgress(LobbyLoadProgress & pack)
 {
-	if(auto w = GH.windows().topWindow<CLoadingScreen>())
+	if(auto w = ENGINE->windows().topWindow<CLoadingScreen>())
 	{
 		w->set(pack.progress);
 		w->tick(0);
@@ -209,17 +209,17 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState &
 	{
 		auto bonusSel = std::make_shared<CBonusSelection>();
 		lobby->bonusSel = bonusSel;
-		if(!handler.si->campState->conqueredScenarios().size() && !handler.si->campState->getIntroVideo().empty() && CCS->videoh->open(handler.si->campState->getIntroVideo(), 1))
+		if(!handler.si->campState->conqueredScenarios().size() && !handler.si->campState->getIntroVideo().empty() && ENGINE->video().open(handler.si->campState->getIntroVideo(), 1))
 		{
-			CCS->musich->stopMusic();
-			GH.windows().createAndPushWindow<VideoWindow>(handler.si->campState->getIntroVideo(), handler.si->campState->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : handler.si->campState->getVideoRim(), false, 1, [bonusSel](bool skipped){
-				if(!CSH->si->campState->getMusic().empty())
-					CCS->musich->playMusic(CSH->si->campState->getMusic(), true, false);
-				GH.windows().pushWindow(bonusSel);
+			ENGINE->music().stopMusic();
+			ENGINE->windows().createAndPushWindow<VideoWindow>(handler.si->campState->getIntroVideo(), handler.si->campState->getVideoRim().empty() ? ImagePath::builtin("INTRORIM") : handler.si->campState->getVideoRim(), false, 1, [bonusSel](bool skipped){
+				if(!GAME->server().si->campState->getMusic().empty())
+					ENGINE->music().playMusic(GAME->server().si->campState->getMusic(), true, false);
+				ENGINE->windows().pushWindow(bonusSel);
 			});
 		}
 		else
-			GH.windows().pushWindow(bonusSel);
+			ENGINE->windows().pushWindow(bonusSel);
 	}
 
 	if(lobby->bonusSel)

+ 134 - 134
client/adventureMap/AdventureMapInterface.cpp

@@ -25,9 +25,9 @@
 #include "../mapView/MapView.h"
 #include "../windows/InfoWindows.h"
 #include "../widgets/RadialMenu.h"
-#include "../CGameInfo.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../render/Canvas.h"
@@ -61,8 +61,8 @@ AdventureMapInterface::AdventureMapInterface():
 {
 	OBJECT_CONSTRUCTION;
 	pos.x = pos.y = 0;
-	pos.w = GH.screenDimensions().x;
-	pos.h = GH.screenDimensions().y;
+	pos.w = ENGINE->screenDimensions().x;
+	pos.h = ENGINE->screenDimensions().y;
 
 	shortcuts = std::make_shared<AdventureMapShortcuts>(*this);
 
@@ -70,7 +70,7 @@ AdventureMapInterface::AdventureMapInterface():
 	shortcuts->setState(EAdventureState::MAKING_TURN);
 	widget->getMapView()->onViewMapActivated();
 
-	if(LOCPLINT->cb->getStartInfo()->turnTimerInfo.turnTimer != 0)
+	if(GAME->interface()->cb->getStartInfo()->turnTimerInfo.turnTimer != 0)
 		watches = std::make_shared<TurnTimerWidget>(Point(24, 24));
 	
 	addUsedEvents(KEYBOARD | TIME);
@@ -106,7 +106,7 @@ void AdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
 {
 	widget->getHeroList()->updateElement(h);
 
-	if (h && h == LOCPLINT->localState->getCurrentHero() && !widget->getInfoBar()->showingComponents())
+	if (h && h == GAME->interface()->localState->getCurrentHero() && !widget->getInfoBar()->showingComponents())
 		widget->getInfoBar()->showSelection();
 
 	widget->updateActiveState();
@@ -116,7 +116,7 @@ void AdventureMapInterface::onTownChanged(const CGTownInstance * town)
 {
 	widget->getTownList()->updateElement(town);
 
-	if (town && town == LOCPLINT->localState->getCurrentTown() && !widget->getInfoBar()->showingComponents())
+	if (town && town == GAME->interface()->localState->getCurrentTown() && !widget->getInfoBar()->showingComponents())
 		widget->getInfoBar()->showSelection();
 }
 
@@ -131,42 +131,42 @@ void AdventureMapInterface::activate()
 
 	adjustActiveness();
 
-	if(LOCPLINT)
+	if(GAME->interface())
 	{
-		LOCPLINT->cingconsole->activate();
-		LOCPLINT->cingconsole->pos = this->pos;
+		GAME->interface()->cingconsole->activate();
+		GAME->interface()->cingconsole->pos = this->pos;
 	}
 
-	GH.fakeMouseMove(); //to restore the cursor
+	ENGINE->fakeMouseMove(); //to restore the cursor
 
 	// workaround for an edge case:
 	// if player unequips Angel Wings / Boots of Levitation of currently active hero
 	// game will correctly invalidate paths but current route will not be updated since verifyPath() is not called for current hero
-	if (LOCPLINT->makingTurn && LOCPLINT->localState->getCurrentHero())
-		LOCPLINT->localState->verifyPath(LOCPLINT->localState->getCurrentHero());
+	if (GAME->interface()->makingTurn && GAME->interface()->localState->getCurrentHero())
+		GAME->interface()->localState->verifyPath(GAME->interface()->localState->getCurrentHero());
 }
 
 void AdventureMapInterface::deactivate()
 {
 	CIntObject::deactivate();
-	CCS->curh->set(Cursor::Map::POINTER);
+	ENGINE->cursor().set(Cursor::Map::POINTER);
 
-	if(LOCPLINT)
-		LOCPLINT->cingconsole->deactivate();
+	if(GAME->interface())
+		GAME->interface()->cingconsole->deactivate();
 }
 
 void AdventureMapInterface::showAll(Canvas & to)
 {
 	CIntObject::showAll(to);
 	dim(to);
-	LOCPLINT->cingconsole->show(to);
+	GAME->interface()->cingconsole->show(to);
 }
 
 void AdventureMapInterface::show(Canvas & to)
 {
 	CIntObject::show(to);
 	dim(to);
-	LOCPLINT->cingconsole->show(to);
+	GAME->interface()->cingconsole->show(to);
 }
 
 void AdventureMapInterface::dim(Canvas & to)
@@ -174,19 +174,19 @@ void AdventureMapInterface::dim(Canvas & to)
 	auto const isBigWindow = [&](std::shared_ptr<CIntObject> window) { return window->pos.w >= 800 && window->pos.h >= 600; }; // OH3 fullscreen
 
 	if(settings["adventure"]["hideBackground"].Bool())
-		for (auto window : GH.windows().findWindows<CIntObject>())
+		for (auto window : ENGINE->windows().findWindows<CIntObject>())
 		{
 			if(!std::dynamic_pointer_cast<AdventureMapInterface>(window) && std::dynamic_pointer_cast<CIntObject>(window) && isBigWindow(window))
 			{
-				to.fillTexture(GH.renderHandler().loadImage(ImagePath::builtin("DiBoxBck"), EImageBlitMode::OPAQUE));
+				to.fillTexture(ENGINE->renderHandler().loadImage(ImagePath::builtin("DiBoxBck"), EImageBlitMode::OPAQUE));
 				return;
 			}
 		}
-	for (auto window : GH.windows().findWindows<CIntObject>())
+	for (auto window : ENGINE->windows().findWindows<CIntObject>())
 	{
 		if (!std::dynamic_pointer_cast<AdventureMapInterface>(window) && !std::dynamic_pointer_cast<RadialMenu>(window) && !window->isPopupWindow() && (settings["adventure"]["backgroundDimSmallWindows"].Bool() || isBigWindow(window) || shortcuts->getState() == EAdventureState::HOTSEAT_WAIT))
 		{
-			Rect targetRect(0, 0, GH.screenDimensions().x, GH.screenDimensions().y);
+			Rect targetRect(0, 0, ENGINE->screenDimensions().x, ENGINE->screenDimensions().y);
 			ColorRGBA colorToFill(0, 0, 0, std::clamp<int>(backgroundDimLevel, 0, 255));
 			if(backgroundDimLevel > 0)
 				to.drawColorBlended(targetRect, colorToFill);
@@ -212,26 +212,26 @@ void AdventureMapInterface::handleMapScrollingUpdate(uint32_t timePassed)
 	int32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
 	int32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
 
-	Point cursorPosition = GH.getCursorPosition();
+	Point cursorPosition = ENGINE->getCursorPosition();
 	Point scrollDirection;
 
 	if (cursorPosition.x < borderScrollWidth)
 		scrollDirection.x = -1;
 
-	if (cursorPosition.x > GH.screenDimensions().x - borderScrollWidth)
+	if (cursorPosition.x > ENGINE->screenDimensions().x - borderScrollWidth)
 		scrollDirection.x = +1;
 
 	if (cursorPosition.y < borderScrollWidth)
 		scrollDirection.y = -1;
 
-	if (cursorPosition.y > GH.screenDimensions().y - borderScrollWidth)
+	if (cursorPosition.y > ENGINE->screenDimensions().y - borderScrollWidth)
 		scrollDirection.y = +1;
 
 	Point scrollDelta = scrollDirection * scrollDistance;
 
 	bool cursorInScrollArea = scrollDelta != Point(0,0);
 	bool scrollingActive = cursorInScrollArea && shortcuts->optionMapScrollingActive() && !scrollingWasBlocked;
-	bool scrollingBlocked = GH.isKeyboardCtrlDown() || !settings["adventure"]["borderScroll"].Bool() || !GH.screenHandler().hasFocus();
+	bool scrollingBlocked = ENGINE->isKeyboardCtrlDown() || !settings["adventure"]["borderScroll"].Bool() || !ENGINE->screenHandler().hasFocus();
 
 	if (!scrollingWasActive && scrollingBlocked)
 	{
@@ -254,30 +254,30 @@ void AdventureMapInterface::handleMapScrollingUpdate(uint32_t timePassed)
 	if(scrollDelta.x > 0)
 	{
 		if(scrollDelta.y < 0)
-			CCS->curh->set(Cursor::Map::SCROLL_NORTHEAST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_NORTHEAST);
 		if(scrollDelta.y > 0)
-			CCS->curh->set(Cursor::Map::SCROLL_SOUTHEAST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_SOUTHEAST);
 		if(scrollDelta.y == 0)
-			CCS->curh->set(Cursor::Map::SCROLL_EAST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_EAST);
 	}
 	if(scrollDelta.x < 0)
 	{
 		if(scrollDelta.y < 0)
-			CCS->curh->set(Cursor::Map::SCROLL_NORTHWEST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_NORTHWEST);
 		if(scrollDelta.y > 0)
-			CCS->curh->set(Cursor::Map::SCROLL_SOUTHWEST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_SOUTHWEST);
 		if(scrollDelta.y == 0)
-			CCS->curh->set(Cursor::Map::SCROLL_WEST);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_WEST);
 	}
 
 	if (scrollDelta.x == 0)
 	{
 		if(scrollDelta.y < 0)
-			CCS->curh->set(Cursor::Map::SCROLL_NORTH);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_NORTH);
 		if(scrollDelta.y > 0)
-			CCS->curh->set(Cursor::Map::SCROLL_SOUTH);
+			ENGINE->cursor().set(Cursor::Map::SCROLL_SOUTH);
 		if(scrollDelta.y == 0)
-			CCS->curh->set(Cursor::Map::POINTER);
+			ENGINE->cursor().set(Cursor::Map::POINTER);
 	}
 
 	scrollingWasActive = scrollingActive;
@@ -299,7 +299,7 @@ void AdventureMapInterface::keyPressed(EShortcut key)
 		hotkeyAbortCastingMode();
 
 	//fake mouse use to trigger onTileHovered()
-	GH.fakeMouseMove();
+	ENGINE->fakeMouseMove();
 }
 
 void AdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
@@ -331,7 +331,7 @@ void AdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
 		widget->getHeroList()->select(hero);
 		widget->getTownList()->select(nullptr);
 
-		LOCPLINT->localState->verifyPath(hero);
+		GAME->interface()->localState->verifyPath(hero);
 		onHeroChanged(hero);
 	}
 
@@ -409,7 +409,7 @@ void AdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
 	onCurrentPlayerChanged(playerID);
 
 	setState(EAdventureState::MAKING_TURN);
-	if(playerID == LOCPLINT->playerID || settings["session"]["spectate"].Bool())
+	if(playerID == GAME->interface()->playerID || settings["session"]["spectate"].Bool())
 	{
 		widget->getMinimap()->setAIRadar(false);
 		widget->getInfoBar()->showSelection();
@@ -421,9 +421,9 @@ void AdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
 	const CGHeroInstance * heroToSelect = nullptr;
 
 	// find first non-sleeping hero
-	for (auto hero : LOCPLINT->localState->getWanderingHeroes())
+	for (auto hero : GAME->interface()->localState->getWanderingHeroes())
 	{
-		if (!LOCPLINT->localState->isHeroSleeping(hero))
+		if (!GAME->interface()->localState->isHeroSleeping(hero))
 		{
 			heroToSelect = hero;
 			break;
@@ -433,33 +433,33 @@ void AdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
 	//select first hero if available.
 	if (heroToSelect != nullptr)
 	{
-		LOCPLINT->localState->setSelection(heroToSelect);
+		GAME->interface()->localState->setSelection(heroToSelect);
 	}
-	else if (LOCPLINT->localState->getOwnedTowns().size())
+	else if (GAME->interface()->localState->getOwnedTowns().size())
 	{
-		LOCPLINT->localState->setSelection(LOCPLINT->localState->getOwnedTown(0));
+		GAME->interface()->localState->setSelection(GAME->interface()->localState->getOwnedTown(0));
 	}
 	else
 	{
-		LOCPLINT->localState->setSelection(LOCPLINT->localState->getWanderingHero(0));
+		GAME->interface()->localState->setSelection(GAME->interface()->localState->getWanderingHero(0));
 	}
 
-	onSelectionChanged(LOCPLINT->localState->getCurrentArmy());
+	onSelectionChanged(GAME->interface()->localState->getCurrentArmy());
 
 	//show new day animation and sound on infobar, except for 1st day of the game
-	if (LOCPLINT->cb->getDate(Date::DAY) != 1)
+	if (GAME->interface()->cb->getDate(Date::DAY) != 1)
 		widget->getInfoBar()->showDate();
 
 	onHeroChanged(nullptr);
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 	mapAudio->onPlayerTurnStarted();
 
-	if(settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown())
+	if(settings["session"]["autoSkip"].Bool() && !ENGINE->isKeyboardShiftDown())
 	{
-		if(auto iw = GH.windows().topWindow<CInfoWindow>())
+		if(auto iw = ENGINE->windows().topWindow<CInfoWindow>())
 			iw->close();
 
-		GH.dispatchMainThread([this]()
+		ENGINE->dispatchMainThread([this]()
 		{
 			hotkeyEndingTurn();
 		});
@@ -473,11 +473,11 @@ void AdventureMapInterface::hotkeyEndingTurn()
 
 	if(!settings["general"]["startTurnAutosave"].Bool())
 	{
-		LOCPLINT->performAutosave();
+		GAME->interface()->performAutosave();
 	}
 
-	LOCPLINT->makingTurn = false;
-	LOCPLINT->cb->endTurn();
+	GAME->interface()->makingTurn = false;
+	GAME->interface()->cb->endTurn();
 
 	mapAudio->onPlayerTurnEnded();
 
@@ -486,9 +486,9 @@ void AdventureMapInterface::hotkeyEndingTurn()
 	// So find first player other than ours that is acting at the moment and update UI as if he had started turn
 	for (auto player = PlayerColor(0); player < PlayerColor::PLAYER_LIMIT; ++player)
 	{
-		if (player != LOCPLINT->playerID && LOCPLINT->cb->isPlayerMakingTurn(player))
+		if (player != GAME->interface()->playerID && GAME->interface()->cb->isPlayerMakingTurn(player))
 		{
-			onEnemyTurnStarted(player, LOCPLINT->cb->getStartInfo()->playerInfos.at(player).isControlledByHuman());
+			onEnemyTurnStarted(player, GAME->interface()->cb->getStartInfo()->playerInfos.at(player).isControlledByHuman());
 			break;
 		}
 	}
@@ -496,7 +496,7 @@ void AdventureMapInterface::hotkeyEndingTurn()
 
 const CGObjectInstance* AdventureMapInterface::getActiveObject(const int3 &mapPos)
 {
-	std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mapPos);  //blocking objects at tile
+	std::vector < const CGObjectInstance * > bobjs = GAME->interface()->cb->getBlockingObjs(mapPos);  //blocking objects at tile
 
 	if (bobjs.empty())
 		return nullptr;
@@ -509,7 +509,7 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
 	if(!shortcuts->optionMapViewActive())
 		return;
 
-	const CGObjectInstance *topBlocking = LOCPLINT->cb->isVisible(targetPosition) ? getActiveObject(targetPosition) : nullptr;
+	const CGObjectInstance *topBlocking = GAME->interface()->cb->isVisible(targetPosition) ? getActiveObject(targetPosition) : nullptr;
 
 	if(spellBeingCasted)
 	{
@@ -521,39 +521,39 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
 		return;
 	}
 
-	if(!LOCPLINT->cb->isVisible(targetPosition))
+	if(!GAME->interface()->cb->isVisible(targetPosition))
 		return;
 
 	//check if we can select this object
-	bool canSelect = topBlocking && topBlocking->ID == Obj::HERO && topBlocking->tempOwner == LOCPLINT->playerID;
-	canSelect |= topBlocking && topBlocking->ID == Obj::TOWN && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES;
+	bool canSelect = topBlocking && topBlocking->ID == Obj::HERO && topBlocking->tempOwner == GAME->interface()->playerID;
+	canSelect |= topBlocking && topBlocking->ID == Obj::TOWN && GAME->interface()->cb->getPlayerRelations(GAME->interface()->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES;
 
-	if(LOCPLINT->localState->getCurrentArmy()->ID != Obj::HERO) //hero is not selected (presumably town)
+	if(GAME->interface()->localState->getCurrentArmy()->ID != Obj::HERO) //hero is not selected (presumably town)
 	{
-		if(LOCPLINT->localState->getCurrentArmy() == topBlocking) //selected town clicked
-			LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
+		if(GAME->interface()->localState->getCurrentArmy() == topBlocking) //selected town clicked
+			GAME->interface()->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
 		else if(canSelect)
-			LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
+			GAME->interface()->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
 	}
-	else if(const CGHeroInstance * currentHero = LOCPLINT->localState->getCurrentHero()) //hero is selected
+	else if(const CGHeroInstance * currentHero = GAME->interface()->localState->getCurrentHero()) //hero is selected
 	{
-		const CGPathNode *pn = LOCPLINT->getPathsInfo(currentHero)->getPathInfo(targetPosition);
+		const CGPathNode *pn = GAME->interface()->getPathsInfo(currentHero)->getPathInfo(targetPosition);
 
 		const auto shipyard = dynamic_cast<const IShipyard *>(topBlocking);
 
 		if(currentHero == topBlocking) //clicked selected hero
 		{
-			LOCPLINT->openHeroWindow(currentHero);
+			GAME->interface()->openHeroWindow(currentHero);
 			return;
 		}
 		else if(canSelect && pn->turns == 255 ) //selectable object at inaccessible tile
 		{
-			LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
+			GAME->interface()->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
 			return;
 		}
-		else if(shipyard != nullptr && pn->turns == 255 && LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES)
+		else if(shipyard != nullptr && pn->turns == 255 && GAME->interface()->cb->getPlayerRelations(GAME->interface()->playerID, topBlocking->tempOwner) != PlayerRelations::ENEMIES)
 		{
-			LOCPLINT->showShipyardDialogOrProblemPopup(shipyard);
+			GAME->interface()->showShipyardDialogOrProblemPopup(shipyard);
 		}
 		else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
 		{
@@ -562,25 +562,25 @@ void AdventureMapInterface::onTileLeftClicked(const int3 &targetPosition)
 			if(topBlocking && topBlocking->isVisitable() && !topBlocking->visitableAt(destinationTile) && settings["gameTweaks"]["simpleObjectSelection"].Bool())
 				destinationTile = topBlocking->visitablePos();
 
-			if(LOCPLINT->localState->hasPath(currentHero) &&
-			   LOCPLINT->localState->getPath(currentHero).endPos() == destinationTile &&
-			   !GH.isKeyboardShiftDown())//we'll be moving
+			if(GAME->interface()->localState->hasPath(currentHero) &&
+			   GAME->interface()->localState->getPath(currentHero).endPos() == destinationTile &&
+			   !ENGINE->isKeyboardShiftDown())//we'll be moving
 			{
-				assert(!CGI->mh->hasOngoingAnimations());
-				if(!CGI->mh->hasOngoingAnimations() && LOCPLINT->localState->getPath(currentHero).nextNode().turns == 0)
-					LOCPLINT->moveHero(currentHero, LOCPLINT->localState->getPath(currentHero));
+				assert(!GAME->map().hasOngoingAnimations());
+				if(!GAME->map().hasOngoingAnimations() && GAME->interface()->localState->getPath(currentHero).nextNode().turns == 0)
+					GAME->interface()->moveHero(currentHero, GAME->interface()->localState->getPath(currentHero));
 				return;
 			}
 			else
 			{
-				if(GH.isKeyboardShiftDown()) //normal click behaviour (as no hero selected)
+				if(ENGINE->isKeyboardShiftDown()) //normal click behaviour (as no hero selected)
 				{
 					if(canSelect)
-						LOCPLINT->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
+						GAME->interface()->localState->setSelection(static_cast<const CArmedInstance*>(topBlocking));
 				}
 				else //remove old path and find a new one if we clicked on accessible tile
 				{
-					LOCPLINT->localState->setPath(currentHero, destinationTile);
+					GAME->interface()->localState->setPath(currentHero, destinationTile);
 					onHeroChanged(currentHero);
 				}
 			}
@@ -598,10 +598,10 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		return;
 
 	//may occur just at the start of game (fake move before full initialization)
-	if(!LOCPLINT->localState->getCurrentArmy())
+	if(!GAME->interface()->localState->getCurrentArmy())
 		return;
 
-	bool isTargetPositionVisible = LOCPLINT->cb->isVisible(targetPosition);
+	bool isTargetPositionVisible = GAME->interface()->cb->isVisible(targetPosition);
 	const CGObjectInstance *objAtTile = isTargetPositionVisible ? getActiveObject(targetPosition) : nullptr;
 
 	if(spellBeingCasted)
@@ -610,32 +610,32 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		{
 		case SpellID::SCUTTLE_BOAT:
 			if(isValidAdventureSpellTarget(targetPosition))
-				CCS->curh->set(Cursor::Map::SCUTTLE_BOAT);
+				ENGINE->cursor().set(Cursor::Map::SCUTTLE_BOAT);
 			else
-				CCS->curh->set(Cursor::Map::POINTER);
+				ENGINE->cursor().set(Cursor::Map::POINTER);
 			return;
 
 		case SpellID::DIMENSION_DOOR:
 			if(isValidAdventureSpellTarget(targetPosition))
 			{
-				if(LOCPLINT->cb->getSettings().getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS) && LOCPLINT->cb->isTileGuardedUnchecked(targetPosition))
-					CCS->curh->set(Cursor::Map::T1_ATTACK);
+				if(GAME->interface()->cb->getSettings().getBoolean(EGameSettings::DIMENSION_DOOR_TRIGGERS_GUARDS) && GAME->interface()->cb->isTileGuardedUnchecked(targetPosition))
+					ENGINE->cursor().set(Cursor::Map::T1_ATTACK);
 				else
-					CCS->curh->set(Cursor::Map::TELEPORT);
+					ENGINE->cursor().set(Cursor::Map::TELEPORT);
 				return;
 			}
 			else
-				CCS->curh->set(Cursor::Map::POINTER);
+				ENGINE->cursor().set(Cursor::Map::POINTER);
 			return;
 		default:
-			CCS->curh->set(Cursor::Map::POINTER);
+			ENGINE->cursor().set(Cursor::Map::POINTER);
 			return;
 		}
 	}
 
 	if(!isTargetPositionVisible)
 	{
-		CCS->curh->set(Cursor::Map::POINTER);
+		ENGINE->cursor().set(Cursor::Map::POINTER);
 		return;
 	}
 
@@ -643,36 +643,36 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 
 	if(objAtTile)
 	{
-		objRelations = LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner);
-		std::string text = LOCPLINT->localState->getCurrentHero() ? objAtTile->getHoverText(LOCPLINT->localState->getCurrentHero()) : objAtTile->getHoverText(LOCPLINT->playerID);
+		objRelations = GAME->interface()->cb->getPlayerRelations(GAME->interface()->playerID, objAtTile->tempOwner);
+		std::string text = GAME->interface()->localState->getCurrentHero() ? objAtTile->getHoverText(GAME->interface()->localState->getCurrentHero()) : objAtTile->getHoverText(GAME->interface()->playerID);
 		boost::replace_all(text,"\n"," ");
-		if (GH.isKeyboardCmdDown())
+		if (ENGINE->isKeyboardCmdDown())
 			text.append(" (" + std::to_string(targetPosition.x) + ", " + std::to_string(targetPosition.y) + ")");
-		GH.statusbar()->write(text);
+		ENGINE->statusbar()->write(text);
 	}
 	else if(isTargetPositionVisible)
 	{
-		std::string tileTooltipText = CGI->mh->getTerrainDescr(targetPosition, false);
-		if (GH.isKeyboardCmdDown())
+		std::string tileTooltipText = GAME->map().getTerrainDescr(targetPosition, false);
+		if (ENGINE->isKeyboardCmdDown())
 			tileTooltipText.append(" (" + std::to_string(targetPosition.x) + ", " + std::to_string(targetPosition.y) + ")");
-		GH.statusbar()->write(tileTooltipText);
+		ENGINE->statusbar()->write(tileTooltipText);
 	}
 
-	if(LOCPLINT->localState->getCurrentArmy()->ID == Obj::TOWN || GH.isKeyboardShiftDown())
+	if(GAME->interface()->localState->getCurrentArmy()->ID == Obj::TOWN || ENGINE->isKeyboardShiftDown())
 	{
 		if(objAtTile)
 		{
 			if(objAtTile->ID == Obj::TOWN && objRelations != PlayerRelations::ENEMIES)
-				CCS->curh->set(Cursor::Map::TOWN);
+				ENGINE->cursor().set(Cursor::Map::TOWN);
 			else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER)
-				CCS->curh->set(Cursor::Map::HERO);
+				ENGINE->cursor().set(Cursor::Map::HERO);
 			else
-				CCS->curh->set(Cursor::Map::POINTER);
+				ENGINE->cursor().set(Cursor::Map::POINTER);
 		}
 		else
-			CCS->curh->set(Cursor::Map::POINTER);
+			ENGINE->cursor().set(Cursor::Map::POINTER);
 	}
-	else if(const CGHeroInstance * hero = LOCPLINT->localState->getCurrentHero())
+	else if(const CGHeroInstance * hero = GAME->interface()->localState->getCurrentHero())
 	{
 		std::array<Cursor::Map, 4> cursorMove      = { Cursor::Map::T1_MOVE,       Cursor::Map::T2_MOVE,       Cursor::Map::T3_MOVE,       Cursor::Map::T4_MOVE,       };
 		std::array<Cursor::Map, 4> cursorAttack    = { Cursor::Map::T1_ATTACK,     Cursor::Map::T2_ATTACK,     Cursor::Map::T3_ATTACK,     Cursor::Map::T4_ATTACK,     };
@@ -682,10 +682,10 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		std::array<Cursor::Map, 4> cursorVisit     = { Cursor::Map::T1_VISIT,      Cursor::Map::T2_VISIT,      Cursor::Map::T3_VISIT,      Cursor::Map::T4_VISIT,      };
 		std::array<Cursor::Map, 4> cursorSailVisit = { Cursor::Map::T1_SAIL_VISIT, Cursor::Map::T2_SAIL_VISIT, Cursor::Map::T3_SAIL_VISIT, Cursor::Map::T4_SAIL_VISIT, };
 
-		const CGPathNode * pathNode = LOCPLINT->getPathsInfo(hero)->getPathInfo(targetPosition);
+		const CGPathNode * pathNode = GAME->interface()->getPathsInfo(hero)->getPathInfo(targetPosition);
 		assert(pathNode);
 
-		if((GH.isKeyboardAltDown() || settings["gameTweaks"]["forceMovementInfo"].Bool()) && pathNode->reachable()) //overwrite status bar text with movement info
+		if((ENGINE->isKeyboardAltDown() || settings["gameTweaks"]["forceMovementInfo"].Bool()) && pathNode->reachable()) //overwrite status bar text with movement info
 		{
 			showMoveDetailsInStatusbar(*hero, *pathNode);
 		}
@@ -694,22 +694,22 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		{
 			if(objAtTile->ID == Obj::TOWN && objRelations != PlayerRelations::ENEMIES)
 			{
-				CCS->curh->set(Cursor::Map::TOWN);
+				ENGINE-> cursor().set(Cursor::Map::TOWN);
 				return;
 			}
 			else if(objAtTile->ID == Obj::HERO && objRelations == PlayerRelations::SAME_PLAYER)
 			{
-				CCS->curh->set(Cursor::Map::HERO);
+				ENGINE-> cursor().set(Cursor::Map::HERO);
 				return;
 			}
 			else if (objAtTile->ID == Obj::SHIPYARD && objRelations != PlayerRelations::ENEMIES)
 			{
-				CCS->curh->set(Cursor::Map::T1_SAIL);
+				ENGINE-> cursor().set(Cursor::Map::T1_SAIL);
 				return;
 			}
 
 			if(objAtTile->isVisitable() && !objAtTile->visitableAt(targetPosition) && settings["gameTweaks"]["simpleObjectSelection"].Bool())
-				pathNode = LOCPLINT->getPathsInfo(hero)->getPathInfo(objAtTile->visitablePos());
+				pathNode = GAME->interface()->getPathsInfo(hero)->getPathInfo(objAtTile->visitablePos());
 		}
 
 		int turns = pathNode->turns;
@@ -719,9 +719,9 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		case EPathNodeAction::NORMAL:
 		case EPathNodeAction::TELEPORT_NORMAL:
 			if(pathNode->layer == EPathfindingLayer::LAND)
-				CCS->curh->set(cursorMove[turns]);
+				ENGINE->cursor().set(cursorMove[turns]);
 			else
-				CCS->curh->set(cursorSail[turns]);
+				ENGINE->cursor().set(cursorSail[turns]);
 			break;
 
 		case EPathNodeAction::VISIT:
@@ -729,13 +729,13 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 		case EPathNodeAction::TELEPORT_BLOCKING_VISIT:
 			if(objAtTile && objAtTile->ID == Obj::HERO)
 			{
-				if(LOCPLINT->localState->getCurrentArmy()  == objAtTile)
-					CCS->curh->set(Cursor::Map::HERO);
+				if(GAME->interface()->localState->getCurrentArmy()  == objAtTile)
+					ENGINE->cursor().set(Cursor::Map::HERO);
 				else
-					CCS->curh->set(cursorExchange[turns]);
+					ENGINE->cursor().set(cursorExchange[turns]);
 			}
 			else if(pathNode->layer == EPathfindingLayer::LAND)
-				CCS->curh->set(cursorVisit[turns]);
+				ENGINE->cursor().set(cursorVisit[turns]);
 			else if (pathNode->layer == EPathfindingLayer::SAIL &&
 					 objAtTile &&
 					 objAtTile->isCoastVisitable() &&
@@ -743,27 +743,27 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
 					 pathNode->theNodeBefore->layer == EPathfindingLayer::LAND )
 			{
 				// exception - when visiting shipwreck located on coast from land - show 'horse' cursor, not 'ship' cursor
-				CCS->curh->set(cursorVisit[turns]);
+				ENGINE->cursor().set(cursorVisit[turns]);
 			}
 			else
-				CCS->curh->set(cursorSailVisit[turns]);
+				ENGINE->cursor().set(cursorSailVisit[turns]);
 			break;
 
 		case EPathNodeAction::BATTLE:
 		case EPathNodeAction::TELEPORT_BATTLE:
-			CCS->curh->set(cursorAttack[turns]);
+			ENGINE->cursor().set(cursorAttack[turns]);
 			break;
 
 		case EPathNodeAction::EMBARK:
-			CCS->curh->set(cursorSail[turns]);
+			ENGINE->cursor().set(cursorSail[turns]);
 			break;
 
 		case EPathNodeAction::DISEMBARK:
-			CCS->curh->set(cursorDisembark[turns]);
+			ENGINE->cursor().set(cursorDisembark[turns]);
 			break;
 
 		default:
-				CCS->curh->set(Cursor::Map::POINTER);
+				ENGINE->cursor().set(Cursor::Map::POINTER);
 			break;
 		}
 	}
@@ -787,14 +787,14 @@ void AdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & he
 
 	totalMovementCost -= pathNode.moveRemains;
 
-	std::string result = VLC->generaltexth->translate("vcmi.adventureMap", pathNode.turns > 0 ? "moveCostDetails" : "moveCostDetailsNoTurns");
+	std::string result = LIBRARY->generaltexth->translate("vcmi.adventureMap", pathNode.turns > 0 ? "moveCostDetails" : "moveCostDetailsNoTurns");
 
 	boost::replace_first(result, "%TURNS", std::to_string(pathNode.turns));
 	boost::replace_first(result, "%POINTS", std::to_string(movementPointsLastTurnCost));
 	boost::replace_first(result, "%REMAINING", std::to_string(remainingPointsAfterMove));
 	boost::replace_first(result, "%TOTAL", std::to_string(totalMovementCost));
 
-	GH.statusbar()->write(result);
+	ENGINE->statusbar()->write(result);
 }
 
 void AdventureMapInterface::onTileRightClicked(const int3 &mapPos)
@@ -808,9 +808,9 @@ void AdventureMapInterface::onTileRightClicked(const int3 &mapPos)
 		return;
 	}
 
-	if(!LOCPLINT->cb->isVisible(mapPos))
+	if(!GAME->interface()->cb->isVisible(mapPos))
 	{
-		CRClickPopup::createAndPush(VLC->generaltexth->allTexts[61]); //Uncharted Territory
+		CRClickPopup::createAndPush(LIBRARY->generaltexth->allTexts[61]); //Uncharted Territory
 		return;
 	}
 
@@ -818,16 +818,16 @@ void AdventureMapInterface::onTileRightClicked(const int3 &mapPos)
 	if(!obj)
 	{
 		// Bare or undiscovered terrain
-		const TerrainTile * tile = LOCPLINT->cb->getTile(mapPos);
+		const TerrainTile * tile = GAME->interface()->cb->getTile(mapPos);
 		if(tile)
 		{
-			std::string hlp = CGI->mh->getTerrainDescr(mapPos, true);
+			std::string hlp = GAME->map().getTerrainDescr(mapPos, true);
 			CRClickPopup::createAndPush(hlp);
 		}
 		return;
 	}
 
-	CRClickPopup::createAndPush(obj, GH.getCursorPosition(), ETextAlignment::CENTER);
+	CRClickPopup::createAndPush(obj, ENGINE->getCursorPosition(), ETextAlignment::CENTER);
 }
 
 void AdventureMapInterface::enterCastingMode(const CSpell * sp)
@@ -853,14 +853,14 @@ void AdventureMapInterface::exitCastingMode()
 void AdventureMapInterface::hotkeyAbortCastingMode()
 {
 	exitCastingMode();
-	LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[731]); //Spell cancelled
+	GAME->interface()->showInfoDialog(LIBRARY->generaltexth->allTexts[731]); //Spell cancelled
 }
 
 void AdventureMapInterface::performSpellcasting(const int3 & dest)
 {
 	SpellID id = spellBeingCasted->id;
 	exitCastingMode();
-	LOCPLINT->cb->castSpell(LOCPLINT->localState->getCurrentHero(), id, dest);
+	GAME->interface()->cb->castSpell(GAME->interface()->localState->getCurrentHero(), id, dest);
 }
 
 Rect AdventureMapInterface::terrainAreaPixels() const
@@ -920,8 +920,8 @@ void AdventureMapInterface::onScreenResize()
 
 	widget.reset();
 	pos.x = pos.y = 0;
-	pos.w = GH.screenDimensions().x;
-	pos.h = GH.screenDimensions().y;
+	pos.w = ENGINE->screenDimensions().x;
+	pos.h = ENGINE->screenDimensions().y;
 
 	widget = std::make_shared<AdventureMapWidget>(shortcuts);
 	widget->getMapView()->onViewMapActivated();
@@ -930,8 +930,8 @@ void AdventureMapInterface::onScreenResize()
 	widget->getMinimap()->update();
 	widget->getInfoBar()->showSelection();
 
-	if (LOCPLINT && LOCPLINT->localState->getCurrentArmy())
-		widget->getMapView()->onCenteredObject(LOCPLINT->localState->getCurrentArmy());
+	if (GAME->interface() && GAME->interface()->localState->getCurrentArmy())
+		widget->getMapView()->onCenteredObject(GAME->interface()->localState->getCurrentArmy());
 
 	adjustActiveness();
 
@@ -943,5 +943,5 @@ bool AdventureMapInterface::isValidAdventureSpellTarget(int3 targetPosition) con
 {
 	spells::detail::ProblemImpl problem;
 
-	return spellBeingCasted->getAdventureMechanics().canBeCastAt(problem, LOCPLINT->cb.get(), LOCPLINT->localState->getCurrentHero(), targetPosition);
+	return spellBeingCasted->getAdventureMechanics().canBeCastAt(problem, GAME->interface()->cb.get(), GAME->interface()->localState->getCurrentHero(), targetPosition);
 }

+ 94 - 94
client/adventureMap/AdventureMapShortcuts.cpp

@@ -11,12 +11,12 @@
 #include "StdInc.h"
 #include "AdventureMapShortcuts.h"
 
-#include "../CGameInfo.h"
 #include "../CMT.h"
 #include "../CPlayerInterface.h"
 #include "../CServerHandler.h"
 #include "../PlayerLocalState.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../lobby/CSavingScreen.h"
@@ -122,14 +122,14 @@ std::vector<AdventureMapShortcutState> AdventureMapShortcuts::getShortcuts()
 
 void AdventureMapShortcuts::showOverview()
 {
-	GH.windows().createAndPushWindow<CKingdomInterface>();
+	ENGINE->windows().createAndPushWindow<CKingdomInterface>();
 }
 
 void AdventureMapShortcuts::worldViewBack()
 {
 	owner.hotkeyExitWorldView();
 
-	auto hero = LOCPLINT->localState->getCurrentHero();
+	auto hero = GAME->interface()->localState->getCurrentHero();
 	if (hero)
 		owner.centerOnObject(hero);
 }
@@ -152,7 +152,7 @@ void AdventureMapShortcuts::worldViewScale4x()
 
 void AdventureMapShortcuts::switchMapLevel()
 {
-	int maxLevels = LOCPLINT->cb->getMapSize().z;
+	int maxLevels = GAME->interface()->cb->getMapSize().z;
 	if (maxLevels < 2)
 		return;
 
@@ -161,7 +161,7 @@ void AdventureMapShortcuts::switchMapLevel()
 
 void AdventureMapShortcuts::showQuestlog()
 {
-	LOCPLINT->showQuestLog();
+	GAME->interface()->showQuestLog();
 }
 
 void AdventureMapShortcuts::toggleTrackHero()
@@ -201,10 +201,10 @@ void AdventureMapShortcuts::toggleSleepWake()
 
 void AdventureMapShortcuts::setHeroSleeping()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
 	if (h)
 	{
-		LOCPLINT->localState->setHeroAsleep(h);
+		GAME->interface()->localState->setHeroAsleep(h);
 		owner.onHeroChanged(h);
 		nextHero();
 	}
@@ -212,91 +212,91 @@ void AdventureMapShortcuts::setHeroSleeping()
 
 void AdventureMapShortcuts::setHeroAwake()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
 	if (h)
 	{
-		LOCPLINT->localState->setHeroAwaken(h);
+		GAME->interface()->localState->setHeroAwaken(h);
 		owner.onHeroChanged(h);
 	}
 }
 
 void AdventureMapShortcuts::moveHeroAlongPath()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
-	if (!h || !LOCPLINT->localState->hasPath(h))
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
+	if (!h || !GAME->interface()->localState->hasPath(h))
 		return;
 
-	LOCPLINT->moveHero(h, LOCPLINT->localState->getPath(h));
+	GAME->interface()->moveHero(h, GAME->interface()->localState->getPath(h));
 }
 
 void AdventureMapShortcuts::showSpellbook()
 {
-	if (!LOCPLINT->localState->getCurrentHero())
+	if (!GAME->interface()->localState->getCurrentHero())
 		return;
 
-	owner.centerOnObject(LOCPLINT->localState->getCurrentHero());
+	owner.centerOnObject(GAME->interface()->localState->getCurrentHero());
 
-	GH.windows().createAndPushWindow<CSpellWindow>(LOCPLINT->localState->getCurrentHero(), LOCPLINT, false);
+	ENGINE->windows().createAndPushWindow<CSpellWindow>(GAME->interface()->localState->getCurrentHero(), GAME->interface(), false);
 }
 
 void AdventureMapShortcuts::adventureOptions()
 {
-	GH.windows().createAndPushWindow<AdventureOptions>();
+	ENGINE->windows().createAndPushWindow<AdventureOptions>();
 }
 
 void AdventureMapShortcuts::systemOptions()
 {
-	GH.windows().createAndPushWindow<SettingsMainWindow>();
+	ENGINE->windows().createAndPushWindow<SettingsMainWindow>();
 }
 
 void AdventureMapShortcuts::firstHero()
 {
-	if (!LOCPLINT->localState->getWanderingHeroes().empty())
+	if (!GAME->interface()->localState->getWanderingHeroes().empty())
 	{
-		const auto * hero = LOCPLINT->localState->getWanderingHero(0);
-		LOCPLINT->localState->setSelection(hero);
+		const auto * hero = GAME->interface()->localState->getWanderingHero(0);
+		GAME->interface()->localState->setSelection(hero);
 		owner.centerOnObject(hero);
 	}
 }
 
 void AdventureMapShortcuts::nextHero()
 {
-	const auto * currHero = LOCPLINT->localState->getCurrentHero();
-	const auto * nextHero = LOCPLINT->localState->getNextWanderingHero(currHero);
+	const auto * currHero = GAME->interface()->localState->getCurrentHero();
+	const auto * nextHero = GAME->interface()->localState->getNextWanderingHero(currHero);
 
 	if (nextHero)
 	{
-		LOCPLINT->localState->setSelection(nextHero);
+		GAME->interface()->localState->setSelection(nextHero);
 		owner.centerOnObject(nextHero);
 	}
 }
 
 void AdventureMapShortcuts::endTurn()
 {
-	if(!LOCPLINT->makingTurn)
+	if(!GAME->interface()->makingTurn)
 		return;
 
 	if(settings["adventure"]["heroReminder"].Bool())
 	{
-		for(auto hero : LOCPLINT->localState->getWanderingHeroes())
+		for(auto hero : GAME->interface()->localState->getWanderingHeroes())
 		{
-			if(!LOCPLINT->localState->isHeroSleeping(hero) && hero->movementPointsRemaining() > 0)
+			if(!GAME->interface()->localState->isHeroSleeping(hero) && hero->movementPointsRemaining() > 0)
 			{
 				// Only show hero reminder if conditions met:
 				// - There still movement points
 				// - Hero don't have a path or there not points for first step on path
-				LOCPLINT->localState->verifyPath(hero);
+				GAME->interface()->localState->verifyPath(hero);
 
-				if(!LOCPLINT->localState->hasPath(hero))
+				if(!GAME->interface()->localState->hasPath(hero))
 				{
-					LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], [this](){ owner.hotkeyEndingTurn(); }, nullptr);
+					GAME->interface()->showYesNoDialog( LIBRARY->generaltexth->allTexts[55], [this](){ owner.hotkeyEndingTurn(); }, nullptr);
 					return;
 				}
 
-				auto path = LOCPLINT->localState->getPath(hero);
+				auto path = GAME->interface()->localState->getPath(hero);
 				if (path.nodes.size() < 2 || path.nodes[path.nodes.size() - 2].turns)
 				{
-					LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], [this](){ owner.hotkeyEndingTurn(); }, nullptr);
+					GAME->interface()->showYesNoDialog( LIBRARY->generaltexth->allTexts[55], [this](){ owner.hotkeyEndingTurn(); }, nullptr);
 					return;
 				}
 			}
@@ -308,15 +308,15 @@ void AdventureMapShortcuts::endTurn()
 void AdventureMapShortcuts::showThievesGuild()
 {
 	//find first town with tavern
-	auto itr = range::find_if(LOCPLINT->localState->getOwnedTowns(), [](const CGTownInstance * town)
+	auto itr = range::find_if(GAME->interface()->localState->getOwnedTowns(), [](const CGTownInstance * town)
 	{
 		return town->hasBuilt(BuildingID::TAVERN);
 	});
 
-	if(itr != LOCPLINT->localState->getOwnedTowns().end())
-		LOCPLINT->showThievesGuildWindow(*itr);
+	if(itr != GAME->interface()->localState->getOwnedTowns().end())
+		GAME->interface()->showThievesGuildWindow(*itr);
 	else
-		LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
+		GAME->interface()->showInfoDialog(LIBRARY->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
 }
 
 void AdventureMapShortcuts::showScenarioInfo()
@@ -326,11 +326,11 @@ void AdventureMapShortcuts::showScenarioInfo()
 
 void AdventureMapShortcuts::toMainMenu()
 {
-	LOCPLINT->showYesNoDialog(
-		CGI->generaltexth->allTexts[578],
+	GAME->interface()->showYesNoDialog(
+		LIBRARY->generaltexth->allTexts[578],
 		[]()
 		{
-			CSH->endGameplay();
+			GAME->server().endGameplay();
 			CMM->menu->switchToTab("main");
 		},
 		0
@@ -339,11 +339,11 @@ void AdventureMapShortcuts::toMainMenu()
 
 void AdventureMapShortcuts::newGame()
 {
-	LOCPLINT->showYesNoDialog(
-		CGI->generaltexth->allTexts[578],
+	GAME->interface()->showYesNoDialog(
+		LIBRARY->generaltexth->allTexts[578],
 		[]()
 		{
-			CSH->endGameplay();
+			GAME->server().endGameplay();
 			CMM->menu->switchToTab("new");
 		},
 		nullptr
@@ -352,11 +352,11 @@ void AdventureMapShortcuts::newGame()
 
 void AdventureMapShortcuts::quitGame()
 {
-	LOCPLINT->showYesNoDialog(
-		CGI->generaltexth->allTexts[578],
+	GAME->interface()->showYesNoDialog(
+		LIBRARY->generaltexth->allTexts[578],
 		[]()
 		{
-			GH.dispatchMainThread( []()
+			ENGINE->dispatchMainThread( []()
 			{
 				handleQuit(false);
 			});
@@ -367,37 +367,37 @@ void AdventureMapShortcuts::quitGame()
 
 void AdventureMapShortcuts::saveGame()
 {
-	GH.windows().createAndPushWindow<CSavingScreen>();
+	ENGINE->windows().createAndPushWindow<CSavingScreen>();
 }
 
 void AdventureMapShortcuts::loadGame()
 {
-	LOCPLINT->proposeLoadingGame();
+	GAME->interface()->proposeLoadingGame();
 }
 
 void AdventureMapShortcuts::digGrail()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
 
-	if(h && LOCPLINT->makingTurn)
-		LOCPLINT->tryDigging(h);
+	if(h && GAME->interface()->makingTurn)
+		GAME->interface()->tryDigging(h);
 }
 
 void AdventureMapShortcuts::viewPuzzleMap()
 {
-	LOCPLINT->showPuzzleMap();
+	GAME->interface()->showPuzzleMap();
 }
 
 void AdventureMapShortcuts::restartGame()
 {
-	LOCPLINT->showYesNoDialog(
-		CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
+	GAME->interface()->showYesNoDialog(
+		LIBRARY->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
 		[]()
 		{
-			GH.dispatchMainThread(
+			ENGINE->dispatchMainThread(
 				[]()
 				{
-					CSH->sendRestartGame();
+					GAME->server().sendRestartGame();
 				}
 			);
 		},
@@ -407,28 +407,28 @@ void AdventureMapShortcuts::restartGame()
 
 void AdventureMapShortcuts::visitObject()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
 
 	if(h)
-		LOCPLINT->cb->moveHero(h, h->pos, false);
+		GAME->interface()->cb->moveHero(h, h->pos, false);
 }
 
 void AdventureMapShortcuts::openObject()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
-	const CGTownInstance *t = LOCPLINT->localState->getCurrentTown();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
+	const CGTownInstance *t = GAME->interface()->localState->getCurrentTown();
 	if(h)
-		LOCPLINT->openHeroWindow(h);
+		GAME->interface()->openHeroWindow(h);
 
 	if(t)
-		LOCPLINT->openTownWindow(t);
+		GAME->interface()->openTownWindow(t);
 }
 
 void AdventureMapShortcuts::showMarketplace()
 {
 	//check if we have any marketplace
 	const CGTownInstance *townWithMarket = nullptr;
-	for(const CGTownInstance *t : LOCPLINT->cb->getTownsInfo())
+	for(const CGTownInstance *t : GAME->interface()->cb->getTownsInfo())
 	{
 		if(t->hasBuilt(BuildingID::MARKETPLACE))
 		{
@@ -438,17 +438,17 @@ void AdventureMapShortcuts::showMarketplace()
 	}
 
 	if(townWithMarket) //if any town has marketplace, open window
-		GH.windows().createAndPushWindow<CMarketWindow>(townWithMarket, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
+		ENGINE->windows().createAndPushWindow<CMarketWindow>(townWithMarket, nullptr, nullptr, EMarketMode::RESOURCE_RESOURCE);
 	else //if not - complain
-		LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
+		GAME->interface()->showInfoDialog(LIBRARY->generaltexth->translate("vcmi.adventureMap.noTownWithMarket"));
 }
 
 void AdventureMapShortcuts::firstTown()
 {
-	if (!LOCPLINT->localState->getOwnedTowns().empty())
+	if (!GAME->interface()->localState->getOwnedTowns().empty())
 	{
-		const auto * town = LOCPLINT->localState->getOwnedTown(0);
-		LOCPLINT->localState->setSelection(town);
+		const auto * town = GAME->interface()->localState->getOwnedTown(0);
+		GAME->interface()->localState->setSelection(town);
 		owner.centerOnObject(town);
 	}
 }
@@ -467,14 +467,14 @@ void AdventureMapShortcuts::search(bool next)
 {
 	// get all relevant objects
 	std::vector<ObjectInstanceID> visitableObjInstances;
-	for(auto & obj : LOCPLINT->cb->getAllVisitableObjs())
+	for(auto & obj : GAME->interface()->cb->getAllVisitableObjs())
 		if(obj->ID != MapObjectID::MONSTER && obj->ID != MapObjectID::HERO && obj->ID != MapObjectID::TOWN)
 			visitableObjInstances.push_back(obj->id);
 
 	// count of elements for each group (map is already sorted)
 	std::map<std::string, int> mapObjCount;
 	for(auto & obj : visitableObjInstances)
-		mapObjCount[{ LOCPLINT->cb->getObjInstance(obj)->getObjectName() }]++;
+		mapObjCount[{ GAME->interface()->cb->getObjInstance(obj)->getObjectName() }]++;
 
 	// convert to vector for indexed access
 	std::vector<std::pair<std::string, int>> textCountList;
@@ -500,7 +500,7 @@ void AdventureMapShortcuts::search(bool next)
 			// filter for matching objects
 			std::vector<ObjectInstanceID> selVisitableObjInstances;
 			for(auto & obj : visitableObjInstances)
-				if(selObj == LOCPLINT->cb->getObjInstance(obj)->getObjectName())
+				if(selObj == GAME->interface()->cb->getObjInstance(obj)->getObjectName())
 					selVisitableObjInstances.push_back(obj);
 			
 			if(searchPos + 1 < selVisitableObjInstances.size() && searchLast == selObj)
@@ -508,7 +508,7 @@ void AdventureMapShortcuts::search(bool next)
 			else
 				searchPos = 0;
 
-			auto objInst = LOCPLINT->cb->getObjInstance(selVisitableObjInstances[searchPos]);
+			auto objInst = GAME->interface()->cb->getObjInstance(selVisitableObjInstances[searchPos]);
 			owner.centerOnObject(objInst);
 			searchLast = objInst->getObjectName();
 		};
@@ -516,13 +516,13 @@ void AdventureMapShortcuts::search(bool next)
 	if(next)
 		selectObjOnMap(lastSel);
 	else
-		GH.windows().createAndPushWindow<CObjectListWindow>(texts, nullptr, CGI->generaltexth->translate("vcmi.adventureMap.search.hover"), CGI->generaltexth->translate("vcmi.adventureMap.search.help"), [selectObjOnMap](int index){ selectObjOnMap(index); }, lastSel, std::vector<std::shared_ptr<IImage>>(), true);
+		ENGINE->windows().createAndPushWindow<CObjectListWindow>(texts, nullptr, LIBRARY->generaltexth->translate("vcmi.adventureMap.search.hover"), LIBRARY->generaltexth->translate("vcmi.adventureMap.search.help"), [selectObjOnMap](int index){ selectObjOnMap(index); }, lastSel, std::vector<std::shared_ptr<IImage>>(), true);
 }
 
 void AdventureMapShortcuts::nextObject()
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
-	const CGTownInstance *t = LOCPLINT->localState->getCurrentTown();
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero();
+	const CGTownInstance *t = GAME->interface()->localState->getCurrentTown();
 	if(h)
 		nextHero();
 
@@ -532,39 +532,39 @@ void AdventureMapShortcuts::nextObject()
 
 void AdventureMapShortcuts::moveHeroDirectional(const Point & direction)
 {
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); //selected hero
+	const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero(); //selected hero
 
 	if(!h)
 		return;
 
-	if (CGI->mh->hasOngoingAnimations())
+	if (GAME->map().hasOngoingAnimations())
 		return;
 
 	int3 dst = h->visitablePos() + int3(direction.x, direction.y, 0);
 
-	if (!CGI->mh->isInMap((dst)))
+	if (!GAME->map().isInMap((dst)))
 		return;
 
-	if ( !LOCPLINT->localState->setPath(h, dst))
+	if ( !GAME->interface()->localState->setPath(h, dst))
 		return;
 
-	const CGPath & path = LOCPLINT->localState->getPath(h);
+	const CGPath & path = GAME->interface()->localState->getPath(h);
 
 	if (path.nodes.size() > 2)
 		owner.onHeroChanged(h);
 	else
 		if(path.nodes[0].turns == 0)
-			LOCPLINT->moveHero(h, path);
+			GAME->interface()->moveHero(h, path);
 }
 
 bool AdventureMapShortcuts::optionCanViewQuests()
 {
-	return optionInMapView() && !CGI->mh->getMap()->quests.empty();
+	return optionInMapView() && !GAME->map().getMap()->quests.empty();
 }
 
 bool AdventureMapShortcuts::optionCanToggleLevel()
 {
-	return optionSidePanelActive() && LOCPLINT->cb->getMapSize().z > 1;
+	return optionSidePanelActive() && GAME->interface()->cb->getMapSize().z > 1;
 }
 
 bool AdventureMapShortcuts::optionMapLevelSurface()
@@ -574,14 +574,14 @@ bool AdventureMapShortcuts::optionMapLevelSurface()
 
 bool AdventureMapShortcuts::optionHeroSleeping()
 {
-	const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero();
-	return optionInMapView() && hero && LOCPLINT->localState->isHeroSleeping(hero);
+	const CGHeroInstance *hero = GAME->interface()->localState->getCurrentHero();
+	return optionInMapView() && hero && GAME->interface()->localState->isHeroSleeping(hero);
 }
 
 bool AdventureMapShortcuts::optionHeroAwake()
 {
-	const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero();
-	return optionInMapView() && hero && !LOCPLINT->localState->isHeroSleeping(hero);
+	const CGHeroInstance *hero = GAME->interface()->localState->getCurrentHero();
+	return optionInMapView() && hero && !GAME->interface()->localState->isHeroSleeping(hero);
 }
 
 bool AdventureMapShortcuts::optionCanVisitObject()
@@ -589,34 +589,34 @@ bool AdventureMapShortcuts::optionCanVisitObject()
 	if (!optionHeroSelected())
 		return false;
 
-	auto * hero = LOCPLINT->localState->getCurrentHero();
-	auto objects = LOCPLINT->cb->getVisitableObjs(hero->visitablePos());
+	auto * hero = GAME->interface()->localState->getCurrentHero();
+	auto objects = GAME->interface()->cb->getVisitableObjs(hero->visitablePos());
 
 	return objects.size() > 1; // there is object other than our hero
 }
 
 bool AdventureMapShortcuts::optionHeroSelected()
 {
-	return optionInMapView() && LOCPLINT->localState->getCurrentHero() != nullptr;
+	return optionInMapView() && GAME->interface()->localState->getCurrentHero() != nullptr;
 }
 
 bool AdventureMapShortcuts::optionHeroCanMove()
 {
-	const auto * hero = LOCPLINT->localState->getCurrentHero();
-	return optionInMapView() && hero && LOCPLINT->localState->hasPath(hero) && LOCPLINT->localState->getPath(hero).nextNode().turns == 0;
+	const auto * hero = GAME->interface()->localState->getCurrentHero();
+	return optionInMapView() && hero && GAME->interface()->localState->hasPath(hero) && GAME->interface()->localState->getPath(hero).nextNode().turns == 0;
 }
 
 bool AdventureMapShortcuts::optionHasNextHero()
 {
-	const auto * hero = LOCPLINT->localState->getCurrentHero();
-	const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero);
+	const auto * hero = GAME->interface()->localState->getCurrentHero();
+	const auto * nextSuitableHero = GAME->interface()->localState->getNextWanderingHero(hero);
 
 	return optionInMapView() && nextSuitableHero != nullptr;
 }
 
 bool AdventureMapShortcuts::optionCanEndTurn()
 {
-	return optionInMapView() && LOCPLINT->makingTurn;
+	return optionInMapView() && GAME->interface()->makingTurn;
 }
 
 bool AdventureMapShortcuts::optionSpellcasting()

+ 6 - 5
client/adventureMap/AdventureMapWidget.cpp

@@ -17,7 +17,8 @@
 #include "CResDataBar.h"
 #include "AdventureState.h"
 
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../mapView/MapView.h"
 #include "../render/IImage.h"
@@ -37,8 +38,8 @@ AdventureMapWidget::AdventureMapWidget( std::shared_ptr<AdventureMapShortcuts> s
 	, mapLevel(0)
 {
 	pos.x = pos.y = 0;
-	pos.w = GH.screenDimensions().x;
-	pos.h = GH.screenDimensions().y;
+	pos.w = ENGINE->screenDimensions().x;
+	pos.h = ENGINE->screenDimensions().y;
 
 	REGISTER_BUILDER("adventureInfobar",         &AdventureMapWidget::buildInfobox         );
 	REGISTER_BUILDER("adventureMapImage",        &AdventureMapWidget::buildMapImage        );
@@ -219,7 +220,7 @@ std::shared_ptr<CIntObject> AdventureMapWidget::buildMapHeroList(const JsonNode
 	Point itemOffset(input["itemsOffset"]["x"].Integer(), input["itemsOffset"]["y"].Integer());
 	int itemsCount = input["itemsCount"].Integer();
 
-	auto result = std::make_shared<CHeroList>(itemsCount, area, item.topLeft() - area.topLeft(), itemOffset, LOCPLINT->localState->getWanderingHeroes().size());
+	auto result = std::make_shared<CHeroList>(itemsCount, area, item.topLeft() - area.topLeft(), itemOffset, GAME->interface()->localState->getWanderingHeroes().size());
 
 
 	if(!input["scrollUp"].isNull())
@@ -252,7 +253,7 @@ std::shared_ptr<CIntObject> AdventureMapWidget::buildMapTownList(const JsonNode
 	Point itemOffset(input["itemsOffset"]["x"].Integer(), input["itemsOffset"]["y"].Integer());
 	int itemsCount = input["itemsCount"].Integer();
 
-	auto result = std::make_shared<CTownList>(itemsCount, area, item.topLeft() - area.topLeft(), itemOffset, LOCPLINT->localState->getOwnedTowns().size());
+	auto result = std::make_shared<CTownList>(itemsCount, area, item.topLeft() - area.topLeft(), itemOffset, GAME->interface()->localState->getOwnedTowns().size());
 
 
 	if(!input["scrollUp"].isNull())

+ 11 - 10
client/adventureMap/AdventureOptions.cpp

@@ -11,17 +11,18 @@
 #include "StdInc.h"
 #include "AdventureOptions.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
 #include "../lobby/CCampaignInfoScreen.h"
 #include "../lobby/CScenarioInfoScreen.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
 
 #include "../../CCallback.h"
+#include "../../lib/GameLibrary.h"
 #include "../../lib/StartInfo.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 
@@ -31,14 +32,14 @@ AdventureOptions::AdventureOptions()
 	OBJECT_CONSTRUCTION;
 
 	viewWorld = std::make_shared<CButton>(Point(24, 23), AnimationPath::builtin("ADVVIEW.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_WORLD);
-	viewWorld->addCallback([] { LOCPLINT->viewWorldMap(); });
+	viewWorld->addCallback([] { GAME->interface()->viewWorldMap(); });
 
 	puzzle = std::make_shared<CButton>(Point(24, 81), AnimationPath::builtin("ADVPUZ.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_VIEW_PUZZLE);
-	puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT));
+	puzzle->addCallback(std::bind(&CPlayerInterface::showPuzzleMap, GAME->interface()));
 
 	dig = std::make_shared<CButton>(Point(24, 139), AnimationPath::builtin("ADVDIG.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_DIG_GRAIL);
-	if(const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero())
-		dig->addCallback(std::bind(&CPlayerInterface::tryDigging, LOCPLINT, h));
+	if(const CGHeroInstance *h = GAME->interface()->localState->getCurrentHero())
+		dig->addCallback(std::bind(&CPlayerInterface::tryDigging, GAME->interface(), h));
 	else
 		dig->block(true);
 
@@ -46,20 +47,20 @@ AdventureOptions::AdventureOptions()
 	scenInfo->addCallback(AdventureOptions::showScenarioInfo);
 	
 	replay = std::make_shared<CButton>(Point(24, 257), AnimationPath::builtin("ADVTURN.DEF"), CButton::tooltip(), [&](){ close(); }, EShortcut::ADVENTURE_REPLAY_TURN);
-	replay->addCallback([]{ LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.replayOpponentTurnNotImplemented")); });
+	replay->addCallback([]{ GAME->interface()->showInfoDialog(LIBRARY->generaltexth->translate("vcmi.adventureMap.replayOpponentTurnNotImplemented")); });
 
 	exit = std::make_shared<CButton>(Point(203, 313), AnimationPath::builtin("IOK6432.DEF"), CButton::tooltip(), std::bind(&AdventureOptions::close, this), EShortcut::GLOBAL_RETURN);
 }
 
 void AdventureOptions::showScenarioInfo()
 {
-	if(LOCPLINT->cb->getStartInfo()->campState)
+	if(GAME->interface()->cb->getStartInfo()->campState)
 	{
-		GH.windows().createAndPushWindow<CCampaignInfoScreen>();
+		ENGINE->windows().createAndPushWindow<CCampaignInfoScreen>();
 	}
 	else
 	{
-		GH.windows().createAndPushWindow<CScenarioInfoScreen>();
+		ENGINE->windows().createAndPushWindow<CScenarioInfoScreen>();
 	}
 }
 

+ 20 - 20
client/adventureMap/CInGameConsole.cpp

@@ -11,12 +11,12 @@
 #include "StdInc.h"
 #include "CInGameConsole.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../CServerHandler.h"
 #include "../GameChatHandler.h"
 #include "../ClientCommandManager.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../gui/Shortcut.h"
 #include "../gui/TextAlignment.h"
@@ -47,7 +47,7 @@ void CInGameConsole::showAll(Canvas & to)
 
 void CInGameConsole::show(Canvas & to)
 {
-	if (LOCPLINT->cingconsole != this)
+	if (GAME->interface()->cingconsole != this)
 		return;
 
 	int number = 0;
@@ -82,7 +82,7 @@ void CInGameConsole::tick(uint32_t msPassed)
 	);
 
 	if(sizeBefore != texts.size())
-		GH.windows().totalRedraw(); // FIXME: ingame console has no parent widget set
+		ENGINE->windows().totalRedraw(); // FIXME: ingame console has no parent widget set
 }
 
 void CInGameConsole::addMessageSilent(const std::string & timeFormatted, const std::string & senderName, const std::string & messageText)
@@ -111,14 +111,14 @@ void CInGameConsole::addMessage(const std::string & timeFormatted, const std::st
 {
 	addMessageSilent(timeFormatted, senderName, messageText);
 
-	GH.windows().totalRedraw(); // FIXME: ingame console has no parent widget set
+	ENGINE->windows().totalRedraw(); // FIXME: ingame console has no parent widget set
 
-	int volume = CCS->soundh->getVolume();
+	int volume = ENGINE->sound().getVolume();
 	if(volume == 0)
-		CCS->soundh->setVolume(settings["general"]["sound"].Integer());
-	int handle = CCS->soundh->playSound(AudioPath::builtin("CHAT"));
+		ENGINE->sound().setVolume(settings["general"]["sound"].Integer());
+	int handle = ENGINE->sound().playSound(AudioPath::builtin("CHAT"));
 	if(volume == 0)
-		CCS->soundh->setCallback(handle, [&]() { if(!GH.screenHandler().hasFocus()) CCS->soundh->setVolume(0); });
+		ENGINE->sound().setCallback(handle, [&]() { if(!ENGINE->screenHandler().hasFocus()) ENGINE->sound().setVolume(0); });
 }
 
 bool CInGameConsole::captureThisKey(EShortcut key)
@@ -143,7 +143,7 @@ bool CInGameConsole::captureThisKey(EShortcut key)
 
 void CInGameConsole::keyPressed (EShortcut key)
 {
-	if (LOCPLINT->cingconsole != this)
+	if (GAME->interface()->cingconsole != this)
 		return;
 
 	if(!isEnteringText() && key != EShortcut::GAME_ACTIVATE_CONSOLE)
@@ -222,7 +222,7 @@ void CInGameConsole::keyPressed (EShortcut key)
 
 void CInGameConsole::textInputted(const std::string & inputtedText)
 {
-	if (LOCPLINT->cingconsole != this)
+	if (GAME->interface()->cingconsole != this)
 		return;
 
 	if(!isEnteringText())
@@ -243,7 +243,7 @@ void CInGameConsole::textEdited(const std::string & inputtedText)
 
 void CInGameConsole::showRecentChatHistory()
 {
-	auto const & history = CSH->getGameChat().getChatHistory();
+	auto const & history = GAME->server().getGameChat().getChatHistory();
 
 	texts.clear();
 
@@ -253,7 +253,7 @@ void CInGameConsole::showRecentChatHistory()
 	for (int i = firstEntryToShow; i < history.size(); ++i)
 		addMessageSilent(history[i].dateFormatted, history[i].senderName, history[i].messageText);
 
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void CInGameConsole::startEnteringText()
@@ -264,20 +264,20 @@ void CInGameConsole::startEnteringText()
 	if(isEnteringText())
 	{
 		// force-reset text input to re-show on-screen keyboard
-		GH.statusbar()->setEnteringMode(false);
-		GH.statusbar()->setEnteringMode(true);
-		GH.statusbar()->setEnteredText(enteredText);
+		ENGINE->statusbar()->setEnteringMode(false);
+		ENGINE->statusbar()->setEnteringMode(true);
+		ENGINE->statusbar()->setEnteredText(enteredText);
 		return;
 	}
 		
 	assert(currentStatusBar.expired());//effectively, nullptr check
 
-	currentStatusBar = GH.statusbar();
+	currentStatusBar = ENGINE->statusbar();
 
 	enteredText = "_";
 
-	GH.statusbar()->setEnteringMode(true);
-	GH.statusbar()->setEnteredText(enteredText);
+	ENGINE->statusbar()->setEnteringMode(true);
+	ENGINE->statusbar()->setEnteredText(enteredText);
 
 	showRecentChatHistory();
 }
@@ -304,7 +304,7 @@ void CInGameConsole::endEnteringText(bool processEnteredText)
 			clientCommandThread.detach();
 		}
 		else
-			CSH->getGameChat().sendMessageGameplay(txt);
+			GAME->server().getGameChat().sendMessageGameplay(txt);
 	}
 	enteredText.clear();
 

+ 43 - 43
client/adventureMap/CInfoBar.cpp

@@ -19,10 +19,10 @@
 #include "../widgets/TextControls.h"
 #include "../widgets/MiscWidgets.h"
 #include "../windows/InfoWindows.h"
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/IScreenHandler.h"
@@ -79,10 +79,10 @@ CInfoBar::VisibleDateInfo::VisibleDateInfo()
 	animation->setDuration(1500);
 
 	std::string labelText;
-	if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) == 1 && LOCPLINT->cb->getDate(Date::DAY) != 1) // monday of any week but first - show new week info
-		labelText = CGI->generaltexth->allTexts[63] + " " + std::to_string(LOCPLINT->cb->getDate(Date::WEEK));
+	if(GAME->interface()->cb->getDate(Date::DAY_OF_WEEK) == 1 && GAME->interface()->cb->getDate(Date::DAY) != 1) // monday of any week but first - show new week info
+		labelText = LIBRARY->generaltexth->allTexts[63] + " " + std::to_string(GAME->interface()->cb->getDate(Date::WEEK));
 	else
-		labelText = CGI->generaltexth->allTexts[64] + " " + std::to_string(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK));
+		labelText = LIBRARY->generaltexth->allTexts[64] + " " + std::to_string(GAME->interface()->cb->getDate(Date::DAY_OF_WEEK));
 
 	label = std::make_shared<CLabel>(95, 31, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, labelText);
 
@@ -91,13 +91,13 @@ CInfoBar::VisibleDateInfo::VisibleDateInfo()
 
 AnimationPath CInfoBar::VisibleDateInfo::getNewDayName()
 {
-	if(LOCPLINT->cb->getDate(Date::DAY) == 1)
+	if(GAME->interface()->cb->getDate(Date::DAY) == 1)
 		return AnimationPath::builtin("NEWDAY");
 
-	if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1)
+	if(GAME->interface()->cb->getDate(Date::DAY_OF_WEEK) != 1)
 		return AnimationPath::builtin("NEWDAY");
 
-	switch(LOCPLINT->cb->getDate(Date::WEEK))
+	switch(GAME->interface()->cb->getDate(Date::WEEK))
 	{
 	case 1:
 		return AnimationPath::builtin("NEWWEEK1");
@@ -126,7 +126,7 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
 	OBJECT_CONSTRUCTION;
 	//get amount of halls of each level
 	std::vector<int> halls(4, 0);
-	for(auto town : LOCPLINT->localState->getOwnedTowns())
+	for(auto town : GAME->interface()->localState->getOwnedTowns())
 	{
 		int hallLevel = town->hallLevel();
 		//negative value means no village hall, unlikely but possible
@@ -140,9 +140,9 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
 	//generate list of allies and enemies
 	for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
 	{
-		if(LOCPLINT->cb->getPlayerStatus(PlayerColor(i), false) == EPlayerStatus::INGAME)
+		if(GAME->interface()->cb->getPlayerStatus(PlayerColor(i), false) == EPlayerStatus::INGAME)
 		{
-			if(LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
+			if(GAME->interface()->cb->getPlayerRelations(GAME->interface()->playerID, PlayerColor(i)) != PlayerRelations::ENEMIES)
 				allies.push_back(PlayerColor(i));
 			else
 				enemies.push_back(PlayerColor(i));
@@ -151,8 +151,8 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
 
 	//generate widgets
 	background = std::make_shared<CPicture>(ImagePath::builtin("ADSTATIN"));
-	allyLabel = std::make_shared<CLabel>(10, 106, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[390] + ":");
-	enemyLabel = std::make_shared<CLabel>(10, 136, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[391] + ":");
+	allyLabel = std::make_shared<CLabel>(10, 106, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[390] + ":");
+	enemyLabel = std::make_shared<CLabel>(10, 136, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[391] + ":");
 
 	int posx = allyLabel->pos.w + allyLabel->pos.x - pos.x + 4;
 	for(PlayerColor & player : allies)
@@ -230,43 +230,43 @@ CInfoBar::VisibleComponentInfo::VisibleComponentInfo(const std::vector<Component
 
 void CInfoBar::playNewDaySound()
 {
-	int volume = CCS->soundh->getVolume();
+	int volume = ENGINE->sound().getVolume();
 	int handle = -1;
 	if(volume == 0)
-		CCS->soundh->setVolume(settings["general"]["sound"].Integer());
-
-	if(LOCPLINT->cb->getDate(Date::DAY_OF_WEEK) != 1) // not first day of the week
-		handle = CCS->soundh->playSound(soundBase::newDay);
-	else if(LOCPLINT->cb->getDate(Date::WEEK) != 1) // not first week in month
-		handle = CCS->soundh->playSound(soundBase::newWeek);
-	else if(LOCPLINT->cb->getDate(Date::MONTH) != 1) // not first month
-		handle = CCS->soundh->playSound(soundBase::newMonth);
+		ENGINE->sound().setVolume(settings["general"]["sound"].Integer());
+
+	if(GAME->interface()->cb->getDate(Date::DAY_OF_WEEK) != 1) // not first day of the week
+		handle = ENGINE->sound().playSound(soundBase::newDay);
+	else if(GAME->interface()->cb->getDate(Date::WEEK) != 1) // not first week in month
+		handle = ENGINE->sound().playSound(soundBase::newWeek);
+	else if(GAME->interface()->cb->getDate(Date::MONTH) != 1) // not first month
+		handle = ENGINE->sound().playSound(soundBase::newMonth);
 	else
-		handle = CCS->soundh->playSound(soundBase::newDay);
+		handle = ENGINE->sound().playSound(soundBase::newDay);
 
 	if(volume == 0)
-		CCS->soundh->setCallback(handle, [&]() { if(!GH.screenHandler().hasFocus()) CCS->soundh->setVolume(0); });
+		ENGINE->sound().setCallback(handle, [&]() { if(!ENGINE->screenHandler().hasFocus()) ENGINE->sound().setVolume(0); });
 }
 
 void CInfoBar::reset()
 {
 	OBJECT_CONSTRUCTION;
-	state = EMPTY;
+	state = EState::EMPTY;
 	visibleInfo = std::make_shared<EmptyVisibleInfo>();
 }
 
 void CInfoBar::showSelection()
 {
 	OBJECT_CONSTRUCTION;
-	if(LOCPLINT->localState->getCurrentHero())
+	if(GAME->interface()->localState->getCurrentHero())
 	{
-		showHeroSelection(LOCPLINT->localState->getCurrentHero());
+		showHeroSelection(GAME->interface()->localState->getCurrentHero());
 		return;
 	}
 
-	if(LOCPLINT->localState->getCurrentTown())
+	if(GAME->interface()->localState->getCurrentTown())
 	{
-		showTownSelection(LOCPLINT->localState->getCurrentTown());
+		showTownSelection(GAME->interface()->localState->getCurrentTown());
 		return;
 	}
 
@@ -281,7 +281,7 @@ void CInfoBar::tick(uint32_t msPassed)
 	{
 		timerCounter = 0;
 		removeUsedEvents(TIME);
-		if(GH.windows().isTopWindow(adventureInt))
+		if(ENGINE->windows().isTopWindow(adventureInt))
 			popComponents(true);
 	}
 	else
@@ -295,12 +295,12 @@ void CInfoBar::clickReleased(const Point & cursorPosition, bool lastActivated)
 	timerCounter = 0;
 	removeUsedEvents(TIME); //expiration trigger from just clicked element is not valid anymore
 
-	if(state == HERO || state == TOWN)
+	if(state == EState::HERO || state == EState::TOWN)
 	{
 		if(lastActivated)
 			showGameStatus();
 	}
-	else if(state == GAME)
+	else if(state == EState::GAME)
 		showDate();
 	else
 		popComponents(true);
@@ -308,21 +308,21 @@ void CInfoBar::clickReleased(const Point & cursorPosition, bool lastActivated)
 
 void CInfoBar::showPopupWindow(const Point & cursorPosition)
 {
-	CRClickPopup::createAndPush(CGI->generaltexth->allTexts[109]);
+	CRClickPopup::createAndPush(LIBRARY->generaltexth->allTexts[109]);
 }
 
 void CInfoBar::hover(bool on)
 {
 	if(on)
-		GH.statusbar()->write(CGI->generaltexth->zelp[292].first);
+		ENGINE->statusbar()->write(LIBRARY->generaltexth->zelp[292].first);
 	else
-		GH.statusbar()->clear();
+		ENGINE->statusbar()->clear();
 }
 
 CInfoBar::CInfoBar(const Rect & position)
 	: CIntObject(LCLICK | SHOW_POPUP | HOVER, position.topLeft()),
 	timerCounter(0),
-	state(EMPTY),
+	state(EState::EMPTY),
 	listener(settings.listen["gameTweaks"]["infoBarCreatureManagement"])
 {
 	OBJECT_CONSTRUCTION;
@@ -351,7 +351,7 @@ void CInfoBar::showDate()
 {
 	OBJECT_CONSTRUCTION;
 	playNewDaySound();
-	state = DATE;
+	state = EState::DATE;
 	visibleInfo = std::make_shared<VisibleDateInfo>();
 	setTimer(3000); // confirmed to match H3
 	redraw();
@@ -480,7 +480,7 @@ void CInfoBar::popComponents(bool remove)
 		componentsQueue.pop();
 	if(!componentsQueue.empty())
 	{
-		state = COMPONENT;
+		state = EState::COMPONENT;
 		const auto & extracted = componentsQueue.front();
 		visibleInfo = std::make_shared<VisibleComponentInfo>(extracted.first);
 		setTimer(extracted.second);
@@ -498,13 +498,13 @@ void CInfoBar::pushComponents(const std::vector<Component> & comps, std::string
 
 bool CInfoBar::showingComponents()
 {
-	return state == COMPONENT;
+	return state == EState::COMPONENT;
 }
 
 void CInfoBar::startEnemyTurn(PlayerColor color)
 {
 	OBJECT_CONSTRUCTION;
-	state = AITURN;
+	state = EState::AITURN;
 	visibleInfo = std::make_shared<VisibleEnemyTurnInfo>(color);
 	redraw();
 }
@@ -518,7 +518,7 @@ void CInfoBar::showHeroSelection(const CGHeroInstance * hero)
 	}
 	else
 	{
-		state = HERO;
+		state = EState::HERO;
 		visibleInfo = std::make_shared<VisibleHeroInfo>(hero);
 	}
 	redraw();
@@ -533,7 +533,7 @@ void CInfoBar::showTownSelection(const CGTownInstance * town)
 	}
 	else
 	{
-		state = TOWN;
+		state = EState::TOWN;
 		visibleInfo = std::make_shared<VisibleTownInfo>(town);
 	}
 	redraw();
@@ -542,7 +542,7 @@ void CInfoBar::showTownSelection(const CGTownInstance * town)
 void CInfoBar::showGameStatus()
 {
 	OBJECT_CONSTRUCTION;
-	state = GAME;
+	state = EState::GAME;
 	visibleInfo = std::make_shared<VisibleGameStatusInfo>();
 	setTimer(3000);
 	redraw();

+ 1 - 1
client/adventureMap/CInfoBar.h

@@ -136,7 +136,7 @@ private:
 		VisibleComponentInfo(const std::vector<Component> & compsToDisplay, std::string message, int textH, bool tiny);
 	};
 
-	enum EState
+	enum class EState
 	{
 		EMPTY, HERO, TOWN, DATE, GAME, AITURN, COMPONENT
 	};

+ 48 - 48
client/adventureMap/CList.cpp

@@ -19,10 +19,10 @@
 #include "../widgets/RadialMenu.h"
 #include "../windows/InfoWindows.h"
 #include "../windows/CCastleInterface.h"
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../PlayerLocalState.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../render/Canvas.h"
@@ -66,9 +66,9 @@ void CList::CListItem::clickPressed(const Point & cursorPosition)
 void CList::CListItem::hover(bool on)
 {
 	if (on)
-		GH.statusbar()->write(getHoverText());
+		ENGINE->statusbar()->write(getHoverText());
 	else
-		GH.statusbar()->clear();
+		ENGINE->statusbar()->clear();
 }
 
 void CList::CListItem::onSelect(bool on)
@@ -250,22 +250,22 @@ std::shared_ptr<CIntObject> CHeroList::CHeroItem::genSelection()
 void CHeroList::CHeroItem::select(bool on)
 {
 	if(on)
-		LOCPLINT->localState->setSelection(hero);
+		GAME->interface()->localState->setSelection(hero);
 }
 
 void CHeroList::CHeroItem::open()
 {
-	LOCPLINT->openHeroWindow(hero);
+	GAME->interface()->openHeroWindow(hero);
 }
 
 void CHeroList::CHeroItem::showTooltip()
 {
-	CRClickPopup::createAndPush(hero, GH.getCursorPosition());
+	CRClickPopup::createAndPush(hero, ENGINE->getCursorPosition());
 }
 
 std::string CHeroList::CHeroItem::getHoverText()
 {
-	return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->getClassNameTranslated()) + hero->getMovementPointsTextIfOwner(hero->getOwner());
+	return boost::str(boost::format(LIBRARY->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->getClassNameTranslated()) + hero->getMovementPointsTextIfOwner(hero->getOwner());
 }
 
 void CHeroList::CHeroItem::gesture(bool on, const Point & initialPosition, const Point & finalPosition)
@@ -276,7 +276,7 @@ void CHeroList::CHeroItem::gesture(bool on, const Point & initialPosition, const
 	if(!hero)
 		return;
 
-	auto & heroes = LOCPLINT->localState->getWanderingHeroes();
+	auto & heroes = GAME->interface()->localState->getWanderingHeroes();
 
 	if(heroes.size() < 2)
 		return;
@@ -289,18 +289,18 @@ void CHeroList::CHeroItem::gesture(bool on, const Point & initialPosition, const
 		{ RadialMenuConfig::ITEM_ALT_NN, heroUpper != nullptr, "altUpTop", "vcmi.radialWheel.moveTop", [heroPos]()
 		{
 			for (size_t i = heroPos; i > 0; i--)
-				LOCPLINT->localState->swapWanderingHero(i, i - 1);
+				GAME->interface()->localState->swapWanderingHero(i, i - 1);
 		} },
-		{ RadialMenuConfig::ITEM_ALT_NW, heroUpper != nullptr, "altUp", "vcmi.radialWheel.moveUp", [heroPos](){LOCPLINT->localState->swapWanderingHero(heroPos, heroPos - 1); } },
-		{ RadialMenuConfig::ITEM_ALT_SW, heroLower != nullptr, "altDown", "vcmi.radialWheel.moveDown", [heroPos](){ LOCPLINT->localState->swapWanderingHero(heroPos, heroPos + 1); } },
+		{ RadialMenuConfig::ITEM_ALT_NW, heroUpper != nullptr, "altUp", "vcmi.radialWheel.moveUp", [heroPos](){GAME->interface()->localState->swapWanderingHero(heroPos, heroPos - 1); } },
+		{ RadialMenuConfig::ITEM_ALT_SW, heroLower != nullptr, "altDown", "vcmi.radialWheel.moveDown", [heroPos](){ GAME->interface()->localState->swapWanderingHero(heroPos, heroPos + 1); } },
 		{ RadialMenuConfig::ITEM_ALT_SS, heroLower != nullptr, "altDownBottom", "vcmi.radialWheel.moveBottom", [heroPos, heroes]()
 		{
 			for (int i = heroPos; i < heroes.size() - 1; i++)
-				LOCPLINT->localState->swapWanderingHero(i, i + 1);
+				GAME->interface()->localState->swapWanderingHero(i, i + 1);
 		} },
 	};
 
-	GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
+	ENGINE->windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
 }
 
 void CHeroList::CHeroItem::keyPressed(EShortcut key)
@@ -311,11 +311,11 @@ void CHeroList::CHeroItem::keyPressed(EShortcut key)
 	if(parent->selected != this->shared_from_this())
 		return;
 
-	auto & heroes = LOCPLINT->localState->getWanderingHeroes();
+	auto & heroes = GAME->interface()->localState->getWanderingHeroes();
 
 	if(key == EShortcut::LIST_HERO_DISMISS)
 	{
-		LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22], [=](){ LOCPLINT->cb->dismissHero(hero); }, nullptr);
+		GAME->interface()->showYesNoDialog(LIBRARY->generaltexth->allTexts[22], [=](){ GAME->interface()->cb->dismissHero(hero); }, nullptr);
 		return;
 	}
 
@@ -330,32 +330,32 @@ void CHeroList::CHeroItem::keyPressed(EShortcut key)
 	{
 	case EShortcut::LIST_HERO_UP:
 		if(heroUpper)
-			LOCPLINT->localState->swapWanderingHero(heroPos, heroPos - 1);
+			GAME->interface()->localState->swapWanderingHero(heroPos, heroPos - 1);
 		break;
 
 	case EShortcut::LIST_HERO_DOWN:
 		if(heroLower)
-			LOCPLINT->localState->swapWanderingHero(heroPos, heroPos + 1);
+			GAME->interface()->localState->swapWanderingHero(heroPos, heroPos + 1);
 		break;
 
 	case EShortcut::LIST_HERO_TOP:
 		if(heroUpper)
 			for (size_t i = heroPos; i > 0; i--)
-				LOCPLINT->localState->swapWanderingHero(i, i - 1);
+				GAME->interface()->localState->swapWanderingHero(i, i - 1);
 		break;
 
 	case EShortcut::LIST_HERO_BOTTOM:
 		if(heroLower)
 			for (int i = heroPos; i < heroes.size() - 1; i++)
-				LOCPLINT->localState->swapWanderingHero(i, i + 1);
+				GAME->interface()->localState->swapWanderingHero(i, i + 1);
 		break;
 	}
 }
 
 std::shared_ptr<CIntObject> CHeroList::createItem(size_t index)
 {
-	if (LOCPLINT->localState->getWanderingHeroes().size() > index)
-		return std::make_shared<CHeroItem>(this, LOCPLINT->localState->getWanderingHero(index));
+	if (GAME->interface()->localState->getWanderingHeroes().size() > index)
+		return std::make_shared<CHeroItem>(this, GAME->interface()->localState->getWanderingHero(index));
 	return std::make_shared<CEmptyHeroItem>();
 }
 
@@ -367,7 +367,7 @@ CHeroList::CHeroList(int visibleItemsCount, Rect widgetPosition, Point firstItem
 
 void CHeroList::select(const CGHeroInstance * hero)
 {
-	selectIndex(vstd::find_pos(LOCPLINT->localState->getWanderingHeroes(), hero));
+	selectIndex(vstd::find_pos(GAME->interface()->localState->getWanderingHeroes(), hero));
 }
 
 void CHeroList::updateElement(const CGHeroInstance * hero)
@@ -377,7 +377,7 @@ void CHeroList::updateElement(const CGHeroInstance * hero)
 
 void CHeroList::updateWidget()
 {
-	const auto & heroes = LOCPLINT->localState->getWanderingHeroes();
+	const auto & heroes = GAME->interface()->localState->getWanderingHeroes();
 
 	listBox->resize(heroes.size());
 
@@ -399,16 +399,16 @@ void CHeroList::updateWidget()
 		}
 	}
 
-	if (LOCPLINT->localState->getCurrentHero())
-		select(LOCPLINT->localState->getCurrentHero());
+	if (GAME->interface()->localState->getCurrentHero())
+		select(GAME->interface()->localState->getCurrentHero());
 
 	CList::update();
 }
 
 std::shared_ptr<CIntObject> CTownList::createItem(size_t index)
 {
-	if (LOCPLINT->localState->getOwnedTowns().size() > index)
-		return std::make_shared<CTownItem>(this, LOCPLINT->localState->getOwnedTown(index));
+	if (GAME->interface()->localState->getOwnedTowns().size() > index)
+		return std::make_shared<CTownItem>(this, GAME->interface()->localState->getOwnedTown(index));
 	return std::make_shared<CAnimImage>(AnimationPath::builtin("ITPA"), 0);
 }
 
@@ -431,7 +431,7 @@ std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
 
 void CTownList::CTownItem::update()
 {
-	size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
+	size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= GAME->interface()->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
 
 	picture->setFrame(iconIndex + 2);
 	redraw();
@@ -440,12 +440,12 @@ void CTownList::CTownItem::update()
 void CTownList::CTownItem::select(bool on)
 {
 	if(on)
-		LOCPLINT->localState->setSelection(town);
+		GAME->interface()->localState->setSelection(town);
 }
 
 void CTownList::CTownItem::open()
 {
-	LOCPLINT->openTownWindow(town);
+	GAME->interface()->openTownWindow(town);
 }
 
 void CTownList::CTownItem::showTooltip()
@@ -458,7 +458,7 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
 	if(!on)
 		return;
 
-	const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
+	const std::vector<const CGTownInstance *> towns = GAME->interface()->localState->getOwnedTowns();
 	size_t townIndex = vstd::find_pos(towns, town);
 
 	if(townIndex + 1 > towns.size() || !towns.at(townIndex))
@@ -471,7 +471,7 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
 	int townLowerPos = (townIndex > towns.size() - 2) ? -1 : townIndex + 1;
 
 	auto updateList = [](){
-		for (auto ci : GH.windows().findWindows<CCastleInterface>())
+		for (auto ci : ENGINE->windows().findWindows<CCastleInterface>())
 		{
 			ci->townlist->updateWidget();
 			ci->townlist->select(ci->town);
@@ -482,20 +482,20 @@ void CTownList::CTownItem::gesture(bool on, const Point & initialPosition, const
 		{ RadialMenuConfig::ITEM_ALT_NN, townUpperPos > -1, "altUpTop", "vcmi.radialWheel.moveTop", [updateList, townIndex]()
 		{
 			for (int i = townIndex; i > 0; i--)
-				LOCPLINT->localState->swapOwnedTowns(i, i - 1);
+				GAME->interface()->localState->swapOwnedTowns(i, i - 1);
 			updateList();
 		} },
-		{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.moveUp", [updateList, townIndex, townUpperPos](){LOCPLINT->localState->swapOwnedTowns(townIndex, townUpperPos); updateList(); } },
-		{ RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.moveDown", [updateList, townIndex, townLowerPos](){ LOCPLINT->localState->swapOwnedTowns(townIndex, townLowerPos); updateList(); } },
+		{ RadialMenuConfig::ITEM_ALT_NW, townUpperPos > -1, "altUp", "vcmi.radialWheel.moveUp", [updateList, townIndex, townUpperPos](){GAME->interface()->localState->swapOwnedTowns(townIndex, townUpperPos); updateList(); } },
+		{ RadialMenuConfig::ITEM_ALT_SW, townLowerPos > -1, "altDown", "vcmi.radialWheel.moveDown", [updateList, townIndex, townLowerPos](){ GAME->interface()->localState->swapOwnedTowns(townIndex, townLowerPos); updateList(); } },
 		{ RadialMenuConfig::ITEM_ALT_SS, townLowerPos > -1, "altDownBottom", "vcmi.radialWheel.moveBottom", [updateList, townIndex, towns]()
 		{
 			for (int i = townIndex; i < towns.size() - 1; i++)
-				LOCPLINT->localState->swapOwnedTowns(i, i + 1);
+				GAME->interface()->localState->swapOwnedTowns(i, i + 1);
 			updateList();
 		} },
 	};
 
-	GH.windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
+	ENGINE->windows().createAndPushWindow<RadialMenu>(pos.center(), menuElements, true);
 }
 
 void CTownList::CTownItem::keyPressed(EShortcut key)
@@ -503,7 +503,7 @@ void CTownList::CTownItem::keyPressed(EShortcut key)
 	if(parent->selected != this->shared_from_this())
 		return;
 
-	const std::vector<const CGTownInstance *> towns = LOCPLINT->localState->getOwnedTowns();
+	const std::vector<const CGTownInstance *> towns = GAME->interface()->localState->getOwnedTowns();
 	size_t townIndex = vstd::find_pos(towns, town);
 
 	if(townIndex + 1 > towns.size() || !towns.at(townIndex))
@@ -519,28 +519,28 @@ void CTownList::CTownItem::keyPressed(EShortcut key)
 	{
 	case EShortcut::LIST_TOWN_UP:
 		if(townUpperPos > -1)
-			LOCPLINT->localState->swapOwnedTowns(townIndex, townUpperPos);
+			GAME->interface()->localState->swapOwnedTowns(townIndex, townUpperPos);
 		break;
 
 	case EShortcut::LIST_TOWN_DOWN:
 		if(townLowerPos > -1)
-			LOCPLINT->localState->swapOwnedTowns(townIndex, townLowerPos);
+			GAME->interface()->localState->swapOwnedTowns(townIndex, townLowerPos);
 		break;
 
 	case EShortcut::LIST_TOWN_TOP:
 		if(townUpperPos > -1)
 			for (int i = townIndex; i > 0; i--)
-				LOCPLINT->localState->swapOwnedTowns(i, i - 1);
+				GAME->interface()->localState->swapOwnedTowns(i, i - 1);
 		break;
 
 	case EShortcut::LIST_TOWN_BOTTOM:
 		if(townLowerPos > -1)
 			for (int i = townIndex; i < towns.size() - 1; i++)
-				LOCPLINT->localState->swapOwnedTowns(i, i + 1);
+				GAME->interface()->localState->swapOwnedTowns(i, i + 1);
 		break;
 	}
 
-	for (auto ki : GH.windows().findWindows<CCastleInterface>())
+	for (auto ki : ENGINE->windows().findWindows<CCastleInterface>())
 		ki->townChange(); //update list
 }
 
@@ -557,7 +557,7 @@ CTownList::CTownList(int visibleItemsCount, Rect widgetPosition, Point firstItem
 
 void CTownList::select(const CGTownInstance * town)
 {
-	selectIndex(vstd::find_pos(LOCPLINT->localState->getOwnedTowns(), town));
+	selectIndex(vstd::find_pos(GAME->interface()->localState->getOwnedTowns(), town));
 }
 
 void CTownList::updateElement(const CGTownInstance * town)
@@ -567,7 +567,7 @@ void CTownList::updateElement(const CGTownInstance * town)
 
 void CTownList::updateWidget()
 {
-	auto & towns = LOCPLINT->localState->getOwnedTowns();
+	auto & towns = GAME->interface()->localState->getOwnedTowns();
 
 	listBox->resize(towns.size());
 
@@ -589,8 +589,8 @@ void CTownList::updateWidget()
 		}
 	}
 
-	if (LOCPLINT->localState->getCurrentTown())
-		select(LOCPLINT->localState->getCurrentTown());
+	if (GAME->interface()->localState->getCurrentTown())
+		select(GAME->interface()->localState->getCurrentTown());
 
 	CList::update();
 }

+ 14 - 14
client/adventureMap/CMinimap.cpp

@@ -14,9 +14,9 @@
 #include "AdventureMapInterface.h"
 
 #include "../widgets/Images.h"
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/MouseButton.h"
 #include "../gui/WindowHandler.h"
 #include "../render/Colors.h"
@@ -32,7 +32,7 @@
 
 ColorRGBA CMinimapInstance::getTileColor(const int3 & pos) const
 {
-	const TerrainTile * tile = LOCPLINT->cb->getTile(pos, false);
+	const TerrainTile * tile = GAME->interface()->cb->getTile(pos, false);
 
 	// if tile is not visible it will be black on minimap
 	if(!tile)
@@ -63,7 +63,7 @@ void CMinimapInstance::refreshTile(const int3 &tile)
 
 void CMinimapInstance::redrawMinimap()
 {
-	int3 mapSizes = LOCPLINT->cb->getMapSize();
+	int3 mapSizes = GAME->interface()->cb->getMapSize();
 
 	for (int y = 0; y < mapSizes.y; ++y)
 		for (int x = 0; x < mapSizes.x; ++x)
@@ -71,7 +71,7 @@ void CMinimapInstance::redrawMinimap()
 }
 
 CMinimapInstance::CMinimapInstance(const Point & position, const Point & dimensions, int Level):
-	minimap(new Canvas(Point(LOCPLINT->cb->getMapSize().x, LOCPLINT->cb->getMapSize().y), CanvasScalingPolicy::IGNORE)),
+	minimap(new Canvas(Point(GAME->interface()->cb->getMapSize().x, GAME->interface()->cb->getMapSize().y), CanvasScalingPolicy::IGNORE)),
 	level(Level)
 {
 	pos += position;
@@ -93,10 +93,10 @@ CMinimap::CMinimap(const Rect & position)
 {
 	OBJECT_CONSTRUCTION;
 
-	double maxSideLengthSrc = std::max(LOCPLINT->cb->getMapSize().x, LOCPLINT->cb->getMapSize().y);
+	double maxSideLengthSrc = std::max(GAME->interface()->cb->getMapSize().x, GAME->interface()->cb->getMapSize().y);
 	double maxSideLengthDst = std::max(position.w, position.h);
 	double resize = maxSideLengthSrc / maxSideLengthDst;
-	Point newMinimapSize(LOCPLINT->cb->getMapSize().x/ resize, LOCPLINT->cb->getMapSize().y / resize);
+	Point newMinimapSize(GAME->interface()->cb->getMapSize().x/ resize, GAME->interface()->cb->getMapSize().y / resize);
 	Point offset = Point((std::max(newMinimapSize.x, newMinimapSize.y) - newMinimapSize.x) / 2, (std::max(newMinimapSize.x, newMinimapSize.y) - newMinimapSize.y) / 2);
 
 	pos.x += offset.x;
@@ -114,7 +114,7 @@ int3 CMinimap::pixelToTile(const Point & cursorPos) const
 	double dx = static_cast<double>(cursorPos.x) / pos.w;
 	double dy = static_cast<double>(cursorPos.y) / pos.h;
 
-	int3 mapSizes = LOCPLINT->cb->getMapSize();
+	int3 mapSizes = GAME->interface()->cb->getMapSize();
 
 	int tileX(std::round(mapSizes.x * dx));
 	int tileY(std::round(mapSizes.y * dy));
@@ -124,7 +124,7 @@ int3 CMinimap::pixelToTile(const Point & cursorPos) const
 
 Point CMinimap::tileToPixels(const int3 &tile) const
 {
-	int3 mapSizes = LOCPLINT->cb->getMapSize();
+	int3 mapSizes = GAME->interface()->cb->getMapSize();
 
 	double stepX = static_cast<double>(pos.w) / mapSizes.x;
 	double stepY = static_cast<double>(pos.h) / mapSizes.y;
@@ -141,7 +141,7 @@ void CMinimap::moveAdvMapSelection(const Point & positionGlobal)
 	adventureInt->centerOnTile(newLocation);
 
 	if (!(adventureInt->isActive()))
-		GH.windows().totalRedraw(); //redraw this as well as inactive adventure map
+		ENGINE->windows().totalRedraw(); //redraw this as well as inactive adventure map
 	else
 		redraw();//redraw only this
 }
@@ -159,15 +159,15 @@ void CMinimap::clickPressed(const Point & cursorPosition)
 
 void CMinimap::showPopupWindow(const Point & cursorPosition)
 {
-	CRClickPopup::createAndPush(CGI->generaltexth->zelp[291].second);
+	CRClickPopup::createAndPush(LIBRARY->generaltexth->zelp[291].second);
 }
 
 void CMinimap::hover(bool on)
 {
 	if(on)
-		GH.statusbar()->write(CGI->generaltexth->zelp[291].first);
+		ENGINE->statusbar()->write(LIBRARY->generaltexth->zelp[291].first);
 	else
-		GH.statusbar()->clear();
+		ENGINE->statusbar()->clear();
 }
 
 void CMinimap::mouseDragged(const Point & cursorPosition, const Point & lastUpdateDistance)
@@ -182,7 +182,7 @@ void CMinimap::showAll(Canvas & to)
 
 	if(minimap)
 	{
-		int3 mapSizes = LOCPLINT->cb->getMapSize();
+		int3 mapSizes = GAME->interface()->cb->getMapSize();
 
 		//draw radar
 		Rect radar =

+ 8 - 7
client/adventureMap/CResDataBar.cpp

@@ -10,12 +10,12 @@
 #include "StdInc.h"
 #include "CResDataBar.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../render/Canvas.h"
 #include "../render/Colors.h"
 #include "../render/EFont.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/TextAlignment.h"
 #include "../widgets/Images.h"
 
@@ -23,6 +23,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/ResourceSet.h"
+#include "../../lib/GameLibrary.h"
 
 CResDataBar::CResDataBar(const ImagePath & imageName, const Point & position)
 {
@@ -31,7 +32,7 @@ CResDataBar::CResDataBar(const ImagePath & imageName, const Point & position)
 
 	OBJECT_CONSTRUCTION;
 	background = std::make_shared<CPicture>(imageName, 0, 0);
-	background->setPlayerColor(LOCPLINT->playerID);
+	background->setPlayerColor(GAME->interface()->playerID);
 
 	pos.w = background->pos.w;
 	pos.h = background->pos.h;
@@ -61,9 +62,9 @@ std::string CResDataBar::buildDateString()
 	std::string pattern = "%s: %d, %s: %d, %s: %d";
 
 	auto formatted = boost::format(pattern)
-		% CGI->generaltexth->translate("core.genrltxt.62") % LOCPLINT->cb->getDate(Date::MONTH)
-		% CGI->generaltexth->translate("core.genrltxt.63") % LOCPLINT->cb->getDate(Date::WEEK)
-		% CGI->generaltexth->translate("core.genrltxt.64") % LOCPLINT->cb->getDate(Date::DAY_OF_WEEK);
+		% LIBRARY->generaltexth->translate("core.genrltxt.62") % GAME->interface()->cb->getDate(Date::MONTH)
+		% LIBRARY->generaltexth->translate("core.genrltxt.63") % GAME->interface()->cb->getDate(Date::WEEK)
+		% LIBRARY->generaltexth->translate("core.genrltxt.64") % GAME->interface()->cb->getDate(Date::DAY_OF_WEEK);
 
 	return boost::str(formatted);
 }
@@ -75,7 +76,7 @@ void CResDataBar::showAll(Canvas & to)
 	//TODO: all this should be labels, but they require proper text update on change
 	for (auto & entry : resourcePositions)
 	{
-		std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(entry.first));
+		std::string text = std::to_string(GAME->interface()->cb->getResourceAmount(entry.first));
 
 		to.drawText(pos.topLeft() + entry.second, FONT_SMALL, Colors::WHITE, ETextAlignment::TOPLEFT, text);
 	}

+ 23 - 22
client/adventureMap/MapAudioPlayer.cpp

@@ -11,8 +11,9 @@
 #include "MapAudioPlayer.h"
 
 #include "../CCallback.h"
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../mapView/mapHandler.h"
 #include "../media/IMusicPlayer.h"
 #include "../media/ISoundPlayer.h"
@@ -83,7 +84,7 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
 			{
 				int3 currTile(obj->anchorPos().x - fx, obj->anchorPos().y - fy, obj->anchorPos().z);
 
-				if(LOCPLINT->cb->isInTheMap(currTile) && obj->coveringAt(currTile))
+				if(GAME->interface()->cb->isInTheMap(currTile) && obj->coveringAt(currTile))
 					objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
 			}
 		}
@@ -95,7 +96,7 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
 		// visitable object - visitable tile acts as sound source
 		int3 currTile = obj->visitablePos();
 
-		if(LOCPLINT->cb->isInTheMap(currTile))
+		if(GAME->interface()->cb->isInTheMap(currTile))
 			objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
 
 		return;
@@ -110,7 +111,7 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
 		{
 			int3 currTile = obj->anchorPos() + tile;
 
-			if(LOCPLINT->cb->isInTheMap(currTile))
+			if(GAME->interface()->cb->isInTheMap(currTile))
 				objects[currTile.z][currTile.x][currTile.y].push_back(obj->id);
 		}
 		return;
@@ -119,9 +120,9 @@ void MapAudioPlayer::addObject(const CGObjectInstance * obj)
 
 void MapAudioPlayer::removeObject(const CGObjectInstance * obj)
 {
-	for(int z = 0; z < LOCPLINT->cb->getMapSize().z; z++)
-		for(int x = 0; x < LOCPLINT->cb->getMapSize().x; x++)
-			for(int y = 0; y < LOCPLINT->cb->getMapSize().y; y++)
+	for(int z = 0; z < GAME->interface()->cb->getMapSize().z; z++)
+		for(int x = 0; x < GAME->interface()->cb->getMapSize().x; x++)
+			for(int y = 0; y < GAME->interface()->cb->getMapSize().y; y++)
 				vstd::erase(objects[z][x][y], obj->id);
 }
 
@@ -131,7 +132,7 @@ std::vector<AudioPath> MapAudioPlayer::getAmbientSounds(const int3 & tile)
 
 	for(auto & objectID : objects[tile.z][tile.x][tile.y])
 	{
-		const auto & object = CGI->mh->getMap()->objects[objectID.getNum()];
+		const auto & object = GAME->map().getMap()->objects[objectID.getNum()];
 
 		assert(object);
 		if (!object)
@@ -145,7 +146,7 @@ std::vector<AudioPath> MapAudioPlayer::getAmbientSounds(const int3 & tile)
 		}
 	}
 
-	if(CGI->mh->getMap()->isCoastalTile(tile))
+	if(GAME->map().getMap()->isCoastalTile(tile))
 		result.emplace_back(AudioPath::builtin("LOOPOCEA"));
 
 	return result;
@@ -164,7 +165,7 @@ void MapAudioPlayer::updateAmbientSounds()
 
 	int3 pos = currentSelection->getSightCenter();
 	std::unordered_set<int3> tiles;
-	LOCPLINT->cb->getVisibleTilesInRange(tiles, pos, CCS->soundh->ambientGetRange(), int3::DIST_CHEBYSHEV);
+	GAME->interface()->cb->getVisibleTilesInRange(tiles, pos, ENGINE->sound().ambientGetRange(), int3::DIST_CHEBYSHEV);
 	for(int3 tile : tiles)
 	{
 		int dist = pos.dist(tile, int3::DIST_CHEBYSHEV);
@@ -172,22 +173,22 @@ void MapAudioPlayer::updateAmbientSounds()
 		for(auto & soundName : getAmbientSounds(tile))
 			updateSounds(soundName, dist);
 	}
-	CCS->soundh->ambientUpdateChannels(currentSounds);
+	ENGINE->sound().ambientUpdateChannels(currentSounds);
 }
 
 void MapAudioPlayer::updateMusic()
 {
 	if(audioPlaying && playerMakingTurn && currentSelection)
 	{
-		const auto * tile = LOCPLINT->cb->getTile(currentSelection->visitablePos());
+		const auto * tile = GAME->interface()->cb->getTile(currentSelection->visitablePos());
 
 		if (tile)
-			CCS->musich->playMusicFromSet("terrain", tile->getTerrain()->getJsonKey(), true, false);
+			ENGINE->music().playMusicFromSet("terrain", tile->getTerrain()->getJsonKey(), true, false);
 	}
 
 	if(audioPlaying && enemyMakingTurn)
 	{
-		CCS->musich->playMusicFromSet("enemy-turn", true, false);
+		ENGINE->music().playMusicFromSet("enemy-turn", true, false);
 	}
 }
 
@@ -201,11 +202,11 @@ void MapAudioPlayer::update()
 
 MapAudioPlayer::MapAudioPlayer()
 {
-	auto mapSize = LOCPLINT->cb->getMapSize();
+	auto mapSize = GAME->interface()->cb->getMapSize();
 
 	objects.resize(boost::extents[mapSize.z][mapSize.x][mapSize.y]);
 
-	for(const auto & obj : CGI->mh->getMap()->objects)
+	for(const auto & obj : GAME->map().getMap()->objects)
 	{
 		if (obj)
 			addObject(obj);
@@ -214,8 +215,8 @@ MapAudioPlayer::MapAudioPlayer()
 
 MapAudioPlayer::~MapAudioPlayer()
 {
-	CCS->soundh->ambientStopAllChannels();
-	CCS->musich->stopMusic(1000);
+	ENGINE->sound().ambientStopAllChannels();
+	ENGINE->music().stopMusic(1000);
 }
 
 void MapAudioPlayer::onSelectionChanged(const CArmedInstance * newSelection)
@@ -227,8 +228,8 @@ void MapAudioPlayer::onSelectionChanged(const CArmedInstance * newSelection)
 void MapAudioPlayer::onAudioPaused()
 {
 	audioPlaying = false;
-	CCS->soundh->ambientStopAllChannels();
-	CCS->musich->stopMusic(1000);
+	ENGINE->sound().ambientStopAllChannels();
+	ENGINE->music().stopMusic(1000);
 }
 
 void MapAudioPlayer::onAudioResumed()
@@ -255,6 +256,6 @@ void MapAudioPlayer::onPlayerTurnEnded()
 {
 	playerMakingTurn = false;
 	enemyMakingTurn = false;
-	CCS->soundh->ambientStopAllChannels();
-	CCS->musich->stopMusic(1000);
+	ENGINE->sound().ambientStopAllChannels();
+	ENGINE->music().stopMusic(1000);
 }

+ 13 - 13
client/adventureMap/TurnTimerWidget.cpp

@@ -10,11 +10,11 @@
 #include "StdInc.h"
 #include "TurnTimerWidget.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../battle/BattleInterface.h"
 #include "../battle/BattleStacksController.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/Graphics.h"
 #include "../widgets/Images.h"
@@ -41,7 +41,7 @@ TurnTimerWidget::TurnTimerWidget(const Point & position, PlayerColor player)
 	pos.w = 0;
 	pos.h = 0;
 	recActions &= ~DEACTIVATE;
-	const auto & timers = LOCPLINT->cb->getStartInfo()->turnTimerInfo;
+	const auto & timers = GAME->interface()->cb->getStartInfo()->turnTimerInfo;
 
 	backgroundTexture = std::make_shared<CFilledTexture>(ImagePath::builtin("DiBoxBck"), pos); // 1 px smaller on all sides
 
@@ -69,7 +69,7 @@ TurnTimerWidget::TurnTimerWidget(const Point & position, PlayerColor player)
 			playerLabelsUnit[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
 		}
 
-		updateTextLabel(player, LOCPLINT->cb->getPlayerTurnTime(player));
+		updateTextLabel(player, GAME->interface()->cb->getPlayerTurnTime(player));
 	}
 	else
 	{
@@ -80,16 +80,16 @@ TurnTimerWidget::TurnTimerWidget(const Point & position, PlayerColor player)
 
 		for(PlayerColor player(0); player < PlayerColor::PLAYER_LIMIT; ++player)
 		{
-			if (LOCPLINT->cb->getStartInfo()->playerInfos.count(player) == 0)
+			if (GAME->interface()->cb->getStartInfo()->playerInfos.count(player) == 0)
 				continue;
 
-			if (!LOCPLINT->cb->getStartInfo()->playerInfos.at(player).isControlledByHuman())
+			if (!GAME->interface()->cb->getStartInfo()->playerInfos.at(player).isControlledByHuman())
 				continue;
 
 			pos.h += 20;
 			playerLabelsMain[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
 
-			updateTextLabel(player, LOCPLINT->cb->getPlayerTurnTime(player));
+			updateTextLabel(player, GAME->interface()->cb->getPlayerTurnTime(player));
 		}
 	}
 
@@ -104,13 +104,13 @@ void TurnTimerWidget::show(Canvas & to)
 
 void TurnTimerWidget::updateNotifications(PlayerColor player, int timeMs)
 {
-	if(player != LOCPLINT->playerID)
+	if(player != GAME->interface()->playerID)
 		return;
 
 	int newTimeSeconds = timeMs / 1000;
 
 	if (newTimeSeconds != lastSoundCheckSeconds && notificationThresholds.count(newTimeSeconds))
-		CCS->soundh->playSound(AudioPath::builtin("WE5"));
+		ENGINE->sound().playSound(AudioPath::builtin("WE5"));
 
 	lastSoundCheckSeconds = newTimeSeconds;
 }
@@ -125,7 +125,7 @@ static std::string msToString(int timeMs)
 
 void TurnTimerWidget::updateTextLabel(PlayerColor player, const TurnTimerInfo & timer)
 {
-	const auto & timerSettings = LOCPLINT->cb->getStartInfo()->turnTimerInfo;
+	const auto & timerSettings = GAME->interface()->cb->getStartInfo()->turnTimerInfo;
 	auto mainLabel = playerLabelsMain[player];
 
 	if (isBattleMode)
@@ -166,7 +166,7 @@ void TurnTimerWidget::updateTextLabel(PlayerColor player, const TurnTimerInfo &
 
 void TurnTimerWidget::updateTimer(PlayerColor player, uint32_t msPassed)
 {
-	const auto & gamestateTimer = LOCPLINT->cb->getPlayerTurnTime(player);
+	const auto & gamestateTimer = GAME->interface()->cb->getPlayerTurnTime(player);
 	updateNotifications(player, gamestateTimer.valueMs());
 	updateTextLabel(player, gamestateTimer);
 }
@@ -175,9 +175,9 @@ void TurnTimerWidget::tick(uint32_t msPassed)
 {
 	for(const auto & player : playerLabelsMain)
 	{
-		if (LOCPLINT->battleInt)
+		if (GAME->interface()->battleInt)
 		{
-			const auto & battle = LOCPLINT->battleInt->getBattle();
+			const auto & battle = GAME->interface()->battleInt->getBattle();
 
 			bool isDefender = battle->sideToPlayer(BattleSide::DEFENDER) == player.first;
 			bool isAttacker = battle->sideToPlayer(BattleSide::ATTACKER) == player.first;

+ 61 - 61
client/battle/BattleActionsController.cpp

@@ -17,10 +17,10 @@
 #include "BattleSiegeController.h"
 #include "BattleInterfaceClasses.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/CIntObject.h"
 #include "../gui/WindowHandler.h"
 #include "../windows/CCreatureWindow.h"
@@ -55,8 +55,8 @@ static std::string replacePlaceholders(std::string input, const TextReplacementL
 static std::string translatePlural(int amount, const std::string& baseTextID)
 {
 	if(amount == 1)
-		return CGI->generaltexth->translate(baseTextID + ".1");
-	return CGI->generaltexth->translate(baseTextID);
+		return LIBRARY->generaltexth->translate(baseTextID + ".1");
+	return LIBRARY->generaltexth->translate(baseTextID);
 }
 
 static std::string formatPluralImpl(int amount, const std::string & amountString, const std::string & baseTextID)
@@ -93,7 +93,7 @@ static std::string formatAttack(const DamageEstimation & estimation, const std::
 		{ "%KILLS", formatPlural(estimation.kills, "vcmi.battleWindow.damageEstimation.kills") },
 	};
 
-	return replacePlaceholders(CGI->generaltexth->translate(baseTextID), replacements);
+	return replacePlaceholders(LIBRARY->generaltexth->translate(baseTextID), replacements);
 }
 
 static std::string formatMeleeAttack(const DamageEstimation & estimation, const std::string & creatureName)
@@ -117,7 +117,7 @@ static std::string formatRangedAttack(const DamageEstimation & estimation, const
 static std::string formatRetaliation(const DamageEstimation & estimation, bool mayBeKilled)
 {
 	if (estimation.damage.max == 0)
-		return CGI->generaltexth->translate("vcmi.battleWindow.damageRetaliation.never");
+		return LIBRARY->generaltexth->translate("vcmi.battleWindow.damageRetaliation.never");
 
 	std::string baseTextID = estimation.kills.max == 0 ?
 								 "vcmi.battleWindow.damageRetaliation.damage" :
@@ -127,7 +127,7 @@ static std::string formatRetaliation(const DamageEstimation & estimation, bool m
 		"vcmi.battleWindow.damageRetaliation.may" :
 		"vcmi.battleWindow.damageRetaliation.will";
 
-	return CGI->generaltexth->translate(prefixTextID) + formatAttack(estimation, "", baseTextID, 0);
+	return LIBRARY->generaltexth->translate(prefixTextID) + formatAttack(estimation, "", baseTextID, 0);
 }
 
 BattleActionsController::BattleActionsController(BattleInterface & owner):
@@ -149,7 +149,7 @@ void BattleActionsController::endCastingSpell()
 		possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack()); //restore actions after they were cleared
 
 	selectedStack = nullptr;
-	GH.fakeMouseMove();
+	ENGINE->fakeMouseMove();
 }
 
 bool BattleActionsController::isActiveStackSpellcaster() const
@@ -183,7 +183,7 @@ void BattleActionsController::enterCreatureCastingMode()
 		};
 
 		vstd::erase_if(possibleActions, actionFilterPredicate);
-		GH.fakeMouseMove();
+		ENGINE->fakeMouseMove();
 		return;
 	}
 
@@ -213,7 +213,7 @@ void BattleActionsController::enterCreatureCastingMode()
 			owner.giveCommand(EActionType::MONSTER_SPELL, BattleHex::INVALID, spell->getId());
 			selectedStack = nullptr;
 
-			CCS->curh->set(Cursor::Combat::POINTER);
+			ENGINE->cursor().set(Cursor::Combat::POINTER);
 		}
 		return;
 	}
@@ -226,7 +226,7 @@ void BattleActionsController::enterCreatureCastingMode()
 	};
 
 	vstd::erase_if(possibleActions, actionFilterPredicate);
-	GH.fakeMouseMove();
+	ENGINE->fakeMouseMove();
 }
 
 std::vector<PossiblePlayerBattleAction> BattleActionsController::getPossibleActionsForStack(const CStack *stack) const
@@ -262,8 +262,8 @@ void BattleActionsController::reorderPossibleActionsPriority(const CStack * stac
 				if(!stack->hasBonusOfType(BonusType::NO_SPELLCAST_BY_DEFAULT) && targetStack != nullptr)
 				{
 					PlayerColor stackOwner = owner.getBattle()->battleGetOwner(targetStack);
-					bool enemyTargetingPositiveSpellcast = item.spell().toSpell()->isPositive() && stackOwner != LOCPLINT->playerID;
-					bool friendTargetingNegativeSpellcast = item.spell().toSpell()->isNegative() && stackOwner == LOCPLINT->playerID;
+					bool enemyTargetingPositiveSpellcast = item.spell().toSpell()->isPositive() && stackOwner != GAME->interface()->playerID;
+					bool friendTargetingNegativeSpellcast = item.spell().toSpell()->isNegative() && stackOwner == GAME->interface()->playerID;
 
 					if(!enemyTargetingPositiveSpellcast && !friendTargetingNegativeSpellcast)
 						return 1;
@@ -345,7 +345,7 @@ void BattleActionsController::castThisSpell(SpellID spellID)
 	{
 		possibleActions.clear();
 		possibleActions.push_back (spellSelMode); //only this one action can be performed at the moment
-		GH.fakeMouseMove();//update cursor
+		ENGINE->fakeMouseMove();//update cursor
 	}
 
 	owner.windowObject->blockUI(true);
@@ -403,15 +403,15 @@ void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action,
 	switch (action.get())
 	{
 		case PossiblePlayerBattleAction::CHOOSE_TACTICS_STACK:
-			CCS->curh->set(Cursor::Combat::POINTER);
+			ENGINE->cursor().set(Cursor::Combat::POINTER);
 			return;
 
 		case PossiblePlayerBattleAction::MOVE_TACTICS:
 		case PossiblePlayerBattleAction::MOVE_STACK:
 			if (owner.stacksController->getActiveStack()->hasBonusOfType(BonusType::FLYING))
-				CCS->curh->set(Cursor::Combat::FLY);
+				ENGINE->cursor().set(Cursor::Combat::FLY);
 			else
-				CCS->curh->set(Cursor::Combat::MOVE);
+				ENGINE->cursor().set(Cursor::Combat::MOVE);
 			return;
 
 		case PossiblePlayerBattleAction::ATTACK:
@@ -433,16 +433,16 @@ void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action,
 
 			assert(sectorCursor.count(direction) > 0);
 			if (sectorCursor.count(direction))
-				CCS->curh->set(sectorCursor.at(direction));
+				ENGINE->cursor().set(sectorCursor.at(direction));
 
 			return;
 		}
 
 		case PossiblePlayerBattleAction::SHOOT:
 			if (owner.getBattle()->battleHasShootingPenalty(owner.stacksController->getActiveStack(), targetHex))
-				CCS->curh->set(Cursor::Combat::SHOOT_PENALTY);
+				ENGINE->cursor().set(Cursor::Combat::SHOOT_PENALTY);
 			else
-				CCS->curh->set(Cursor::Combat::SHOOT);
+				ENGINE->cursor().set(Cursor::Combat::SHOOT);
 			return;
 
 		case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
@@ -450,30 +450,30 @@ void BattleActionsController::actionSetCursor(PossiblePlayerBattleAction action,
 		case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
 		case PossiblePlayerBattleAction::FREE_LOCATION:
 		case PossiblePlayerBattleAction::OBSTACLE:
-			CCS->curh->set(Cursor::Spellcast::SPELL);
+			ENGINE->cursor().set(Cursor::Spellcast::SPELL);
 			return;
 
 		case PossiblePlayerBattleAction::TELEPORT:
-			CCS->curh->set(Cursor::Combat::TELEPORT);
+			ENGINE->cursor().set(Cursor::Combat::TELEPORT);
 			return;
 
 		case PossiblePlayerBattleAction::SACRIFICE:
-			CCS->curh->set(Cursor::Combat::SACRIFICE);
+			ENGINE->cursor().set(Cursor::Combat::SACRIFICE);
 			return;
 
 		case PossiblePlayerBattleAction::HEAL:
-			CCS->curh->set(Cursor::Combat::HEAL);
+			ENGINE->cursor().set(Cursor::Combat::HEAL);
 			return;
 
 		case PossiblePlayerBattleAction::CATAPULT:
-			CCS->curh->set(Cursor::Combat::SHOOT_CATAPULT);
+			ENGINE->cursor().set(Cursor::Combat::SHOOT_CATAPULT);
 			return;
 
 		case PossiblePlayerBattleAction::CREATURE_INFO:
-			CCS->curh->set(Cursor::Combat::QUERY);
+			ENGINE->cursor().set(Cursor::Combat::QUERY);
 			return;
 		case PossiblePlayerBattleAction::HERO_INFO:
-			CCS->curh->set(Cursor::Combat::HERO);
+			ENGINE->cursor().set(Cursor::Combat::HERO);
 			return;
 	}
 	assert(0);
@@ -488,13 +488,13 @@ void BattleActionsController::actionSetCursorBlocked(PossiblePlayerBattleAction
 		case PossiblePlayerBattleAction::TELEPORT:
 		case PossiblePlayerBattleAction::SACRIFICE:
 		case PossiblePlayerBattleAction::FREE_LOCATION:
-			CCS->curh->set(Cursor::Combat::BLOCKED);
+			ENGINE->cursor().set(Cursor::Combat::BLOCKED);
 			return;
 		default:
 			if (targetHex == -1)
-				CCS->curh->set(Cursor::Combat::POINTER);
+				ENGINE->cursor().set(Cursor::Combat::POINTER);
 			else
-				CCS->curh->set(Cursor::Combat::BLOCKED);
+				ENGINE->cursor().set(Cursor::Combat::BLOCKED);
 			return;
 	}
 	assert(0);
@@ -507,14 +507,14 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
 	switch (action.get()) //display console message, realize selected action
 	{
 		case PossiblePlayerBattleAction::CHOOSE_TACTICS_STACK:
-			return (boost::format(CGI->generaltexth->allTexts[481]) % targetStack->getName()).str(); //Select %s
+			return (boost::format(LIBRARY->generaltexth->allTexts[481]) % targetStack->getName()).str(); //Select %s
 
 		case PossiblePlayerBattleAction::MOVE_TACTICS:
 		case PossiblePlayerBattleAction::MOVE_STACK:
 			if (owner.stacksController->getActiveStack()->hasBonusOfType(BonusType::FLYING))
-				return (boost::format(CGI->generaltexth->allTexts[295]) % owner.stacksController->getActiveStack()->getName()).str(); //Fly %s here
+				return (boost::format(LIBRARY->generaltexth->allTexts[295]) % owner.stacksController->getActiveStack()->getName()).str(); //Fly %s here
 			else
-				return (boost::format(CGI->generaltexth->allTexts[294]) % owner.stacksController->getActiveStack()->getName()).str(); //Move %s here
+				return (boost::format(LIBRARY->generaltexth->allTexts[294]) % owner.stacksController->getActiveStack()->getName()).str(); //Move %s here
 
 		case PossiblePlayerBattleAction::ATTACK:
 		case PossiblePlayerBattleAction::WALK_AND_ATTACK:
@@ -539,7 +539,7 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
 			{
 				auto spellLikeAttackBonus = owner.stacksController->getActiveStack()->getBonus(Selector::type()(BonusType::SPELL_LIKE_ATTACK));
 				assert(spellLikeAttackBonus != nullptr);
-				return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % spellLikeAttackBonus->subtype.as<SpellID>().toSpell()->getNameTranslated());
+				return boost::str(boost::format(LIBRARY->generaltexth->allTexts[26]) % spellLikeAttackBonus->subtype.as<SpellID>().toSpell()->getNameTranslated());
 			}
 
 			const auto * shooter = owner.stacksController->getActiveStack();
@@ -553,37 +553,37 @@ std::string BattleActionsController::actionGetStatusMessage(PossiblePlayerBattle
 		}
 
 		case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
-			return boost::str(boost::format(CGI->generaltexth->allTexts[27]) % action.spell().toSpell()->getNameTranslated() % targetStack->getName()); //Cast %s on %s
+			return boost::str(boost::format(LIBRARY->generaltexth->allTexts[27]) % action.spell().toSpell()->getNameTranslated() % targetStack->getName()); //Cast %s on %s
 
 		case PossiblePlayerBattleAction::ANY_LOCATION:
-			return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % action.spell().toSpell()->getNameTranslated()); //Cast %s
+			return boost::str(boost::format(LIBRARY->generaltexth->allTexts[26]) % action.spell().toSpell()->getNameTranslated()); //Cast %s
 
 		case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL: //we assume that teleport / sacrifice will never be available as random spell
-			return boost::str(boost::format(CGI->generaltexth->allTexts[301]) % targetStack->getName()); //Cast a spell on %
+			return boost::str(boost::format(LIBRARY->generaltexth->allTexts[301]) % targetStack->getName()); //Cast a spell on %
 
 		case PossiblePlayerBattleAction::TELEPORT:
-			return CGI->generaltexth->allTexts[25]; //Teleport Here
+			return LIBRARY->generaltexth->allTexts[25]; //Teleport Here
 
 		case PossiblePlayerBattleAction::OBSTACLE:
-			return CGI->generaltexth->allTexts[550];
+			return LIBRARY->generaltexth->allTexts[550];
 
 		case PossiblePlayerBattleAction::SACRIFICE:
-			return (boost::format(CGI->generaltexth->allTexts[549]) % targetStack->getName()).str(); //sacrifice the %s
+			return (boost::format(LIBRARY->generaltexth->allTexts[549]) % targetStack->getName()).str(); //sacrifice the %s
 
 		case PossiblePlayerBattleAction::FREE_LOCATION:
-			return boost::str(boost::format(CGI->generaltexth->allTexts[26]) % action.spell().toSpell()->getNameTranslated()); //Cast %s
+			return boost::str(boost::format(LIBRARY->generaltexth->allTexts[26]) % action.spell().toSpell()->getNameTranslated()); //Cast %s
 
 		case PossiblePlayerBattleAction::HEAL:
-			return (boost::format(CGI->generaltexth->allTexts[419]) % targetStack->getName()).str(); //Apply first aid to the %s
+			return (boost::format(LIBRARY->generaltexth->allTexts[419]) % targetStack->getName()).str(); //Apply first aid to the %s
 
 		case PossiblePlayerBattleAction::CATAPULT:
 			return ""; // TODO
 
 		case PossiblePlayerBattleAction::CREATURE_INFO:
-			return (boost::format(CGI->generaltexth->allTexts[297]) % targetStack->getName()).str();
+			return (boost::format(LIBRARY->generaltexth->allTexts[297]) % targetStack->getName()).str();
 
 		case PossiblePlayerBattleAction::HERO_INFO:
-			return  CGI->generaltexth->translate("core.genrltxt.417"); // "View Hero Stats"
+			return  LIBRARY->generaltexth->translate("core.genrltxt.417"); // "View Hero Stats"
 	}
 	assert(0);
 	return "";
@@ -595,16 +595,16 @@ std::string BattleActionsController::actionGetStatusMessageBlocked(PossiblePlaye
 	{
 		case PossiblePlayerBattleAction::AIMED_SPELL_CREATURE:
 		case PossiblePlayerBattleAction::RANDOM_GENIE_SPELL:
-			return CGI->generaltexth->allTexts[23];
+			return LIBRARY->generaltexth->allTexts[23];
 			break;
 		case PossiblePlayerBattleAction::TELEPORT:
-			return CGI->generaltexth->allTexts[24]; //Invalid Teleport Destination
+			return LIBRARY->generaltexth->allTexts[24]; //Invalid Teleport Destination
 			break;
 		case PossiblePlayerBattleAction::SACRIFICE:
-			return CGI->generaltexth->allTexts[543]; //choose army to sacrifice
+			return LIBRARY->generaltexth->allTexts[543]; //choose army to sacrifice
 			break;
 		case PossiblePlayerBattleAction::FREE_LOCATION:
-			return boost::str(boost::format(CGI->generaltexth->allTexts[181]) % action.spell().toSpell()->getNameTranslated()); //No room to place %s here
+			return boost::str(boost::format(LIBRARY->generaltexth->allTexts[181]) % action.spell().toSpell()->getNameTranslated()); //No room to place %s here
 			break;
 		default:
 			return "";
@@ -771,7 +771,7 @@ void BattleActionsController::actionRealize(PossiblePlayerBattleAction action, c
 
 		case PossiblePlayerBattleAction::CREATURE_INFO:
 		{
-			GH.windows().createAndPushWindow<CStackWindow>(targetStack, false);
+			ENGINE->windows().createAndPushWindow<CStackWindow>(targetStack, false);
 			return;
 		}
 
@@ -874,8 +874,8 @@ void BattleActionsController::onHexHovered(const BattleHex & hoveredHex)
 {
 	if (owner.openingPlaying())
 	{
-		currentConsoleMsg = VLC->generaltexth->translate("vcmi.battleWindow.pressKeyToSkipIntro");
-		GH.statusbar()->write(currentConsoleMsg);
+		currentConsoleMsg = LIBRARY->generaltexth->translate("vcmi.battleWindow.pressKeyToSkipIntro");
+		ENGINE->statusbar()->write(currentConsoleMsg);
 		return;
 	}
 
@@ -885,10 +885,10 @@ void BattleActionsController::onHexHovered(const BattleHex & hoveredHex)
 	if (hoveredHex == BattleHex::INVALID)
 	{
 		if (!currentConsoleMsg.empty())
-			GH.statusbar()->clearIfMatching(currentConsoleMsg);
+			ENGINE->statusbar()->clearIfMatching(currentConsoleMsg);
 
 		currentConsoleMsg.clear();
-		CCS->curh->set(Cursor::Combat::BLOCKED);
+		ENGINE->cursor().set(Cursor::Combat::BLOCKED);
 		return;
 	}
 
@@ -908,20 +908,20 @@ void BattleActionsController::onHexHovered(const BattleHex & hoveredHex)
 	}
 
 	if (!currentConsoleMsg.empty())
-		GH.statusbar()->clearIfMatching(currentConsoleMsg);
+		ENGINE->statusbar()->clearIfMatching(currentConsoleMsg);
 
 	if (!newConsoleMsg.empty())
-		GH.statusbar()->write(newConsoleMsg);
+		ENGINE->statusbar()->write(newConsoleMsg);
 
 	currentConsoleMsg = newConsoleMsg;
 }
 
 void BattleActionsController::onHoverEnded()
 {
-	CCS->curh->set(Cursor::Combat::POINTER);
+	ENGINE->cursor().set(Cursor::Combat::POINTER);
 
 	if (!currentConsoleMsg.empty())
-		GH.statusbar()->clearIfMatching(currentConsoleMsg);
+		ENGINE->statusbar()->clearIfMatching(currentConsoleMsg);
 
 	currentConsoleMsg.clear();
 }
@@ -939,7 +939,7 @@ void BattleActionsController::onHexLeftClicked(const BattleHex & clickedHex)
 		return;
 	
 	actionRealize(action, clickedHex);
-	GH.statusbar()->clear();
+	ENGINE->statusbar()->clear();
 }
 
 void BattleActionsController::tryActivateStackSpellcasting(const CStack *casterStack)
@@ -1064,14 +1064,14 @@ void BattleActionsController::onHexRightClicked(const BattleHex & clickedHex)
 	if (heroSpellcastingModeActive() || isCurrentStackInSpellcastMode)
 	{
 		endCastingSpell();
-		CRClickPopup::createAndPush(CGI->generaltexth->translate("core.genrltxt.731")); // spell cancelled
+		CRClickPopup::createAndPush(LIBRARY->generaltexth->translate("core.genrltxt.731")); // spell cancelled
 		return;
 	}
 
 	auto selectedStack = owner.getBattle()->battleGetStackByPos(clickedHex, true);
 
 	if (selectedStack != nullptr)
-		GH.windows().createAndPushWindow<CStackWindow>(selectedStack, true);
+		ENGINE->windows().createAndPushWindow<CStackWindow>(selectedStack, true);
 
 	if (clickedHex == BattleHex::HERO_ATTACKER && owner.attackingHero)
 		owner.attackingHero->heroRightClicked();
@@ -1126,4 +1126,4 @@ void BattleActionsController::pushFrontPossibleAction(PossiblePlayerBattleAction
 void BattleActionsController::resetCurrentStackPossibleActions()
 {
 	possibleActions = getPossibleActionsForStack(owner.stacksController->getActiveStack());
-}
+}

+ 9 - 10
client/battle/BattleAnimationClasses.cpp

@@ -19,10 +19,9 @@
 #include "BattleStacksController.h"
 #include "CreatureAnimation.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/CAnimation.h"
 #include "../render/IRenderHandler.h"
@@ -124,7 +123,7 @@ void StackActionAnimation::setSound( const AudioPath & sound )
 bool StackActionAnimation::init()
 {
 	if (!sound.empty())
-		CCS->soundh->playSound(sound);
+		ENGINE->sound().playSound(sound);
 
 	if (myAnim->framesInGroup(currGroup) > 0)
 	{
@@ -358,7 +357,7 @@ bool MovementAnimation::init()
 
 	if (moveSoundHandler == -1)
 	{
-		moveSoundHandler = CCS->soundh->playSound(stack->unitType()->sounds.move, -1);
+		moveSoundHandler = ENGINE->sound().playSound(stack->unitType()->sounds.move, -1);
 	}
 
 	Point begPosition = owner.stacksController->getStackPositionAtHex(prevHex, stack);
@@ -419,7 +418,7 @@ MovementAnimation::~MovementAnimation()
 	assert(stack);
 
 	if(moveSoundHandler != -1)
-		CCS->soundh->stopSound(moveSoundHandler);
+		ENGINE->sound().stopSound(moveSoundHandler);
 }
 
 MovementAnimation::MovementAnimation(BattleInterface & owner, const CStack *stack, const BattleHexArray & _destTiles, int _distance)
@@ -455,7 +454,7 @@ bool MovementEndAnimation::init()
 	logAnim->debug("CMovementEndAnimation::init: stack %s", stack->getName());
 	myAnim->pos.moveTo(owner.stacksController->getStackPositionAtHex(nextHex, stack));
 
-	CCS->soundh->playSound(stack->unitType()->sounds.endMoving);
+	ENGINE->sound().playSound(stack->unitType()->sounds.endMoving);
 
 	if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_END))
 	{
@@ -475,7 +474,7 @@ MovementEndAnimation::~MovementEndAnimation()
 	if(myAnim->getType() != ECreatureAnimType::DEAD)
 		myAnim->setType(ECreatureAnimType::HOLDING); //resetting to default
 
-	CCS->curh->show();
+	ENGINE->cursor().show();
 }
 
 MovementStartAnimation::MovementStartAnimation(BattleInterface & owner, const CStack * _stack)
@@ -496,7 +495,7 @@ bool MovementStartAnimation::init()
 	}
 
 	logAnim->debug("CMovementStartAnimation::init: stack %s", stack->getName());
-	CCS->soundh->playSound(stack->unitType()->sounds.startMoving);
+	ENGINE->sound().playSound(stack->unitType()->sounds.startMoving);
 
 	if(!myAnim->framesInGroup(ECreatureAnimType::MOVE_START))
 	{
@@ -816,7 +815,7 @@ void CatapultAnimation::tick(uint32_t msPassed)
 	auto soundFilename  = AudioPath::builtin((catapultDamage > 0) ? "WALLHIT" : "WALLMISS");
 	AnimationPath effectFilename = AnimationPath::builtin((catapultDamage > 0) ? "SGEXPL" : "CSGRCK");
 
-	CCS->soundh->playSound( soundFilename );
+	ENGINE->sound().playSound( soundFilename );
 	owner.stacksController->addNewAnim( new EffectAnimation(owner, effectFilename, shotTarget));
 }
 
@@ -888,7 +887,7 @@ uint32_t CastAnimation::getAttackClimaxFrame() const
 
 EffectAnimation::EffectAnimation(BattleInterface & owner, const AnimationPath & animationName, int effects, float transparencyFactor, bool reversed):
 	BattleAnimation(owner),
-	animation(GH.renderHandler().loadAnimation(animationName, EImageBlitMode::SIMPLE)),
+	animation(ENGINE->renderHandler().loadAnimation(animationName, EImageBlitMode::SIMPLE)),
 	transparencyFactor(transparencyFactor),
 	effectFlags(effects),
 	effectFinished(false),

+ 3 - 3
client/battle/BattleEffectsController.cpp

@@ -18,8 +18,8 @@
 #include "BattleStacksController.h"
 #include "BattleRenderer.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
+#include "../GameEngine.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/Canvas.h"
 #include "../render/CAnimation.h"
@@ -50,7 +50,7 @@ void BattleEffectsController::displayEffect(EBattleEffect effect, const AudioPat
 
 	AnimationPath customAnim = AnimationPath::builtinTODO(graphics->battleACToDef[effectID][0]);
 
-	CCS->soundh->playSound( soundFile );
+	ENGINE->sound().playSound( soundFile );
 
 	owner.stacksController->addNewAnim(new EffectAnimation(owner, customAnim, destTile, 0, transparencyFactor));
 }
@@ -82,7 +82,7 @@ void BattleEffectsController::battleTriggerEffect(const BattleTriggerEffect & bt
 			break;
 		case BonusType::MORALE:
 		{
-			std::string hlp = CGI->generaltexth->allTexts[33];
+			std::string hlp = LIBRARY->generaltexth->allTexts[33];
 			boost::algorithm::replace_first(hlp,"%s",(stack->getName()));
 			displayEffect(EBattleEffect::GOOD_MORALE, AudioPath::builtin("GOODMRLE"), stack->getPosition());
 			owner.appendBattleLog(hlp);

+ 19 - 19
client/battle/BattleFieldController.cpp

@@ -21,13 +21,13 @@
 #include "BattleProjectileController.h"
 #include "BattleRenderer.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
 #include "../render/IRenderHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/CursorHandler.h"
 #include "../adventureMap/CInGameConsole.h"
 #include "../client/render/CAnimation.h"
@@ -112,16 +112,16 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
 	OBJECT_CONSTRUCTION;
 
 	//preparing cells and hexes
-	cellBorder = GH.renderHandler().loadImage(ImagePath::builtin("CCELLGRD.BMP"), EImageBlitMode::COLORKEY);
-	cellShade = GH.renderHandler().loadImage(ImagePath::builtin("CCELLSHD.BMP"), EImageBlitMode::SIMPLE);
-	cellUnitMovementHighlight = GH.renderHandler().loadImage(ImagePath::builtin("UnitMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
-	cellUnitMaxMovementHighlight = GH.renderHandler().loadImage(ImagePath::builtin("UnitMaxMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
+	cellBorder = ENGINE->renderHandler().loadImage(ImagePath::builtin("CCELLGRD.BMP"), EImageBlitMode::COLORKEY);
+	cellShade = ENGINE->renderHandler().loadImage(ImagePath::builtin("CCELLSHD.BMP"), EImageBlitMode::SIMPLE);
+	cellUnitMovementHighlight = ENGINE->renderHandler().loadImage(ImagePath::builtin("UnitMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
+	cellUnitMaxMovementHighlight = ENGINE->renderHandler().loadImage(ImagePath::builtin("UnitMaxMovementHighlight.PNG"), EImageBlitMode::COLORKEY);
 
-	attackCursors = GH.renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT"), EImageBlitMode::COLORKEY);
-	spellCursors = GH.renderHandler().loadAnimation(AnimationPath::builtin("CRSPELL"), EImageBlitMode::COLORKEY);
+	attackCursors = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT"), EImageBlitMode::COLORKEY);
+	spellCursors = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRSPELL"), EImageBlitMode::COLORKEY);
 
-	rangedFullDamageLimitImages = GH.renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsGreen.json"), EImageBlitMode::COLORKEY);
-	shootingRangeLimitImages = GH.renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsRed.json"), EImageBlitMode::COLORKEY);
+	rangedFullDamageLimitImages = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsGreen.json"), EImageBlitMode::COLORKEY);
+	shootingRangeLimitImages = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("battle/rangeHighlights/rangeHighlightsRed.json"), EImageBlitMode::COLORKEY);
 
 	if(!owner.siegeController)
 	{
@@ -130,12 +130,12 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
 		if(bfieldType == BattleField::NONE)
 			logGlobal->error("Invalid battlefield returned for current battle");
 		else
-			background = GH.renderHandler().loadImage(bfieldType.getInfo()->graphics, EImageBlitMode::OPAQUE);
+			background = ENGINE->renderHandler().loadImage(bfieldType.getInfo()->graphics, EImageBlitMode::OPAQUE);
 	}
 	else
 	{
 		auto backgroundName = owner.siegeController->getBattleBackgroundName();
-		background = GH.renderHandler().loadImage(backgroundName, EImageBlitMode::OPAQUE);
+		background = ENGINE->renderHandler().loadImage(backgroundName, EImageBlitMode::OPAQUE);
 	}
 
 	pos.w = background->width();
@@ -149,7 +149,7 @@ BattleFieldController::BattleFieldController(BattleInterface & owner):
 
 void BattleFieldController::activate()
 {
-	LOCPLINT->cingconsole->pos = this->pos;
+	GAME->interface()->cingconsole->pos = this->pos;
 	CIntObject::activate();
 }
 
@@ -329,7 +329,7 @@ BattleHexArray BattleFieldController::getMovementRangeForHoveredStack()
 	if (!owner.stacksController->getActiveStack())
 		return BattleHexArray();
 
-	if (!settings["battle"]["movementHighlightOnHover"].Bool() && !GH.isKeyboardShiftDown())
+	if (!settings["battle"]["movementHighlightOnHover"].Bool() && !ENGINE->isKeyboardShiftDown())
 		return BattleHexArray();
 
 	auto hoveredStack = getHoveredStack();
@@ -416,7 +416,7 @@ BattleHexArray BattleFieldController::getRangeHexes(const BattleHex & sourceHex,
 {
 	BattleHexArray rangeHexes;
 
-	if (!settings["battle"]["rangeLimitHighlightOnHover"].Bool() && !GH.isKeyboardShiftDown())
+	if (!settings["battle"]["rangeLimitHighlightOnHover"].Bool() && !ENGINE->isKeyboardShiftDown())
 		return rangeHexes;
 
 	// get only battlefield hexes that are within the given distance
@@ -857,19 +857,19 @@ void BattleFieldController::show(Canvas & to)
 
 	if (isActive() && isGesturing() && getHoveredHex() != BattleHex::INVALID)
 	{
-		auto combatCursorIndex = CCS->curh->get<Cursor::Combat>();
+		auto combatCursorIndex = ENGINE->cursor().get<Cursor::Combat>();
 		if (combatCursorIndex)
 		{
 			auto combatImageIndex = static_cast<size_t>(*combatCursorIndex);
-			to.draw(attackCursors->getImage(combatImageIndex), hexPositionAbsolute(getHoveredHex()).center() - CCS->curh->getPivotOffsetCombat(combatImageIndex));
+			to.draw(attackCursors->getImage(combatImageIndex), hexPositionAbsolute(getHoveredHex()).center() - ENGINE->cursor().getPivotOffsetCombat(combatImageIndex));
 			return;
 		}
 
-		auto spellCursorIndex = CCS->curh->get<Cursor::Spellcast>();
+		auto spellCursorIndex = ENGINE->cursor().get<Cursor::Spellcast>();
 		if (spellCursorIndex)
 		{
 			auto spellImageIndex = static_cast<size_t>(*spellCursorIndex);
-			to.draw(spellCursors->getImage(spellImageIndex), hexPositionAbsolute(getHoveredHex()).center() - CCS->curh->getPivotOffsetSpellcast());
+			to.draw(spellCursors->getImage(spellImageIndex), hexPositionAbsolute(getHoveredHex()).center() - ENGINE->cursor().getPivotOffsetSpellcast());
 			return;
 		}
 

+ 19 - 19
client/battle/BattleInterface.cpp

@@ -23,10 +23,10 @@
 #include "BattleStacksController.h"
 #include "BattleRenderer.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../media/IMusicPlayer.h"
 #include "../media/ISoundPlayer.h"
@@ -97,7 +97,7 @@ BattleInterface::BattleInterface(const BattleID & battleID, const CCreatureSet *
 	adventureInt->onAudioPaused();
 	ongoingAnimationsState.setBusy();
 
-	GH.windows().pushWindow(windowObject);
+	ENGINE->windows().pushWindow(windowObject);
 	windowObject->blockUI(true);
 	windowObject->updateQueue();
 
@@ -109,7 +109,7 @@ void BattleInterface::playIntroSoundAndUnlockInterface()
 	auto onIntroPlayed = [this]()
 	{
 		// Make sure that battle have not ended while intro was playing AND that a different one has not started
-		if(LOCPLINT->battleInt.get() == this)
+		if(GAME->interface()->battleInt.get() == this)
 			onIntroSoundPlayed();
 	};
 
@@ -126,13 +126,13 @@ void BattleInterface::playIntroSoundAndUnlockInterface()
 	int battleIntroSoundChannel = -1;
 
 	if (!battlefieldSound.empty())
-		battleIntroSoundChannel = CCS->soundh->playSound(battlefieldSound);
+		battleIntroSoundChannel = ENGINE->sound().playSound(battlefieldSound);
 	else
-		battleIntroSoundChannel = CCS->soundh->playSoundFromSet(battleIntroSounds);
+		battleIntroSoundChannel = ENGINE->sound().playSoundFromSet(battleIntroSounds);
 
 	if (battleIntroSoundChannel != -1)
 	{
-		CCS->soundh->setCallback(battleIntroSoundChannel, onIntroPlayed);
+		ENGINE->sound().setCallback(battleIntroSoundChannel, onIntroPlayed);
 
 		if (settings["gameTweaks"]["skipBattleIntroMusic"].Bool())
 			openingEnd();
@@ -157,9 +157,9 @@ void BattleInterface::onIntroSoundPlayed()
 	const auto & battlefieldMusic = bfieldType.getInfo()->musicFilename;
 
 	if (!battlefieldMusic.empty())
-		CCS->musich->playMusic(battlefieldMusic, true, true);
+		ENGINE->music().playMusic(battlefieldMusic, true, true);
 	else
-		CCS->musich->playMusicFromSet("battle", true, true);
+		ENGINE->music().playMusicFromSet("battle", true, true);
 }
 
 void BattleInterface::openingEnd()
@@ -191,7 +191,7 @@ BattleInterface::~BattleInterface()
 void BattleInterface::redrawBattlefield()
 {
 	fieldController->redrawBackgroundWithHexes();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleInterface::stackReset(const CStack * stack)
@@ -257,7 +257,7 @@ void BattleInterface::newRoundFirst()
 
 void BattleInterface::newRound()
 {
-	console->addText(CGI->generaltexth->allTexts[412]);
+	console->addText(LIBRARY->generaltexth->allTexts[412]);
 	round++;
 }
 
@@ -301,7 +301,7 @@ void BattleInterface::sendCommand(BattleAction command, const CStack * actor)
 		stacksController->setActiveStack(nullptr);
 		//next stack will be activated when action ends
 	}
-	CCS->curh->set(Cursor::Combat::POINTER);
+	ENGINE->cursor().set(Cursor::Combat::POINTER);
 }
 
 const CGHeroInstance * BattleInterface::getActiveHero()
@@ -337,7 +337,7 @@ void BattleInterface::battleFinished(const BattleResult& br, QueryID queryID)
 	checkForAnimations();
 	stacksController->setActiveStack(nullptr);
 
-	CCS->curh->set(Cursor::Map::POINTER);
+	ENGINE->cursor().set(Cursor::Map::POINTER);
 	curInt->waitWhileDialog();
 
 	if(settings["session"]["spectate"].Bool() && settings["session"]["spectate-skip-battle-result"].Bool())
@@ -352,7 +352,7 @@ void BattleInterface::battleFinished(const BattleResult& br, QueryID queryID)
 	{
 		curInt->cb->selectionMade(selection, queryID);
 	};
-	GH.windows().pushWindow(wnd);
+	ENGINE->windows().pushWindow(wnd);
 
 	curInt->waitWhileDialog(); // Avoid freeze when AI end turn after battle. Check bug #1897
 	CPlayerInterface::battleInt.reset();
@@ -371,7 +371,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 		stacksController->deactivateStack();
 	}
 
-	CCS->curh->set(Cursor::Combat::BLOCKED);
+	ENGINE->cursor().set(Cursor::Combat::BLOCKED);
 
 	const SpellID spellID = sc->spellID;
 
@@ -390,7 +390,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 					EAnimationEvents::BEFORE_HIT;//FIXME: recheck whether this should be on projectile spawning
 
 		addToAnimationStage(group, [=]() {
-			CCS->soundh->playSound(castSoundPath);
+			ENGINE->sound().playSound(castSoundPath);
 		});
 	}
 
@@ -447,7 +447,7 @@ void BattleInterface::spellCast(const BattleSpellCast * sc)
 	if (!sc->resistedCres.empty())
 	{
 		addToAnimationStage(EAnimationEvents::HIT, [=](){
-			CCS->soundh->playSound(AudioPath::builtin("MAGICRES"));
+			ENGINE->sound().playSound(AudioPath::builtin("MAGICRES"));
 		});
 	}
 
@@ -586,7 +586,7 @@ void BattleInterface::activateStack()
 	windowObject->blockUI(false);
 	fieldController->redrawBackgroundWithHexes();
 	actionsController->activateStack();
-	GH.fakeMouseMove();
+	ENGINE->fakeMouseMove();
 }
 
 bool BattleInterface::makingTurn() const
@@ -813,7 +813,7 @@ void BattleInterface::onAnimationsFinished()
 void BattleInterface::waitForAnimations()
 {
 	{
-		auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+		auto unlockInterface = vstd::makeUnlockGuard(ENGINE->interfaceMutex);
 		ongoingAnimationsState.waitWhileBusy();
 	}
 

+ 53 - 53
client/battle/BattleInterfaceClasses.cpp

@@ -18,10 +18,10 @@
 #include "BattleStacksController.h"
 #include "BattleWindow.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/MouseButton.h"
 #include "../gui/WindowHandler.h"
@@ -113,7 +113,7 @@ std::vector<std::string> BattleConsole::splitText(const std::string &text)
 
 	boost::split(lines, text, boost::is_any_of("\n"));
 
-	const auto & font = GH.renderHandler().loadFont(FONT_SMALL);
+	const auto & font = ENGINE->renderHandler().loadFont(FONT_SMALL);
 	for(const auto & line : lines)
 	{
 		if (font->getStringWidth(text) < pos.w)
@@ -171,7 +171,7 @@ BattleConsole::BattleConsole(const BattleInterface & owner, std::shared_ptr<CPic
 void BattleConsole::deactivate()
 {
 	if (enteringText)
-		LOCPLINT->cingconsole->endEnteringText(false);
+		GAME->interface()->cingconsole->endEnteringText(false);
 
 	CIntObject::deactivate();
 }
@@ -180,7 +180,7 @@ void BattleConsole::clickPressed(const Point & cursorPosition)
 {
 	if(owner.makingTurn() && !owner.openingPlaying())
 	{
-		GH.windows().createAndPushWindow<BattleConsoleWindow>(boost::algorithm::join(logEntries, "\n"));
+		ENGINE->windows().createAndPushWindow<BattleConsoleWindow>(boost::algorithm::join(logEntries, "\n"));
 	}
 }
 
@@ -191,12 +191,12 @@ void BattleConsole::setEnteringMode(bool on)
 	if (on)
 	{
 		assert(enteringText == false);
-		GH.startTextInput(pos);
+		ENGINE->input().startTextInput(pos);
 	}
 	else
 	{
 		assert(enteringText == true);
-		GH.stopTextInput();
+		ENGINE->input().stopTextInput();
 	}
 	enteringText = on;
 	redraw();
@@ -337,8 +337,8 @@ void BattleHero::heroLeftClicked()
 
 	if(owner.getBattle()->battleCanCastSpell(hero, spells::Mode::HERO) == ESpellCastProblem::OK) //check conditions
 	{
-		CCS->curh->set(Cursor::Map::POINTER);
-		GH.windows().createAndPushWindow<CSpellWindow>(hero, owner.getCurrentPlayerInterface());
+		ENGINE->cursor().set(Cursor::Map::POINTER);
+		ENGINE->windows().createAndPushWindow<CSpellWindow>(hero, owner.getCurrentPlayerInterface());
 	}
 }
 
@@ -348,7 +348,7 @@ void BattleHero::heroRightClicked()
 		return;
 
 	Point windowPosition;
-	if(GH.screenDimensions().x < 1000)
+	if(ENGINE->screenDimensions().x < 1000)
 	{
 		windowPosition.x = (!defender) ? owner.fieldController->pos.left() + 1 : owner.fieldController->pos.right() - 79;
 		windowPosition.y = owner.fieldController->pos.y + 135;
@@ -364,7 +364,7 @@ void BattleHero::heroRightClicked()
 	{
 		auto h = defender ? owner.defendingHeroInstance : owner.attackingHeroInstance;
 		targetHero.initFromHero(h, InfoAboutHero::EInfoLevel::INBATTLE);
-		GH.windows().createAndPushWindow<HeroInfoWindow>(targetHero, &windowPosition);
+		ENGINE->windows().createAndPushWindow<HeroInfoWindow>(targetHero, &windowPosition);
 	}
 }
 
@@ -398,7 +398,7 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
 	else
 		animationPath = hero->getHeroClass()->imageBattleMale;
 
-	animation = GH.renderHandler().loadAnimation(animationPath, EImageBlitMode::WITH_SHADOW);
+	animation = ENGINE->renderHandler().loadAnimation(animationPath, EImageBlitMode::WITH_SHADOW);
 
 	pos.w = 64;
 	pos.h = 136;
@@ -409,9 +409,9 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
 		animation->verticalFlip();
 
 	if(defender)
-		flagAnimation = GH.renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGR"), EImageBlitMode::COLORKEY);
+		flagAnimation = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGR"), EImageBlitMode::COLORKEY);
 	else
-		flagAnimation = GH.renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGL"), EImageBlitMode::COLORKEY);
+		flagAnimation = ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CMFLAGL"), EImageBlitMode::COLORKEY);
 
 	flagAnimation->playerColored(hero->tempOwner);
 
@@ -462,7 +462,7 @@ std::vector<std::tuple<SpellID, bool>> QuickSpellPanel::getSpells() const
 		if(spellIds[i] != SpellID::NONE)
 			continue;
 
-		for(const auto & availableSpellID : CGI->spellh->getDefaultAllowed())
+		for(const auto & availableSpellID : LIBRARY->spellh->getDefaultAllowed())
 		{
 			const auto * availableSpell = availableSpellID.toSpell();
 			if(!availableSpell->isAdventure() && !availableSpell->isCreatureAbility() && hero->canCastThisSpell(availableSpell) && !vstd::contains(spellIds, availableSpell->getId()))
@@ -507,8 +507,8 @@ void QuickSpellPanel::create()
 		});
 		button->setOverlay(std::make_shared<CAnimImage>(AnimationPath::builtin("spellint"), id != SpellID::NONE ? id.num + 1 : 0));
 		button->addPopupCallback([this, i, hero](){
-			GH.input().hapticFeedback();
-			GH.windows().createAndPushWindow<CSpellWindow>(hero, owner.curInt.get(), true, [this, i](SpellID spell){
+			ENGINE->input().hapticFeedback();
+			ENGINE->windows().createAndPushWindow<CSpellWindow>(hero, owner.curInt.get(), true, [this, i](SpellID spell){
 				Settings configID = persistentStorage.write["quickSpell"][std::to_string(i)];
 				configID->String() = spell == SpellID::NONE ? "" : spell.toSpell()->identifier;
 				create();
@@ -522,7 +522,7 @@ void QuickSpellPanel::create()
 		{
 			buttonsDisabled.push_back(std::make_shared<TransparentFilledRectangle>(Rect(2, 7 + 50 * i, 48, 36), ColorRGBA(0, 0, 0, 172)));
 		}
-		if(GH.input().getCurrentInputMode() == InputMode::KEYBOARD_AND_MOUSE)
+		if(ENGINE->input().getCurrentInputMode() == InputMode::KEYBOARD_AND_MOUSE)
 			labels.push_back(std::make_shared<CLabel>(7, 10 + 50 * i, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, config["keyboard"]["battleSpellShortcut" + std::to_string(i)].String()));
 
 		buttons.push_back(button);
@@ -572,10 +572,10 @@ void HeroInfoBasicPanel::initializeData(const InfoAboutHero & hero)
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("PortraitsLarge"), hero.getIconIndex(), 0, 10, 6));
 
 	//primary stats
-	labels.push_back(std::make_shared<CLabel>(9, 75, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 87, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[381] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 99, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[382] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 111, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[383] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 75, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[380] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 87, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[381] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 99, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[382] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 111, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[383] + ":"));
 
 	labels.push_back(std::make_shared<CLabel>(69, 87, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(attack)));
 	labels.push_back(std::make_shared<CLabel>(69, 99, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(defense)));
@@ -583,14 +583,14 @@ void HeroInfoBasicPanel::initializeData(const InfoAboutHero & hero)
 	labels.push_back(std::make_shared<CLabel>(69, 123, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(knowledge)));
 
 	//morale+luck
-	labels.push_back(std::make_shared<CLabel>(9, 131, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 143, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 131, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[384] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 143, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[385] + ":"));
 
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("IMRL22"), morale + 3, 0, 47, 131));
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("ILCK22"), luck + 3, 0, 47, 143));
 
 	//spell points
-	labels.push_back(std::make_shared<CLabel>(39, 174, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[387]));
+	labels.push_back(std::make_shared<CLabel>(39, 174, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[387]));
 	labels.push_back(std::make_shared<CLabel>(39, 186, EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, std::to_string(currentSpellPoints) + "/" + std::to_string(maxSpellPoints)));
 }
 
@@ -633,9 +633,9 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), stack->creatureId() + 2, 0, 10, 6));
 	labels.push_back(std::make_shared<CLabel>(10 + 58, 6 + 64, FONT_MEDIUM, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, TextOperations::formatMetric(stack->getCount(), 4)));
 
-	auto attack = std::to_string(CGI->creatures()->getByIndex(stack->creatureIndex())->getAttack(stack->isShooter())) + "(" + std::to_string(stack->getAttack(stack->isShooter())) + ")";
-	auto defense = std::to_string(CGI->creatures()->getByIndex(stack->creatureIndex())->getDefense(stack->isShooter())) + "(" + std::to_string(stack->getDefense(stack->isShooter())) + ")";
-	auto damage = std::to_string(CGI->creatures()->getByIndex(stack->creatureIndex())->getMinDamage(stack->isShooter())) + "-" + std::to_string(stack->getMaxDamage(stack->isShooter()));
+	auto attack = std::to_string(LIBRARY->creatures()->getByIndex(stack->creatureIndex())->getAttack(stack->isShooter())) + "(" + std::to_string(stack->getAttack(stack->isShooter())) + ")";
+	auto defense = std::to_string(LIBRARY->creatures()->getByIndex(stack->creatureIndex())->getDefense(stack->isShooter())) + "(" + std::to_string(stack->getDefense(stack->isShooter())) + ")";
+	auto damage = std::to_string(LIBRARY->creatures()->getByIndex(stack->creatureIndex())->getMinDamage(stack->isShooter())) + "-" + std::to_string(stack->getMaxDamage(stack->isShooter()));
 	auto health = stack->getMaxHealth();
 	auto morale = stack->moraleVal();
 	auto luck = stack->luckVal();
@@ -644,10 +644,10 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
 	auto healthRemaining = TextOperations::formatMetric(std::max(stack->getAvailableHealth() - (stack->getCount() - 1) * health, (si64)0), 4);
 
 	//primary stats*/
-	labels.push_back(std::make_shared<CLabel>(9, 75, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[380] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 87, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[381] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 99, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[386] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 111, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[389] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 75, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[380] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 87, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[381] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 99, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[386] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 111, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[389] + ":"));
 
 	labels.push_back(std::make_shared<CLabel>(69, 87, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, attack));
 	labels.push_back(std::make_shared<CLabel>(69, 99, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, defense));
@@ -655,15 +655,15 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
 	labels.push_back(std::make_shared<CLabel>(69, 123, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(health)));
 
 	//morale+luck
-	labels.push_back(std::make_shared<CLabel>(9, 131, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[384] + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 143, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[385] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 131, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[384] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 143, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[385] + ":"));
 
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("IMRL22"), morale + 3, 0, 47, 131));
 	icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("ILCK22"), luck + 3, 0, 47, 143));
 
 	//extra information
-	labels.push_back(std::make_shared<CLabel>(9, 168, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, VLC->generaltexth->translate("vcmi.battleWindow.killed") + ":"));
-	labels.push_back(std::make_shared<CLabel>(9, 180, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->allTexts[389] + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 168, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.battleWindow.killed") + ":"));
+	labels.push_back(std::make_shared<CLabel>(9, 180, EFonts::FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->allTexts[389] + ":"));
 
 	labels.push_back(std::make_shared<CLabel>(69, 180, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(killed)));
 	labels.push_back(std::make_shared<CLabel>(69, 192, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, healthRemaining));
@@ -702,7 +702,7 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
 	}
 
 	if(spells.size() == 0)
-		labelsMultiline.push_back(std::make_shared<CMultiLineLabel>(Rect(firstPos.x, firstPos.y, 48, 36), EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[674]));
+		labelsMultiline.push_back(std::make_shared<CMultiLineLabel>(Rect(firstPos.x, firstPos.y, 48, 36), EFonts::FONT_TINY, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[674]));
 	if(spells.size() > 3)
 		labelsMultiline.push_back(std::make_shared<CMultiLineLabel>(Rect(firstPos.x + offset.x * 2, firstPos.y + offset.y * 2 - 4, 48, 36), EFonts::FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, "..."));
 }
@@ -750,30 +750,30 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
 	{
 		repeat = std::make_shared<CButton>(Point(24, 505), AnimationPath::builtin("icn6432.def"), std::make_pair("", ""), [&](){ bRepeatf();}, EShortcut::GLOBAL_CANCEL);
 		repeat->setBorderColor(Colors::METALLIC_GOLD);
-		labels.push_back(std::make_shared<CLabel>(232, 520, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->translate("vcmi.battleResultsWindow.applyResultsLabel")));
+		labels.push_back(std::make_shared<CLabel>(232, 520, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.battleResultsWindow.applyResultsLabel")));
 	}
 
 	if(br.winner == BattleSide::ATTACKER)
 	{
-		labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]));
+		labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[410]));
 	}
 	else
 	{
-		labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
+		labels.push_back(std::make_shared<CLabel>(59, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[411]));
 	}
 	
 	if(br.winner == BattleSide::DEFENDER)
 	{
-		labels.push_back(std::make_shared<CLabel>(412, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[410]));
+		labels.push_back(std::make_shared<CLabel>(412, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[410]));
 	}
 	else
 	{
-		labels.push_back(std::make_shared<CLabel>(408, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[411]));
+		labels.push_back(std::make_shared<CLabel>(408, 124, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[411]));
 	}
 
-	labels.push_back(std::make_shared<CLabel>(232, 302, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,  CGI->generaltexth->allTexts[407]));
-	labels.push_back(std::make_shared<CLabel>(232, 332, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[408]));
-	labels.push_back(std::make_shared<CLabel>(232, 428, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[409]));
+	labels.push_back(std::make_shared<CLabel>(232, 302, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,  LIBRARY->generaltexth->allTexts[407]));
+	labels.push_back(std::make_shared<CLabel>(232, 332, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[408]));
+	labels.push_back(std::make_shared<CLabel>(232, 428, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[409]));
 
 	std::string sideNames[2] = {"N/A", "N/A"};
 
@@ -817,7 +817,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
 	{
 		if(br.casualties[step].size()==0)
 		{
-			labels.push_back(std::make_shared<CLabel>(235, 360 + 97 * static_cast<int>(step), FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[523]));
+			labels.push_back(std::make_shared<CLabel>(235, 360 + 97 * static_cast<int>(step), FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->allTexts[523]));
 		}
 		else
 		{
@@ -825,7 +825,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
 			int yPos = 344 + static_cast<int>(step) * 97;
 			for(auto & elem : br.casualties[step])
 			{
-				auto creature = CGI->creatures()->getByIndex(elem.first);
+				auto creature = LIBRARY->creatures()->getByIndex(elem.first);
 				if (creature->getId() == CreatureID::ARROW_TOWERS )
 					continue; // do not show destroyed towers in battle results
 
@@ -843,7 +843,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
 	description = std::make_shared<CTextBox>(resources.resultText.toString(), Rect(69, 203, 330, 68), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
 	videoPlayer = std::make_shared<VideoWidget>(Point(107, 70), resources.prologueVideo, resources.loopedVideo, false);
 
-	CCS->musich->playMusic(resources.musicName, false, true);
+	ENGINE->music().playMusic(resources.musicName, false, true);
 }
 
 BattleResultResources BattleResultWindow::getResources(const BattleResult & br)
@@ -946,8 +946,8 @@ void BattleResultWindow::buttonPressed(int button)
 
 	close();
 
-	if(GH.windows().topWindow<BattleWindow>())
-		GH.windows().popWindows(1); //pop battle interface if present
+	if(ENGINE->windows().topWindow<BattleWindow>())
+		ENGINE->windows().popWindows(1); //pop battle interface if present
 
 	//Result window and battle interface are gone. We requested all dialogs to be closed before opening the battle,
 	//so we can be sure that there is no dialogs left on GUI stack.
@@ -976,7 +976,7 @@ StackQueue::StackQueue(bool Embedded, BattleInterface & owner)
 	{
 		int32_t queueSmallOutsideYOffset = 65;
 		bool queueSmallOutside = settings["battle"]["queueSmallOutside"].Bool() && (pos.y - queueSmallOutsideYOffset) >= 0;
-		queueSize = std::clamp(static_cast<int>(settings["battle"]["queueSmallSlots"].Float()), 1, queueSmallOutside ? GH.screenDimensions().x / 41 : 19);
+		queueSize = std::clamp(static_cast<int>(settings["battle"]["queueSmallSlots"].Float()), 1, queueSmallOutside ? ENGINE->screenDimensions().x / 41 : 19);
 
 		pos.w = queueSize * 41;
 		pos.h = 49;
@@ -1107,7 +1107,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn, std::
 		if(currentTurn && !owner->embedded)
 		{
 			std::string tmp = std::to_string(*currentTurn);
-			const auto & font = GH.renderHandler().loadFont(FONT_SMALL);
+			const auto & font = ENGINE->renderHandler().loadFont(FONT_SMALL);
 			int len = font->getStringWidth(tmp);
 			roundRect->pos.w = len + 6;
 			round->pos = Rect(roundRect->pos.center().x, roundRect->pos.center().y, 0, 0);
@@ -1170,5 +1170,5 @@ void StackQueue::StackBox::showPopupWindow(const Point & cursorPosition)
 	auto stacks = owner->owner.getBattle()->battleGetAllStacks();
 	for(const CStack * stack : stacks)
 		if(boundUnitID.has_value() && stack->unitId() == *boundUnitID)
-			GH.windows().createAndPushWindow<CStackWindow>(stack, true);
+			ENGINE->windows().createAndPushWindow<CStackWindow>(stack, true);
 }

+ 6 - 7
client/battle/BattleObstacleController.cpp

@@ -17,9 +17,8 @@
 #include "BattleRenderer.h"
 #include "CreatureAnimation.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
@@ -50,11 +49,11 @@ void BattleObstacleController::loadObstacleImage(const CObstacleInstance & oi)
 	if (oi.obstacleType == CObstacleInstance::ABSOLUTE_OBSTACLE)
 	{
 		// obstacle uses single bitmap image for animations
-		obstacleImages[oi.uniqueID] = GH.renderHandler().loadImage(animationName.toType<EResType::IMAGE>(), EImageBlitMode::SIMPLE);
+		obstacleImages[oi.uniqueID] = ENGINE->renderHandler().loadImage(animationName.toType<EResType::IMAGE>(), EImageBlitMode::SIMPLE);
 	}
 	else
 	{
-		obstacleAnimations[oi.uniqueID] = GH.renderHandler().loadAnimation(animationName, EImageBlitMode::SIMPLE);
+		obstacleAnimations[oi.uniqueID] = ENGINE->renderHandler().loadAnimation(animationName, EImageBlitMode::SIMPLE);
 		obstacleImages[oi.uniqueID] = obstacleAnimations[oi.uniqueID]->getImage(0);
 	}
 }
@@ -78,7 +77,7 @@ void BattleObstacleController::obstacleRemoved(const std::vector<ObstacleChanges
 		if(animationPath.empty())
 			continue;
 
-		auto animation = GH.renderHandler().loadAnimation(animationPath, EImageBlitMode::SIMPLE);
+		auto animation = ENGINE->renderHandler().loadAnimation(animationPath, EImageBlitMode::SIMPLE);
 		auto first = animation->getImage(0, 0);
 		if(!first)
 			continue;
@@ -105,7 +104,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 		if(!oi->visibleForSide(side, owner.getBattle()->battleHasNativeStack(side)))
 			continue;
 
-		auto animation = GH.renderHandler().loadAnimation(oi->getAppearAnimation(), EImageBlitMode::SIMPLE);
+		auto animation = ENGINE->renderHandler().loadAnimation(oi->getAppearAnimation(), EImageBlitMode::SIMPLE);
 		auto first = animation->getImage(0, 0);
 		if(!first)
 			continue;
@@ -113,7 +112,7 @@ void BattleObstacleController::obstaclePlaced(const std::vector<std::shared_ptr<
 		//we assume here that effect graphics have the same size as the usual obstacle image
 		// -> if we know how to blit obstacle, let's blit the effect in the same place
 		Point whereTo = getObstaclePosition(first, *oi);
-		CCS->soundh->playSound( oi->getAppearSound() );
+		ENGINE->sound().playSound( oi->getAppearSound() );
 		owner.stacksController->addNewAnim(new EffectAnimation(owner, oi->getAppearAnimation(), whereTo, oi->pos));
 
 		//so when multiple obstacles are added, they show up one after another

+ 2 - 2
client/battle/BattleOverlayLogVisualizer.cpp

@@ -19,7 +19,7 @@
 #include "../render/IFont.h"
 #include "../render/IRenderHandler.h"
 #include "../gui/TextAlignment.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../render/Graphics.h"
 
 BattleOverlayLogVisualizer::BattleOverlayLogVisualizer(
@@ -32,7 +32,7 @@ BattleOverlayLogVisualizer::BattleOverlayLogVisualizer(
 void BattleOverlayLogVisualizer::drawText(const BattleHex & hex, int lineNumber, const std::string & text)
 {
 	Point offset = owner.fieldController->hexPositionLocal(hex).topLeft() + Point(20, 20);
-	const auto & font = GH.renderHandler().loadFont(FONT_TINY);
+	const auto & font = ENGINE->renderHandler().loadFont(FONT_TINY);
 	int h = font->getLineHeight();
 
 	offset.y += h * lineNumber;

+ 2 - 3
client/battle/BattleProjectileController.cpp

@@ -18,8 +18,7 @@
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/IRenderHandler.h"
-#include "../gui/CGuiHandler.h"
-#include "../CGameInfo.h"
+#include "../GameEngine.h"
 
 #include "../../lib/CStack.h"
 #include "../../lib/mapObjects/CGTownInstance.h"
@@ -192,7 +191,7 @@ void BattleProjectileController::initStackProjectile(const CStack * stack)
 
 std::shared_ptr<CAnimation> BattleProjectileController::createProjectileImage(const AnimationPath & path )
 {
-	std::shared_ptr<CAnimation> projectile = GH.renderHandler().loadAnimation(path, EImageBlitMode::COLORKEY);
+	std::shared_ptr<CAnimation> projectile = ENGINE->renderHandler().loadAnimation(path, EImageBlitMode::COLORKEY);
 
 	if(projectile->size(1) != 0)
 		logAnim->error("Expected empty group 1 in stack projectile");

+ 6 - 7
client/battle/BattleSiegeController.cpp

@@ -17,9 +17,8 @@
 #include "BattleFieldController.h"
 #include "BattleRenderer.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/Canvas.h"
 #include "../render/IImage.h"
@@ -179,7 +178,7 @@ BattleSiegeController::BattleSiegeController(BattleInterface & owner, const CGTo
 		if ( !getWallPieceExistence(EWallVisual::EWallVisual(g)) )
 			continue;
 
-		wallPieceImages[g] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED), EImageBlitMode::COLORKEY);
+		wallPieceImages[g] = ENGINE->renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(g), EWallState::REINFORCED), EImageBlitMode::COLORKEY);
 	}
 }
 
@@ -255,10 +254,10 @@ void BattleSiegeController::gateStateChanged(const EGateState state)
 		wallPieceImages[EWallVisual::GATE] = nullptr;
 
 	if (stateId != EWallState::NONE)
-		wallPieceImages[EWallVisual::GATE] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::GATE,  stateId), EImageBlitMode::COLORKEY);
+		wallPieceImages[EWallVisual::GATE] = ENGINE->renderHandler().loadImage(getWallPieceImageName(EWallVisual::GATE,  stateId), EImageBlitMode::COLORKEY);
 
 	if (playSound)
-		CCS->soundh->playSound(soundBase::DRAWBRG);
+		ENGINE->sound().playSound(soundBase::DRAWBRG);
 }
 
 void BattleSiegeController::showAbsoluteObstacles(Canvas & canvas)
@@ -349,7 +348,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 		for (auto attackInfo : ca.attackedParts)
 			positions.push_back(owner.stacksController->getStackPositionAtHex(attackInfo.destinationTile, nullptr) + Point(99, 120));
 
-		CCS->soundh->playSound( AudioPath::builtin("WALLHIT") );
+		ENGINE->sound().playSound( AudioPath::builtin("WALLHIT") );
 		owner.stacksController->addNewAnim(new EffectAnimation(owner, AnimationPath::builtin("SGEXPL.DEF"), positions));
 	}
 
@@ -364,7 +363,7 @@ void BattleSiegeController::stackIsCatapulting(const CatapultAttack & ca)
 
 		auto wallState = EWallState(owner.getBattle()->battleGetWallState(attackInfo.attackedPart));
 
-		wallPieceImages[wallId] = GH.renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState), EImageBlitMode::COLORKEY);
+		wallPieceImages[wallId] = ENGINE->renderHandler().loadImage(getWallPieceImageName(EWallVisual::EWallVisual(wallId), wallState), EImageBlitMode::COLORKEY);
 	}
 }
 

+ 8 - 9
client/battle/BattleStacksController.cpp

@@ -23,8 +23,7 @@
 #include "CreatureAnimation.h"
 
 #include "../CPlayerInterface.h"
-#include "../CGameInfo.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../gui/WindowHandler.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/Colors.h"
@@ -81,10 +80,10 @@ BattleStacksController::BattleStacksController(BattleInterface & owner):
 	animIDhelper(0)
 {
 	//preparing graphics for displaying amounts of creatures
-	amountNormal     = GH.renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowDefault"), EImageBlitMode::COLORKEY);
-	amountPositive   = GH.renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowPositive"), EImageBlitMode::COLORKEY);
-	amountNegative   = GH.renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowNegative"), EImageBlitMode::COLORKEY);
-	amountEffNeutral = GH.renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowNeutral"), EImageBlitMode::COLORKEY);
+	amountNormal     = ENGINE->renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowDefault"), EImageBlitMode::COLORKEY);
+	amountPositive   = ENGINE->renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowPositive"), EImageBlitMode::COLORKEY);
+	amountNegative   = ENGINE->renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowNegative"), EImageBlitMode::COLORKEY);
+	amountEffNeutral = ENGINE->renderHandler().loadImage(ImagePath::builtin("combatUnitNumberWindowNeutral"), EImageBlitMode::COLORKEY);
 
 	std::vector<const CStack*> stacks = owner.getBattle()->battleGetAllStacks(true);
 	for(const CStack * s : stacks)
@@ -263,7 +262,7 @@ std::shared_ptr<IImage> BattleStacksController::getStackAmountBox(const CStack *
 
 	for(const auto & spellID : activeSpells)
 	{
-		auto positiveness = CGI->spells()->getByIndex(spellID)->getPositiveness();
+		auto positiveness = LIBRARY->spells()->getByIndex(spellID)->getPositiveness();
 		if(!boost::logic::indeterminate(positiveness))
 		{
 			if(positiveness)
@@ -472,7 +471,7 @@ void BattleStacksController::stacksAreAttacked(std::vector<StackAttackedInfo> at
 			{
 				auto spell = attackedInfo.spellEffect.toSpell();
 				if (!spell->getCastSound().empty())
-					CCS->soundh->playSound(spell->getCastSound());
+					ENGINE->sound().playSound(spell->getCastSound());
 
 
 				owner.displaySpellEffect(spell, attackedInfo.defender->getPosition());
@@ -842,7 +841,7 @@ void BattleStacksController::updateHoveredStacks()
 	}
 
 	if(mouseHoveredStacks != newStacks)
-		GH.windows().totalRedraw(); //fix for frozen stack info window and blue border in action bar
+		ENGINE->windows().totalRedraw(); //fix for frozen stack info window and blue border in action bar
 
 	mouseHoveredStacks = newStacks;
 }

+ 45 - 45
client/battle/BattleWindow.cpp

@@ -16,10 +16,10 @@
 #include "BattleStacksController.h"
 #include "BattleActionsController.h"
 
-#include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../windows/CSpellWindow.h"
@@ -56,8 +56,8 @@ BattleWindow::BattleWindow(BattleInterface & Owner):
 
 	PlayerColor defenderColor = owner.getBattle()->getBattle()->getSidePlayer(BattleSide::DEFENDER);
 	PlayerColor attackerColor = owner.getBattle()->getBattle()->getSidePlayer(BattleSide::ATTACKER);
-	bool isDefenderHuman = defenderColor.isValidPlayer() && LOCPLINT->cb->getStartInfo()->playerInfos.at(defenderColor).isControlledByHuman();
-	bool isAttackerHuman = attackerColor.isValidPlayer() && LOCPLINT->cb->getStartInfo()->playerInfos.at(attackerColor).isControlledByHuman();
+	bool isDefenderHuman = defenderColor.isValidPlayer() && GAME->interface()->cb->getStartInfo()->playerInfos.at(defenderColor).isControlledByHuman();
+	bool isAttackerHuman = attackerColor.isValidPlayer() && GAME->interface()->cb->getStartInfo()->playerInfos.at(attackerColor).isControlledByHuman();
 	onlyOnePlayerHuman = isDefenderHuman != isAttackerHuman;
 
 	REGISTER_BUILDER("battleConsole", &BattleWindow::buildBattleConsole);
@@ -131,9 +131,9 @@ void BattleWindow::createQueue()
 	std::string queueSize = settings["battle"]["queueSize"].String();
 
 	if(queueSize == "auto")
-		embedQueue = GH.screenDimensions().y < 700;
+		embedQueue = ENGINE->screenDimensions().y < 700;
 	else
-		embedQueue = GH.screenDimensions().y < 700 || queueSize == "small";
+		embedQueue = ENGINE->screenDimensions().y < 700 || queueSize == "small";
 
 	queue = std::make_shared<StackQueue>(embedQueue, owner);
 	if(!embedQueue && showQueue)
@@ -210,7 +210,7 @@ void BattleWindow::hideStickyQuickSpellWindow()
 
 	setPositionInfoWindow();
 	createTimerInfoWindows();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::showStickyQuickSpellWindow()
@@ -220,7 +220,7 @@ void BattleWindow::showStickyQuickSpellWindow()
 
 	auto hero = owner.getBattle()->battleGetMyHero();
 
-	if(GH.screenDimensions().x >= 1050 && hero != nullptr && hero->hasSpellbook())
+	if(ENGINE->screenDimensions().x >= 1050 && hero != nullptr && hero->hasSpellbook())
 	{
 		quickSpellWindow->enable();
 		quickSpellWindow->isEnabled = true;
@@ -233,7 +233,7 @@ void BattleWindow::showStickyQuickSpellWindow()
 
 	setPositionInfoWindow();
 	createTimerInfoWindows();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::createTimerInfoWindows()
@@ -242,14 +242,14 @@ void BattleWindow::createTimerInfoWindows()
 
 	int xOffsetAttacker = quickSpellWindow->isEnabled ? -53 : 0;
 
-	if(LOCPLINT->cb->getStartInfo()->turnTimerInfo.battleTimer != 0 || LOCPLINT->cb->getStartInfo()->turnTimerInfo.unitTimer != 0)
+	if(GAME->interface()->cb->getStartInfo()->turnTimerInfo.battleTimer != 0 || GAME->interface()->cb->getStartInfo()->turnTimerInfo.unitTimer != 0)
 	{
 		PlayerColor attacker = owner.getBattle()->sideToPlayer(BattleSide::ATTACKER);
 		PlayerColor defender = owner.getBattle()->sideToPlayer(BattleSide::DEFENDER);
 
 		if (attacker.isValidPlayer())
 		{
-			if (GH.screenDimensions().x >= 1000)
+			if (ENGINE->screenDimensions().x >= 1000)
 				attackerTimerWidget = std::make_shared<TurnTimerWidget>(Point(-92 + xOffsetAttacker, 1), attacker);
 			else
 				attackerTimerWidget = std::make_shared<TurnTimerWidget>(Point(1, 135), attacker);
@@ -257,7 +257,7 @@ void BattleWindow::createTimerInfoWindows()
 
 		if (defender.isValidPlayer())
 		{
-			if (GH.screenDimensions().x >= 1000)
+			if (ENGINE->screenDimensions().x >= 1000)
 				defenderTimerWidget = std::make_shared<TurnTimerWidget>(Point(pos.w + 16, 1), defender);
 			else
 				defenderTimerWidget = std::make_shared<TurnTimerWidget>(Point(pos.w - 78, 135), defender);
@@ -314,7 +314,7 @@ void BattleWindow::hideQueue()
 		pos = center();
 	}
 	setPositionInfoWindow();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::showQueue()
@@ -328,7 +328,7 @@ void BattleWindow::showQueue()
 	createQueue();
 	updateQueue();
 	setPositionInfoWindow();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::toggleStickyHeroWindowsVisibility()
@@ -353,7 +353,7 @@ void BattleWindow::hideStickyHeroWindows()
 	if(defenderHeroWindow)
 		defenderHeroWindow->disable();
 
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::showStickyHeroWindows()
@@ -366,7 +366,7 @@ void BattleWindow::showStickyHeroWindows()
 
 
 	createStickyHeroInfoWindows();
-	GH.windows().totalRedraw();
+	ENGINE->windows().totalRedraw();
 }
 
 void BattleWindow::updateQueue()
@@ -380,28 +380,28 @@ void BattleWindow::setPositionInfoWindow()
 	int xOffsetAttacker = quickSpellWindow->isEnabled ? -53 : 0;
 	if(defenderHeroWindow)
 	{
-		Point position = (GH.screenDimensions().x >= 1000)
+		Point position = (ENGINE->screenDimensions().x >= 1000)
 				? Point(pos.x + pos.w + 15, pos.y + 60)
 				: Point(pos.x + pos.w -79, pos.y + 195);
 		defenderHeroWindow->moveTo(position);
 	}
 	if(attackerHeroWindow)
 	{
-		Point position = (GH.screenDimensions().x >= 1000)
+		Point position = (ENGINE->screenDimensions().x >= 1000)
 				? Point(pos.x - 93 + xOffsetAttacker, pos.y + 60)
 				: Point(pos.x + 1, pos.y + 195);
 		attackerHeroWindow->moveTo(position);
 	}
 	if(defenderStackWindow)
 	{
-		Point position = (GH.screenDimensions().x >= 1000)
+		Point position = (ENGINE->screenDimensions().x >= 1000)
 				? Point(pos.x + pos.w + 15, defenderHeroWindow ? defenderHeroWindow->pos.y + 210 : pos.y + 60)
 				: Point(pos.x + pos.w -79, defenderHeroWindow ? defenderHeroWindow->pos.y : pos.y + 195);
 		defenderStackWindow->moveTo(position);
 	}
 	if(attackerStackWindow)
 	{
-		Point position = (GH.screenDimensions().x >= 1000)
+		Point position = (ENGINE->screenDimensions().x >= 1000)
 				? Point(pos.x - 93 + xOffsetAttacker, attackerHeroWindow ? attackerHeroWindow->pos.y + 210 : pos.y + 60)
 				: Point(pos.x + 1, attackerHeroWindow ? attackerHeroWindow->pos.y : pos.y + 195);
 		attackerStackWindow->moveTo(position);
@@ -457,16 +457,16 @@ void BattleWindow::heroManaPointsChanged(const CGHeroInstance * hero)
 
 void BattleWindow::activate()
 {
-	GH.setStatusbar(console);
+	ENGINE->setStatusbar(console);
 	CIntObject::activate();
-	LOCPLINT->cingconsole->activate();
+	GAME->interface()->cingconsole->activate();
 }
 
 void BattleWindow::deactivate()
 {
-	GH.setStatusbar(nullptr);
+	ENGINE->setStatusbar(nullptr);
 	CIntObject::deactivate();
-	LOCPLINT->cingconsole->deactivate();
+	GAME->interface()->cingconsole->deactivate();
 }
 
 bool BattleWindow::captureThisKey(EShortcut key)
@@ -541,9 +541,9 @@ void BattleWindow::bOptionsf()
 	if (owner.actionsController->heroSpellcastingModeActive())
 		return;
 
-	CCS->curh->set(Cursor::Map::POINTER);
+	ENGINE->cursor().set(Cursor::Map::POINTER);
 
-	GH.windows().createAndPushWindow<SettingsMainWindow>(&owner);
+	ENGINE->windows().createAndPushWindow<SettingsMainWindow>(&owner);
 }
 
 void BattleWindow::bSurrenderf()
@@ -561,7 +561,7 @@ void BattleWindow::bSurrenderf()
 			enemyHeroName = "#ENEMY#";
 		}
 
-		std::string surrenderMessage = boost::str(boost::format(CGI->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
+		std::string surrenderMessage = boost::str(boost::format(LIBRARY->generaltexth->allTexts[32]) % enemyHeroName % cost); //%s states: "I will accept your surrender and grant you and your troops safe passage for the price of %d gold."
 		owner.curInt->showYesNoDialog(surrenderMessage, [this](){ reallySurrender(); }, nullptr);
 	}
 }
@@ -574,7 +574,7 @@ void BattleWindow::bFleef()
 	if ( owner.getBattle()->battleCanFlee() )
 	{
 		auto ony = std::bind(&BattleWindow::reallyFlee,this);
-		owner.curInt->showYesNoDialog(CGI->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
+		owner.curInt->showYesNoDialog(LIBRARY->generaltexth->allTexts[28], ony, nullptr); //Are you sure you want to retreat?
 	}
 	else
 	{
@@ -588,7 +588,7 @@ void BattleWindow::bFleef()
 			if (owner.defendingHeroInstance->tempOwner == owner.curInt->cb->getPlayerID())
 				heroName = owner.defendingHeroInstance->getNameTranslated();
 		//calculating text
-		auto txt = boost::format(CGI->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat!
+		auto txt = boost::format(LIBRARY->generaltexth->allTexts[340]) % heroName; //The Shackles of War are present.  %s can not retreat!
 
 		//printing message
 		owner.curInt->showInfoDialog(boost::str(txt), comps);
@@ -598,19 +598,19 @@ void BattleWindow::bFleef()
 void BattleWindow::reallyFlee()
 {
 	owner.giveCommand(EActionType::RETREAT);
-	CCS->curh->set(Cursor::Map::POINTER);
+	ENGINE->cursor().set(Cursor::Map::POINTER);
 }
 
 void BattleWindow::reallySurrender()
 {
 	if (owner.curInt->cb->getResourceAmount(EGameResID::GOLD) < owner.getBattle()->battleGetSurrenderCost())
 	{
-		owner.curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold!
+		owner.curInt->showInfoDialog(LIBRARY->generaltexth->allTexts[29]); //You don't have enough gold!
 	}
 	else
 	{
 		owner.giveCommand(EActionType::SURRENDER);
-		CCS->curh->set(Cursor::Map::POINTER);
+		ENGINE->cursor().set(Cursor::Map::POINTER);
 	}
 }
 
@@ -722,13 +722,13 @@ void BattleWindow::bSpellf()
 	if(!myHero)
 		return;
 
-	CCS->curh->set(Cursor::Map::POINTER);
+	ENGINE->cursor().set(Cursor::Map::POINTER);
 
 	ESpellCastProblem spellCastProblem = owner.getBattle()->battleCanCastSpell(myHero, spells::Mode::HERO);
 
 	if(spellCastProblem == ESpellCastProblem::OK)
 	{
-		GH.windows().createAndPushWindow<CSpellWindow>(myHero, owner.curInt.get());
+		ENGINE->windows().createAndPushWindow<CSpellWindow>(myHero, owner.curInt.get());
 	}
 	else if (spellCastProblem == ESpellCastProblem::MAGIC_IS_BLOCKED)
 	{
@@ -746,13 +746,13 @@ void BattleWindow::bSpellf()
 			std::string heroName = myHero->hasArt(artID, true) ? myHero->getNameTranslated() : owner.enemyHero().name;
 
 			//%s wields the %s, an ancient artifact which creates a p dead to all magic.
-			LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[683])
-										% heroName % CGI->artifacts()->getByIndex(artID)->getNameTranslated()));
+			GAME->interface()->showInfoDialog(boost::str(boost::format(LIBRARY->generaltexth->allTexts[683])
+										% heroName % LIBRARY->artifacts()->getByIndex(artID)->getNameTranslated()));
 		}
 		else if(blockingBonus->source == BonusSource::OBJECT_TYPE)
 		{
 			if(blockingBonus->sid.as<MapObjectID>() == Obj::GARRISON || blockingBonus->sid.as<MapObjectID>() == Obj::GARRISON2)
-				LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[684]);
+				GAME->interface()->showInfoDialog(LIBRARY->generaltexth->allTexts[684]);
 		}
 	}
 	else
@@ -866,7 +866,7 @@ void BattleWindow::bOpenActiveUnit()
 	const auto * unit = owner.stacksController->getActiveStack();
 
 	if (unit)
-		GH.windows().createAndPushWindow<CStackWindow>(unit, false);
+		ENGINE->windows().createAndPushWindow<CStackWindow>(unit, false);
 }
 
 void BattleWindow::bOpenHoveredUnit()
@@ -877,7 +877,7 @@ void BattleWindow::bOpenHoveredUnit()
 	{
 		const auto * unit = owner.getBattle()->battleGetStackByID(units[0]);
 		if (unit)
-			GH.windows().createAndPushWindow<CStackWindow>(unit, false);
+			ENGINE->windows().createAndPushWindow<CStackWindow>(unit, false);
 	}
 }
 
@@ -891,8 +891,8 @@ void BattleWindow::endWithAutocombat()
 	if(!owner.makingTurn() || owner.tacticsMode)
 		return;
 
-	LOCPLINT->showYesNoDialog(
-		VLC->generaltexth->translate("vcmi.battleWindow.endWithAutocombat"),
+	GAME->interface()->showYesNoDialog(
+		LIBRARY->generaltexth->translate("vcmi.battleWindow.endWithAutocombat"),
 		[this]()
 		{
 			owner.curInt->isAutoFightEndBattle = true;
@@ -923,19 +923,19 @@ void BattleWindow::showAll(Canvas & to)
 {
 	CIntObject::showAll(to);
 
-	if (GH.screenDimensions().x != 800 || GH.screenDimensions().y !=600)
+	if (ENGINE->screenDimensions().x != 800 || ENGINE->screenDimensions().y !=600)
 		CMessage::drawBorder(owner.curInt->playerID, to, pos.w+28, pos.h+29, pos.x-14, pos.y-15);
 }
 
 void BattleWindow::show(Canvas & to)
 {
 	CIntObject::show(to);
-	LOCPLINT->cingconsole->show(to);
+	GAME->interface()->cingconsole->show(to);
 }
 
 void BattleWindow::close()
 {
-	if(!GH.windows().isTopWindow(this))
+	if(!ENGINE->windows().isTopWindow(this))
 		logGlobal->error("Only top interface must be closed");
-	GH.windows().popWindows(1);
+	ENGINE->windows().popWindows(1);
 }

+ 3 - 3
client/battle/CreatureAnimation.cpp

@@ -13,7 +13,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/CCreatureHandler.h"
 
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../render/CAnimation.h"
 #include "../render/Canvas.h"
 #include "../render/ColorFilter.h"
@@ -195,8 +195,8 @@ CreatureAnimation::CreatureAnimation(const AnimationPath & name_, TSpeedControll
 	  once(false)
 {
 
-	forward = GH.renderHandler().loadAnimation(name_, EImageBlitMode::WITH_SHADOW_AND_SELECTION);
-	reverse = GH.renderHandler().loadAnimation(name_, EImageBlitMode::WITH_SHADOW_AND_SELECTION);
+	forward = ENGINE->renderHandler().loadAnimation(name_, EImageBlitMode::WITH_SHADOW_AND_SELECTION);
+	reverse = ENGINE->renderHandler().loadAnimation(name_, EImageBlitMode::WITH_SHADOW_AND_SELECTION);
 
 	if (forward->size(size_t(ECreatureAnimType::DEATH)) == 0)
 		throw std::runtime_error("Animation '" + name_.getOriginalName() + "' has empty death animation!");

+ 20 - 22
client/eventsSDL/InputHandler.cpp

@@ -18,7 +18,7 @@
 #include "InputSourceText.h"
 #include "InputSourceGameController.h"
 
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../gui/CursorHandler.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/MouseButton.h"
@@ -26,7 +26,6 @@
 #include "../media/ISoundPlayer.h"
 #include "../CMT.h"
 #include "../CPlayerInterface.h"
-#include "../CGameInfo.h"
 
 #include "../../lib/CConfigHandler.h"
 
@@ -134,7 +133,7 @@ void InputHandler::setCurrentInputMode(InputMode modi)
 	if(currentInputMode != modi)
 	{
 		currentInputMode = modi;
-		GH.events().dispatchInputModeChanged(modi);
+		ENGINE->events().dispatchInputModeChanged(modi);
 	}
 }
 
@@ -193,7 +192,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 {
 	if(ev.type == SDL_QUIT)
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 #ifdef VCMI_ANDROID
 		handleQuit(false);
 #else
@@ -206,21 +205,21 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 		if(ev.key.keysym.sym == SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT))
 		{
 			// FIXME: dead code? Looks like intercepted by OS/SDL and delivered as SDL_Quit instead?
-			boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+			boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 			handleQuit(true);
 			return;
 		}
 
 		if(ev.key.keysym.scancode == SDL_SCANCODE_AC_BACK && !settings["input"]["handleBackRightMouseButton"].Bool())
 		{
-			boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+			boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 			handleQuit(true);
 			return;
 		}
 	}
 	else if(ev.type == SDL_USEREVENT)
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 		handleUserEvent(ev.user);
 
 		return;
@@ -231,34 +230,34 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 			case SDL_WINDOWEVENT_RESTORED:
 #ifndef VCMI_IOS
 			{
-				boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
-				GH.onScreenResize(false);
+				boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
+				ENGINE->onScreenResize(false);
 			}
 #endif
 				break;
 			case SDL_WINDOWEVENT_SIZE_CHANGED:
 #ifdef VCMI_ANDROID
 			{
-				boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
-				GH.onScreenResize(true);
+				boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
+				ENGINE->onScreenResize(true);
 			}
 #endif
 				break;
 			case SDL_WINDOWEVENT_FOCUS_GAINED:
 			{
-				boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+				boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 				if(settings["general"]["audioMuteFocus"].Bool()) {
-					CCS->musich->setVolume(settings["general"]["music"].Integer());
-					CCS->soundh->setVolume(settings["general"]["sound"].Integer());
+					ENGINE->music().setVolume(settings["general"]["music"].Integer());
+					ENGINE->sound().setVolume(settings["general"]["sound"].Integer());
 				}
 			}
 				break;
 			case SDL_WINDOWEVENT_FOCUS_LOST:
 			{
-				boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+				boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 				if(settings["general"]["audioMuteFocus"].Bool()) {
-					CCS->musich->setVolume(0);
-					CCS->soundh->setVolume(0);
+					ENGINE->music().setVolume(0);
+					ENGINE->sound().setVolume(0);
 				}
 			}
 				break;
@@ -267,7 +266,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 	}
 	else if(ev.type == SDL_SYSWMEVENT)
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 		if(!settings["session"]["headless"].Bool() && settings["general"]["notifications"].Bool())
 		{
 			NotificationHandler::handleSdlEvent(ev);
@@ -292,9 +291,8 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
 	//preprocessing
 	if(ev.type == SDL_MOUSEMOTION)
 	{
-		boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
-		if (CCS && CCS->curh)
-			CCS->curh->cursorMove(ev.motion.x, ev.motion.y);
+		boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
+		ENGINE->cursor().cursorMove(ev.motion.x, ev.motion.y);
 	}
 
 	{
@@ -368,7 +366,7 @@ void InputHandler::moveCursorPosition(const Point & distance)
 void InputHandler::setCursorPosition(const Point & position)
 {
 	cursorPosition = position;
-	GH.events().dispatchMouseMoved(Point(0, 0), position);
+	ENGINE->events().dispatchMouseMoved(Point(0, 0), position);
 }
 
 void InputHandler::startTextInput(const Rect & where)

+ 24 - 28
client/eventsSDL/InputSourceGameController.cpp

@@ -13,8 +13,7 @@
 
 #include "InputHandler.h"
 
-#include "../CGameInfo.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../gui/CursorHandler.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/ShortcutHandler.h"
@@ -147,7 +146,7 @@ void InputSourceGameController::dispatchAxisShortcuts(const std::vector<EShortcu
 	{
 		if(!pressedAxes.count(axisID))
 		{
-			GH.events().dispatchShortcutPressed(shortcutsVector);
+			ENGINE->events().dispatchShortcutPressed(shortcutsVector);
 			pressedAxes.insert(axisID);
 		}
 	}
@@ -155,7 +154,7 @@ void InputSourceGameController::dispatchAxisShortcuts(const std::vector<EShortcu
 	{
 		if(pressedAxes.count(axisID))
 		{
-			GH.events().dispatchShortcutReleased(shortcutsVector);
+			ENGINE->events().dispatchShortcutReleased(shortcutsVector);
 			pressedAxes.erase(axisID);
 		}
 	}
@@ -168,8 +167,8 @@ void InputSourceGameController::handleEventAxisMotion(const SDL_ControllerAxisEv
 	SDL_GameControllerAxis axisID = static_cast<SDL_GameControllerAxis>(axis.axis);
 	std::string axisName = SDL_GameControllerGetStringForAxis(axisID);
 
-	auto axisActions = GH.shortcuts().translateJoystickAxis(axisName);
-	auto buttonActions = GH.shortcuts().translateJoystickButton(axisName);
+	auto axisActions = ENGINE->shortcuts().translateJoystickAxis(axisName);
+	auto buttonActions = ENGINE->shortcuts().translateJoystickButton(axisName);
 
 	for(const auto & action : axisActions)
 	{
@@ -195,45 +194,42 @@ void InputSourceGameController::handleEventAxisMotion(const SDL_ControllerAxisEv
 
 void InputSourceGameController::tryToConvertCursor()
 {
-	assert(CCS);
-	assert(CCS->curh);
-	if(CCS->curh->getShowType() == Cursor::ShowType::HARDWARE)
+	if(ENGINE->cursor().getShowType() == Cursor::ShowType::HARDWARE)
 	{
-		int scalingFactor = GH.screenHandler().getScalingFactor();
-		const Point & cursorPosition = GH.getCursorPosition();
-		CCS->curh->changeCursor(Cursor::ShowType::SOFTWARE);
-		CCS->curh->cursorMove(cursorPosition.x * scalingFactor, cursorPosition.y * scalingFactor);
-		GH.input().setCursorPosition(cursorPosition);
+		int scalingFactor = ENGINE->screenHandler().getScalingFactor();
+		const Point & cursorPosition = ENGINE->getCursorPosition();
+		ENGINE->cursor().changeCursor(Cursor::ShowType::SOFTWARE);
+		ENGINE->cursor().cursorMove(cursorPosition.x * scalingFactor, cursorPosition.y * scalingFactor);
+		ENGINE->input().setCursorPosition(cursorPosition);
 	}
 }
 
 void InputSourceGameController::handleEventButtonDown(const SDL_ControllerButtonEvent & button)
 {
 	std::string buttonName = SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(button.button));
-	const auto & shortcutsVector = GH.shortcuts().translateJoystickButton(buttonName);
-	GH.events().dispatchShortcutPressed(shortcutsVector);
+	const auto & shortcutsVector = ENGINE->shortcuts().translateJoystickButton(buttonName);
+	ENGINE->events().dispatchShortcutPressed(shortcutsVector);
 }
 
 void InputSourceGameController::handleEventButtonUp(const SDL_ControllerButtonEvent & button)
 {
 	std::string buttonName = SDL_GameControllerGetStringForButton(static_cast<SDL_GameControllerButton>(button.button));
-	const auto & shortcutsVector = GH.shortcuts().translateJoystickButton(buttonName);
-	GH.events().dispatchShortcutReleased(shortcutsVector);
+	const auto & shortcutsVector = ENGINE->shortcuts().translateJoystickButton(buttonName);
+	ENGINE->events().dispatchShortcutReleased(shortcutsVector);
 }
 
 void InputSourceGameController::doCursorMove(int deltaX, int deltaY)
 {
 	if(deltaX == 0 && deltaY == 0)
 		return;
-	const Point & screenSize = GH.screenDimensions();
-	const Point & cursorPosition = GH.getCursorPosition();
-	int scalingFactor = GH.screenHandler().getScalingFactor();
+	const Point & screenSize = ENGINE->screenDimensions();
+	const Point & cursorPosition = ENGINE->getCursorPosition();
+	int scalingFactor = ENGINE->screenHandler().getScalingFactor();
 	int newX = std::min(std::max(cursorPosition.x + deltaX, 0), screenSize.x);
 	int newY = std::min(std::max(cursorPosition.y + deltaY, 0), screenSize.y);
 	Point targetPosition{newX, newY};
-	GH.input().setCursorPosition(targetPosition);
-	if(CCS && CCS->curh)
-		CCS->curh->cursorMove(GH.getCursorPosition().x * scalingFactor, GH.getCursorPosition().y * scalingFactor);
+	ENGINE->input().setCursorPosition(targetPosition);
+	ENGINE->cursor().cursorMove(ENGINE->getCursorPosition().x * scalingFactor, ENGINE->getCursorPosition().y * scalingFactor);
 }
 
 int InputSourceGameController::getMoveDis(float planDis)
@@ -298,12 +294,12 @@ void InputSourceGameController::handleScrollUpdate(int32_t deltaTimeMs)
 	else if(!scrollAxisMoved && !isScrollAxisReleased())
 	{
 		scrollAxisMoved = true;
-		scrollCurrent = scrollStart = GH.input().getCursorPosition();
-		GH.events().dispatchGesturePanningStarted(scrollStart);
+		scrollCurrent = scrollStart = ENGINE->input().getCursorPosition();
+		ENGINE->events().dispatchGesturePanningStarted(scrollStart);
 	}
 	else if(scrollAxisMoved && isScrollAxisReleased())
 	{
-		GH.events().dispatchGesturePanningEnded(scrollStart, scrollCurrent);
+		ENGINE->events().dispatchGesturePanningEnded(scrollStart, scrollCurrent);
 		scrollAxisMoved = false;
 		scrollPlanDisX = scrollPlanDisY = 0;
 		return;
@@ -320,7 +316,7 @@ void InputSourceGameController::handleScrollUpdate(int32_t deltaTimeMs)
 		scrollCurrent.x += moveDisX;
 		scrollCurrent.y += moveDisY;
 		Point distance(moveDisX, moveDisY);
-		GH.events().dispatchGesturePanning(scrollStart, scrollCurrent, distance);
+		ENGINE->events().dispatchGesturePanning(scrollStart, scrollCurrent, distance);
 	}
 }
 

+ 11 - 10
client/eventsSDL/InputSourceKeyboard.cpp

@@ -13,7 +13,8 @@
 
 #include "../../lib/CConfigHandler.h"
 #include "../CPlayerInterface.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/Shortcut.h"
 #include "../gui/ShortcutHandler.h"
@@ -70,7 +71,7 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 			std::string clipboardContent = clipboardBuffer;
 			boost::erase_all(clipboardContent, "\r");
 			boost::erase_all(clipboardContent, "\n");
-			GH.events().dispatchTextInput(clipboardContent);
+			ENGINE->events().dispatchTextInput(clipboardContent);
 			SDL_free(clipboardBuffer);
 			return;
 	 	}
@@ -84,20 +85,20 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 
 	if(handleBackRightMouseButton && key.keysym.scancode ==  SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
 	{
-		GH.events().dispatchShowPopup(GH.getCursorPosition(), settings["input"]["mouseToleranceDistance"].Integer());
+		ENGINE->events().dispatchShowPopup(ENGINE->getCursorPosition(), settings["input"]["mouseToleranceDistance"].Integer());
 		return;
 	}
 
-	auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
+	auto shortcutsVector = ENGINE->shortcuts().translateKeycode(keyName);
 
 	if (vstd::contains(shortcutsVector, EShortcut::MAIN_MENU_LOBBY))
-		CSH->getGlobalLobby().activateInterface();
+		GAME->server().getGlobalLobby().activateInterface();
 
 	if (vstd::contains(shortcutsVector, EShortcut::GLOBAL_FULLSCREEN))
 	{
 		Settings full = settings.write["video"]["fullscreen"];
 		full->Bool() = !full->Bool();
-		GH.onScreenResize(true);
+		ENGINE->onScreenResize(true);
 	}
 
 	if (vstd::contains(shortcutsVector, EShortcut::SPECTATE_TRACK_HERO))
@@ -118,7 +119,7 @@ void InputSourceKeyboard::handleEventKeyDown(const SDL_KeyboardEvent & key)
 		s["spectate-skip-battle-result"].Bool() = !settings["session"]["spectate-skip-battle-result"].Bool();
 	}
 
-	GH.events().dispatchShortcutPressed(shortcutsVector);
+	ENGINE->events().dispatchShortcutPressed(shortcutsVector);
 }
 
 void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
@@ -128,7 +129,7 @@ void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
 
 	if(handleBackRightMouseButton && key.keysym.scancode ==  SDL_SCANCODE_AC_BACK) // on some android devices right mouse button is "back"
 	{
-		GH.events().dispatchClosePopup(GH.getCursorPosition());
+		ENGINE->events().dispatchClosePopup(ENGINE->getCursorPosition());
 		return;
 	}
 
@@ -143,9 +144,9 @@ void InputSourceKeyboard::handleEventKeyUp(const SDL_KeyboardEvent & key)
 
 	assert(key.state == SDL_RELEASED);
 
-	auto shortcutsVector = GH.shortcuts().translateKeycode(keyName);
+	auto shortcutsVector = ENGINE->shortcuts().translateKeycode(keyName);
 
-	GH.events().dispatchShortcutReleased(shortcutsVector);
+	ENGINE->events().dispatchShortcutReleased(shortcutsVector);
 }
 
 bool InputSourceKeyboard::isKeyboardCmdDown() const

+ 18 - 18
client/eventsSDL/InputSourceMouse.cpp

@@ -12,7 +12,7 @@
 #include "InputSourceMouse.h"
 #include "InputHandler.h"
 
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/MouseButton.h"
 
@@ -33,39 +33,39 @@ InputSourceMouse::InputSourceMouse()
 
 void InputSourceMouse::handleEventMouseMotion(const SDL_MouseMotionEvent & motion)
 {
-	Point newPosition = Point(motion.x, motion.y) / GH.screenHandler().getScalingFactor();
-	Point distance = Point(-motion.xrel, -motion.yrel) / GH.screenHandler().getScalingFactor();
+	Point newPosition = Point(motion.x, motion.y) / ENGINE->screenHandler().getScalingFactor();
+	Point distance = Point(-motion.xrel, -motion.yrel) / ENGINE->screenHandler().getScalingFactor();
 
 	mouseButtonsMask = motion.state;
 
 	if (mouseButtonsMask & SDL_BUTTON(SDL_BUTTON_MIDDLE))
-		GH.events().dispatchGesturePanning(middleClickPosition, newPosition, distance);
+		ENGINE->events().dispatchGesturePanning(middleClickPosition, newPosition, distance);
 	else if (mouseButtonsMask & SDL_BUTTON(SDL_BUTTON_LEFT))
-		GH.events().dispatchMouseDragged(newPosition, distance);
+		ENGINE->events().dispatchMouseDragged(newPosition, distance);
 	else if (mouseButtonsMask & SDL_BUTTON(SDL_BUTTON_RIGHT))
-		GH.events().dispatchMouseDraggedPopup(newPosition, distance);
+		ENGINE->events().dispatchMouseDraggedPopup(newPosition, distance);
 	else
-		GH.input().setCursorPosition(newPosition);
+		ENGINE->input().setCursorPosition(newPosition);
 }
 
 void InputSourceMouse::handleEventMouseButtonDown(const SDL_MouseButtonEvent & button)
 {
-	Point position = Point(button.x, button.y) / GH.screenHandler().getScalingFactor();
+	Point position = Point(button.x, button.y) / ENGINE->screenHandler().getScalingFactor();
 
 	switch(button.button)
 	{
 		case SDL_BUTTON_LEFT:
 			if(button.clicks > 1)
-				GH.events().dispatchMouseDoubleClick(position, mouseToleranceDistance);
+				ENGINE->events().dispatchMouseDoubleClick(position, mouseToleranceDistance);
 			else
-				GH.events().dispatchMouseLeftButtonPressed(position, mouseToleranceDistance);
+				ENGINE->events().dispatchMouseLeftButtonPressed(position, mouseToleranceDistance);
 			break;
 		case SDL_BUTTON_RIGHT:
-			GH.events().dispatchShowPopup(position, mouseToleranceDistance);
+			ENGINE->events().dispatchShowPopup(position, mouseToleranceDistance);
 			break;
 		case SDL_BUTTON_MIDDLE:
 			middleClickPosition = position;
-			GH.events().dispatchGesturePanningStarted(position);
+			ENGINE->events().dispatchGesturePanningStarted(position);
 			break;
 	}
 }
@@ -75,26 +75,26 @@ void InputSourceMouse::handleEventMouseWheel(const SDL_MouseWheelEvent & wheel)
 	//NOTE: while mouseX / mouseY properties are available since 2.26.0, they are not converted into logical coordinates so don't account for resolution scaling
 	// This SDL bug was fixed in 2.30.1: https://github.com/libsdl-org/SDL/issues/9097
 #if SDL_VERSION_ATLEAST(2,30,1)
-	GH.events().dispatchMouseScrolled(Point(wheel.x, wheel.y), Point(wheel.mouseX, wheel.mouseY) / GH.screenHandler().getScalingFactor());
+	ENGINE->events().dispatchMouseScrolled(Point(wheel.x, wheel.y), Point(wheel.mouseX, wheel.mouseY) / ENGINE->screenHandler().getScalingFactor());
 #else
-	GH.events().dispatchMouseScrolled(Point(wheel.x, wheel.y), GH.getCursorPosition());
+	ENGINE->events().dispatchMouseScrolled(Point(wheel.x, wheel.y), ENGINE->getCursorPosition());
 #endif
 }
 
 void InputSourceMouse::handleEventMouseButtonUp(const SDL_MouseButtonEvent & button)
 {
-	Point position = Point(button.x, button.y) / GH.screenHandler().getScalingFactor();
+	Point position = Point(button.x, button.y) / ENGINE->screenHandler().getScalingFactor();
 
 	switch(button.button)
 	{
 		case SDL_BUTTON_LEFT:
-			GH.events().dispatchMouseLeftButtonReleased(position, mouseToleranceDistance);
+			ENGINE->events().dispatchMouseLeftButtonReleased(position, mouseToleranceDistance);
 			break;
 		case SDL_BUTTON_RIGHT:
-			GH.events().dispatchClosePopup(position);
+			ENGINE->events().dispatchClosePopup(position);
 			break;
 		case SDL_BUTTON_MIDDLE:
-			GH.events().dispatchGesturePanningEnded(middleClickPosition, position);
+			ENGINE->events().dispatchGesturePanningEnded(middleClickPosition, position);
 			break;
 	}
 }

+ 6 - 6
client/eventsSDL/InputSourceText.cpp

@@ -11,7 +11,7 @@
 #include "StdInc.h"
 #include "InputSourceText.h"
 
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
 #include "../gui/EventDispatcher.h"
 #include "../render/IScreenHandler.h"
 #include "../renderSDL/SDL_Extensions.h"
@@ -29,19 +29,19 @@ InputSourceText::InputSourceText()
 
 void InputSourceText::handleEventTextInput(const SDL_TextInputEvent & text)
 {
-	GH.events().dispatchTextInput(text.text);
+	ENGINE->events().dispatchTextInput(text.text);
 }
 
 void InputSourceText::handleEventTextEditing(const SDL_TextEditingEvent & text)
 {
-	GH.events().dispatchTextEditing(text.text);
+	ENGINE->events().dispatchTextEditing(text.text);
 }
 
 void InputSourceText::startTextInput(const Rect & whereInput)
 {
-	GH.dispatchMainThread([whereInput]()
+	ENGINE->dispatchMainThread([whereInput]()
 	{
-		Rect rectInScreenCoordinates = GH.screenHandler().convertLogicalPointsToWindow(whereInput);
+		Rect rectInScreenCoordinates = ENGINE->screenHandler().convertLogicalPointsToWindow(whereInput);
 		SDL_Rect textInputRect = CSDL_Ext::toSDL(rectInScreenCoordinates);
 
 		SDL_SetTextInputRect(&textInputRect);
@@ -55,7 +55,7 @@ void InputSourceText::startTextInput(const Rect & whereInput)
 
 void InputSourceText::stopTextInput()
 {
-	GH.dispatchMainThread([]()
+	ENGINE->dispatchMainThread([]()
 	{
 		if (SDL_IsTextInputActive() == SDL_TRUE)
 		{

+ 38 - 39
client/eventsSDL/InputSourceTouch.cpp

@@ -14,9 +14,9 @@
 #include "InputHandler.h"
 
 #include "../../lib/CConfigHandler.h"
-#include "../CGameInfo.h"
 #include "../gui/CursorHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/EventDispatcher.h"
 #include "../gui/MouseButton.h"
 #include "../gui/WindowHandler.h"
@@ -58,24 +58,23 @@ InputSourceTouch::InputSourceTouch()
 
 void InputSourceTouch::handleEventFingerMotion(const SDL_TouchFingerEvent & tfinger)
 {
-	if (CCS && CCS->curh && settings["video"]["cursor"].String() == "software" && state != TouchState::RELATIVE_MODE)
-		CCS->curh->cursorMove(GH.getCursorPosition().x, GH.getCursorPosition().y);
+	if (settings["video"]["cursor"].String() == "software" && state != TouchState::RELATIVE_MODE)
+		ENGINE->cursor().cursorMove(ENGINE->getCursorPosition().x, ENGINE->getCursorPosition().y);
 
 	switch(state)
 	{
 		case TouchState::RELATIVE_MODE:
 		{
-			Point screenSize = GH.screenDimensions();
-			int scalingFactor = GH.screenHandler().getScalingFactor();
+			Point screenSize = ENGINE->screenDimensions();
+			int scalingFactor = ENGINE->screenHandler().getScalingFactor();
 
 			Point moveDistance {
 				static_cast<int>(screenSize.x * params.relativeModeSpeedFactor * tfinger.dx),
 				static_cast<int>(screenSize.y * params.relativeModeSpeedFactor * tfinger.dy)
 			};
 
-			GH.input().moveCursorPosition(moveDistance);
-			if (CCS && CCS->curh)
-				CCS->curh->cursorMove(GH.getCursorPosition().x * scalingFactor, GH.getCursorPosition().y * scalingFactor);
+			ENGINE->input().moveCursorPosition(moveDistance);
+			ENGINE->cursor().cursorMove(ENGINE->getCursorPosition().x * scalingFactor, ENGINE->getCursorPosition().y * scalingFactor);
 
 			break;
 		}
@@ -91,7 +90,7 @@ void InputSourceTouch::handleEventFingerMotion(const SDL_TouchFingerEvent & tfin
 			if ( std::abs(distance.x) > params.panningSensitivityThreshold || std::abs(distance.y) > params.panningSensitivityThreshold)
 			{
 				state = state == TouchState::TAP_DOWN_SHORT ? TouchState::TAP_DOWN_PANNING : TouchState::TAP_DOWN_PANNING_POPUP;
-				GH.events().dispatchGesturePanningStarted(lastTapPosition);
+				ENGINE->events().dispatchGesturePanningStarted(lastTapPosition);
 			}
 			break;
 		}
@@ -131,35 +130,35 @@ void InputSourceTouch::handleEventFingerDown(const SDL_TouchFingerEvent & tfinge
 			if(tfinger.x > 0.5)
 			{
 				if (tfinger.y < 0.5)
-					GH.events().dispatchShowPopup(GH.getCursorPosition(), params.touchToleranceDistance);
+					ENGINE->events().dispatchShowPopup(ENGINE->getCursorPosition(), params.touchToleranceDistance);
 				else
-					GH.events().dispatchMouseLeftButtonPressed(GH.getCursorPosition(), params.touchToleranceDistance);
+					ENGINE->events().dispatchMouseLeftButtonPressed(ENGINE->getCursorPosition(), params.touchToleranceDistance);
 			}
 			break;
 		}
 		case TouchState::IDLE:
 		{
 			lastTapPosition = convertTouchToMouse(tfinger);
-			GH.input().setCursorPosition(lastTapPosition);
+			ENGINE->input().setCursorPosition(lastTapPosition);
 			state = TouchState::TAP_DOWN_SHORT;
 			break;
 		}
 		case TouchState::TAP_DOWN_SHORT:
 		{
-			GH.input().setCursorPosition(convertTouchToMouse(tfinger));
-			GH.events().dispatchGesturePanningStarted(lastTapPosition);
+			ENGINE->input().setCursorPosition(convertTouchToMouse(tfinger));
+			ENGINE->events().dispatchGesturePanningStarted(lastTapPosition);
 			state = TouchState::TAP_DOWN_DOUBLE;
 			break;
 		}
 		case TouchState::TAP_DOWN_PANNING:
 		{
-			GH.input().setCursorPosition(convertTouchToMouse(tfinger));
+			ENGINE->input().setCursorPosition(convertTouchToMouse(tfinger));
 			state = TouchState::TAP_DOWN_DOUBLE;
 			break;
 		}
 		case TouchState::TAP_DOWN_DOUBLE:
 		{
-			CSH->getGlobalLobby().activateInterface();
+			GAME->server().getGlobalLobby().activateInterface();
 			break;
 		}
 		case TouchState::TAP_DOWN_LONG_AWAIT:
@@ -185,9 +184,9 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 			if(tfinger.x > 0.5)
 			{
 				if (tfinger.y < 0.5)
-					GH.events().dispatchClosePopup(GH.getCursorPosition());
+					ENGINE->events().dispatchClosePopup(ENGINE->getCursorPosition());
 				else
-					GH.events().dispatchMouseLeftButtonReleased(GH.getCursorPosition(), params.touchToleranceDistance);
+					ENGINE->events().dispatchMouseLeftButtonReleased(ENGINE->getCursorPosition(), params.touchToleranceDistance);
 			}
 			break;
 		}
@@ -198,16 +197,16 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 		}
 		case TouchState::TAP_DOWN_SHORT:
 		{
-			GH.input().setCursorPosition(convertTouchToMouse(tfinger));
+			ENGINE->input().setCursorPosition(convertTouchToMouse(tfinger));
 			if(tfinger.timestamp - lastLeftClickTimeTicks < params.doubleTouchTimeMilliseconds && (convertTouchToMouse(tfinger) - lastLeftClickPosition).length() < params.doubleTouchToleranceDistance)
 			{
-				GH.events().dispatchMouseDoubleClick(convertTouchToMouse(tfinger), params.touchToleranceDistance);
-				GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
+				ENGINE->events().dispatchMouseDoubleClick(convertTouchToMouse(tfinger), params.touchToleranceDistance);
+				ENGINE->events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
 			}
 			else
 			{
-				GH.events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger), params.touchToleranceDistance);
-				GH.events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
+				ENGINE->events().dispatchMouseLeftButtonPressed(convertTouchToMouse(tfinger), params.touchToleranceDistance);
+				ENGINE->events().dispatchMouseLeftButtonReleased(convertTouchToMouse(tfinger), params.touchToleranceDistance);
 				lastLeftClickTimeTicks = tfinger.timestamp;
 				lastLeftClickPosition = convertTouchToMouse(tfinger);
 			}
@@ -217,7 +216,7 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 		case TouchState::TAP_DOWN_PANNING:
 		case TouchState::TAP_DOWN_PANNING_POPUP:
 		{
-			GH.events().dispatchGesturePanningEnded(lastTapPosition, convertTouchToMouse(tfinger));
+			ENGINE->events().dispatchGesturePanningEnded(lastTapPosition, convertTouchToMouse(tfinger));
 			state = state == TouchState::TAP_DOWN_PANNING ? TouchState::IDLE : TouchState::TAP_DOWN_LONG_AWAIT;
 			break;
 		}
@@ -227,7 +226,7 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 				state = TouchState::TAP_DOWN_PANNING;
 			if (SDL_GetNumTouchFingers(tfinger.touchId) == 0)
 			{
-				GH.events().dispatchGesturePanningEnded(lastTapPosition, convertTouchToMouse(tfinger));
+				ENGINE->events().dispatchGesturePanningEnded(lastTapPosition, convertTouchToMouse(tfinger));
 				state = TouchState::IDLE;
 			}
 			break;
@@ -244,8 +243,8 @@ void InputSourceTouch::handleEventFingerUp(const SDL_TouchFingerEvent & tfinger)
 		{
 			if (SDL_GetNumTouchFingers(tfinger.touchId) == 0)
 			{
-				GH.input().setCursorPosition(convertTouchToMouse(tfinger));
-				GH.events().dispatchClosePopup(convertTouchToMouse(tfinger));
+				ENGINE->input().setCursorPosition(convertTouchToMouse(tfinger));
+				ENGINE->events().dispatchClosePopup(convertTouchToMouse(tfinger));
 				state = TouchState::IDLE;
 			}
 			break;
@@ -260,9 +259,9 @@ void InputSourceTouch::handleUpdate()
 		uint32_t currentTime = SDL_GetTicks();
 		if (currentTime > lastTapTimeTicks + params.longTouchTimeMilliseconds)
 		{
-			GH.events().dispatchShowPopup(GH.getCursorPosition(), params.touchToleranceDistance);
+			ENGINE->events().dispatchShowPopup(ENGINE->getCursorPosition(), params.touchToleranceDistance);
 
-			if (GH.windows().isTopWindowPopup())
+			if (ENGINE->windows().isTopWindowPopup())
 			{
 				hapticFeedback();
 				state = TouchState::TAP_DOWN_LONG;
@@ -278,7 +277,7 @@ Point InputSourceTouch::convertTouchToMouse(const SDL_TouchFingerEvent & tfinger
 
 Point InputSourceTouch::convertTouchToMouse(float x, float y)
 {
-	return Point(x * GH.screenDimensions().x, y * GH.screenDimensions().y);
+	return Point(x * ENGINE->screenDimensions().x, y * ENGINE->screenDimensions().y);
 }
 
 bool InputSourceTouch::hasTouchInputDevice() const
@@ -295,7 +294,7 @@ void InputSourceTouch::emitPanningEvent(const SDL_TouchFingerEvent & tfinger)
 {
 	Point distance = convertTouchToMouse(-tfinger.dx, -tfinger.dy);
 
-	GH.events().dispatchGesturePanning(lastTapPosition, convertTouchToMouse(tfinger), distance);
+	ENGINE->events().dispatchGesturePanning(lastTapPosition, convertTouchToMouse(tfinger), distance);
 }
 
 void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
@@ -315,8 +314,8 @@ void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
 
 		if (finger && finger->id != tfinger.fingerId)
 		{
-			otherX = finger->x * GH.screenDimensions().x;
-			otherY = finger->y * GH.screenDimensions().y;
+			otherX = finger->x * ENGINE->screenDimensions().x;
+			otherY = finger->y * ENGINE->screenDimensions().y;
 			otherFingerFound = true;
 			break;
 		}
@@ -325,10 +324,10 @@ void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
 	if (!otherFingerFound)
 		return; // should be impossible, but better to avoid weird edge cases
 
-	float thisX = tfinger.x * GH.screenDimensions().x;
-	float thisY = tfinger.y * GH.screenDimensions().y;
-	float deltaX = tfinger.dx * GH.screenDimensions().x;
-	float deltaY = tfinger.dy * GH.screenDimensions().y;
+	float thisX = tfinger.x * ENGINE->screenDimensions().x;
+	float thisY = tfinger.y * ENGINE->screenDimensions().y;
+	float deltaX = tfinger.dx * ENGINE->screenDimensions().x;
+	float deltaY = tfinger.dy * ENGINE->screenDimensions().y;
 
 	float oldX = thisX - deltaX - otherX;
 	float oldY = thisY - deltaY - otherY;
@@ -339,7 +338,7 @@ void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger)
 	double distanceNew = std::sqrt(newX * newX + newY * newY);
 
 	if (distanceOld > params.pinchSensitivityThreshold)
-		GH.events().dispatchGesturePinch(lastTapPosition, distanceNew / distanceOld);
+		ENGINE->events().dispatchGesturePinch(lastTapPosition, distanceNew / distanceOld);
 }
 
 void InputSourceTouch::hapticFeedback() {

+ 5 - 4
client/globalLobby/GlobalLobbyAddChannelWindow.cpp

@@ -14,7 +14,8 @@
 #include "GlobalLobbyClient.h"
 
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../gui/WindowHandler.h"
 #include "../widgets/Buttons.h"
@@ -45,8 +46,8 @@ GlobalLobbyAddChannelWindowCard::GlobalLobbyAddChannelWindowCard(const std::stri
 
 void GlobalLobbyAddChannelWindowCard::clickPressed(const Point & cursorPosition)
 {
-	CSH->getGlobalLobby().addChannel(languageID);
-	GH.windows().popWindows(1);
+	GAME->server().getGlobalLobby().addChannel(languageID);
+	ENGINE->windows().popWindows(1);
 }
 
 GlobalLobbyAddChannelWindow::GlobalLobbyAddChannelWindow()
@@ -66,7 +67,7 @@ GlobalLobbyAddChannelWindow::GlobalLobbyAddChannelWindow()
 	const auto & allLanguages = Languages::getLanguageList();
 	std::vector<std::string> newLanguages;
 	for (const auto & language : allLanguages)
-		if (!vstd::contains(CSH->getGlobalLobby().getActiveChannels(), language.identifier))
+		if (!vstd::contains(GAME->server().getGlobalLobby().getActiveChannels(), language.identifier))
 			newLanguages.push_back(language.identifier);
 
 	const auto & createChannelCardCallback = [newLanguages](size_t index) -> std::shared_ptr<CIntObject>

+ 38 - 37
client/globalLobby/GlobalLobbyClient.cpp

@@ -16,9 +16,9 @@
 #include "GlobalLobbyObserver.h"
 #include "GlobalLobbyWindow.h"
 
-#include "../CGameInfo.h"
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../mainmenu/CMainMenu.h"
 #include "../media/ISoundPlayer.h"
@@ -29,6 +29,7 @@
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/texts/MetaString.h"
 #include "../../lib/texts/TextOperations.h"
+#include "../../lib/GameLibrary.h"
 
 GlobalLobbyClient::GlobalLobbyClient()
 {
@@ -37,8 +38,8 @@ GlobalLobbyClient::GlobalLobbyClient()
 	if (customChannels.empty())
 	{
 		activeChannels.emplace_back("english");
-		if (CGI->generaltexth->getPreferredLanguage() != "english")
-			activeChannels.emplace_back(CGI->generaltexth->getPreferredLanguage());
+		if (LIBRARY->generaltexth->getPreferredLanguage() != "english")
+			activeChannels.emplace_back(LIBRARY->generaltexth->getPreferredLanguage());
 	}
 	else
 	{
@@ -58,7 +59,7 @@ void GlobalLobbyClient::addChannel(const std::string & channel)
 	toSend["type"].String() = "requestChatHistory";
 	toSend["channelType"].String() = "global";
 	toSend["channelName"].String() = channel;
-	CSH->getGlobalLobby().sendMessage(toSend);
+	GAME->server().getGlobalLobby().sendMessage(toSend);
 
 	Settings languageRooms = settings.write["lobby"]["languageRooms"];
 
@@ -86,7 +87,7 @@ GlobalLobbyClient::~GlobalLobbyClient() = default;
 
 void GlobalLobbyClient::onPacketReceived(const std::shared_ptr<INetworkConnection> &, const std::vector<std::byte> & message)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	JsonNode json(message.data(), message.size(), "<lobby network packet>");
 
@@ -127,7 +128,7 @@ void GlobalLobbyClient::receiveAccountCreated(const JsonNode & json)
 {
 	auto loginWindowPtr = loginWindow.lock();
 
-	if(!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+	if(!loginWindowPtr || !ENGINE->windows().topWindow<GlobalLobbyLoginWindow>())
 		throw std::runtime_error("lobby connection finished without active login window!");
 
 	{
@@ -158,7 +159,7 @@ void GlobalLobbyClient::receiveClientLoginSuccess(const JsonNode & json)
 
 	auto loginWindowPtr = loginWindow.lock();
 
-	if(!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+	if(!loginWindowPtr || !ENGINE->windows().topWindow<GlobalLobbyLoginWindow>())
 		throw std::runtime_error("lobby connection finished without active login window!");
 
 	loginWindowPtr->onLoginSuccess();
@@ -217,7 +218,7 @@ void GlobalLobbyClient::receiveChatMessage(const JsonNode & json)
 		lobbyWindowPtr->refreshChatText();
 
 		if(channelType == "player" || (lobbyWindowPtr->isChannelOpen(channelType, channelName) && lobbyWindowPtr->isActive()))
-			CCS->soundh->playSound(AudioPath::builtin("CHAT"));
+			ENGINE->sound().playSound(AudioPath::builtin("CHAT"));
 	}
 }
 
@@ -240,7 +241,7 @@ void GlobalLobbyClient::receiveActiveAccounts(const JsonNode & json)
 	if(lobbyWindowPtr)
 		lobbyWindowPtr->onActiveAccounts(activeAccounts);
 
-	for (auto const & window : GH.windows().findWindows<GlobalLobbyObserver>())
+	for (auto const & window : ENGINE->windows().findWindows<GlobalLobbyObserver>())
 		window->onActiveAccounts(activeAccounts);
 }
 
@@ -287,7 +288,7 @@ void GlobalLobbyClient::receiveActiveGameRooms(const JsonNode & json)
 	if(lobbyWindowPtr)
 		lobbyWindowPtr->onActiveGameRooms(activeRooms);
 
-	for (auto const & window : GH.windows().findWindows<GlobalLobbyObserver>())
+	for (auto const & window : ENGINE->windows().findWindows<GlobalLobbyObserver>())
 		window->onActiveGameRooms(activeRooms);
 }
 
@@ -342,33 +343,33 @@ void GlobalLobbyClient::receiveInviteReceived(const JsonNode & json)
 		lobbyWindowPtr->refreshChatText();
 	}
 
-	CCS->soundh->playSound(AudioPath::builtin("CHAT"));
+	ENGINE->sound().playSound(AudioPath::builtin("CHAT"));
 }
 
 void GlobalLobbyClient::receiveJoinRoomSuccess(const JsonNode & json)
 {
 	if (json["proxyMode"].Bool())
 	{
-		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_GUEST, { CSH->getGlobalLobby().getAccountDisplayName() });
-		CSH->loadMode = ELoadMode::MULTI;
+		GAME->server().resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_GUEST, { GAME->server().getGlobalLobby().getAccountDisplayName() });
+		GAME->server().loadMode = ELoadMode::MULTI;
 
 		std::string hostname = getServerHost();
 		uint16_t port = getServerPort();
-		CSH->connectToServer(hostname, port);
+		GAME->server().connectToServer(hostname, port);
 	}
 
-	// NOTE: must be set after CSH->resetStateForLobby call
+	// NOTE: must be set after GAME->server().resetStateForLobby call
 	currentGameRoomUUID = json["gameRoomID"].String();
 }
 
 void GlobalLobbyClient::onConnectionEstablished(const std::shared_ptr<INetworkConnection> & connection)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 	networkConnection = connection;
 
 	auto loginWindowPtr = loginWindow.lock();
 
-	if(!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+	if(!loginWindowPtr || !ENGINE->windows().topWindow<GlobalLobbyLoginWindow>())
 		throw std::runtime_error("lobby connection established without active login window!");
 
 	loginWindowPtr->onConnectionSuccess();
@@ -379,7 +380,7 @@ void GlobalLobbyClient::sendClientRegister(const std::string & accountName)
 	JsonNode toSend;
 	toSend["type"].String() = "clientRegister";
 	toSend["displayName"].String() = accountName;
-	toSend["language"].String() = CGI->generaltexth->getPreferredLanguage();
+	toSend["language"].String() = LIBRARY->generaltexth->getPreferredLanguage();
 	toSend["version"].String() = VCMI_VERSION_STRING;
 	sendMessage(toSend);
 }
@@ -390,7 +391,7 @@ void GlobalLobbyClient::sendClientLogin()
 	toSend["type"].String() = "clientLogin";
 	toSend["accountID"].String() = getAccountID();
 	toSend["accountCookie"].String() = getAccountCookie();
-	toSend["language"].String() = CGI->generaltexth->getPreferredLanguage();
+	toSend["language"].String() = LIBRARY->generaltexth->getPreferredLanguage();
 	toSend["version"].String() = VCMI_VERSION_STRING;
 
 	for (const auto & language : activeChannels)
@@ -401,11 +402,11 @@ void GlobalLobbyClient::sendClientLogin()
 
 void GlobalLobbyClient::onConnectionFailed(const std::string & errorMessage)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	auto loginWindowPtr = loginWindow.lock();
 
-	if(!loginWindowPtr || !GH.windows().topWindow<GlobalLobbyLoginWindow>())
+	if(!loginWindowPtr || !ENGINE->windows().topWindow<GlobalLobbyLoginWindow>())
 		throw std::runtime_error("lobby connection failed without active login window!");
 
 	logGlobal->warn("Connection to game lobby failed! Reason: %s", errorMessage);
@@ -414,16 +415,16 @@ void GlobalLobbyClient::onConnectionFailed(const std::string & errorMessage)
 
 void GlobalLobbyClient::onDisconnected(const std::shared_ptr<INetworkConnection> & connection, const std::string & errorMessage)
 {
-	boost::mutex::scoped_lock interfaceLock(GH.interfaceMutex);
+	boost::mutex::scoped_lock interfaceLock(ENGINE->interfaceMutex);
 
 	assert(connection == networkConnection);
 	networkConnection.reset();
 	accountLoggedIn = false;
 
-	while (!GH.windows().findWindows<GlobalLobbyWindow>().empty())
+	while (!ENGINE->windows().findWindows<GlobalLobbyWindow>().empty())
 	{
 		// if global lobby is open, pop all dialogs on top of it as well as lobby itself
-		GH.windows().popWindows(1);
+		ENGINE->windows().popWindows(1);
 	}
 
 	CInfoWindow::showInfoDialog("Connection to game lobby was lost!", {});
@@ -449,7 +450,7 @@ void GlobalLobbyClient::connect()
 {
 	std::string hostname = getServerHost();
 	uint16_t port = getServerPort();
-	CSH->getNetworkHandler().connectToRemote(*this, hostname, port);
+	GAME->server().getNetworkHandler().connectToRemote(*this, hostname, port);
 }
 
 bool GlobalLobbyClient::isLoggedIn() const
@@ -531,7 +532,7 @@ const std::vector<GlobalLobbyChannelMessage> & GlobalLobbyClient::getChannelHist
 			toSend["type"].String() = "requestChatHistory";
 			toSend["channelType"].String() = channelType;
 			toSend["channelName"].String() = channelName;
-			CSH->getGlobalLobby().sendMessage(toSend);
+			GAME->server().getGlobalLobby().sendMessage(toSend);
 		}
 		return emptyVector;
 	}
@@ -541,29 +542,29 @@ const std::vector<GlobalLobbyChannelMessage> & GlobalLobbyClient::getChannelHist
 
 void GlobalLobbyClient::activateInterface()
 {
-	if (GH.windows().topWindow<GlobalLobbyWindow>() != nullptr)
+	if (ENGINE->windows().topWindow<GlobalLobbyWindow>() != nullptr)
 	{
-		GH.windows().popWindows(1);
+		ENGINE->windows().popWindows(1);
 		return;
 	}
 
-	if (!GH.windows().findWindows<GlobalLobbyWindow>().empty())
+	if (!ENGINE->windows().findWindows<GlobalLobbyWindow>().empty())
 		return;
 
-	if (!GH.windows().findWindows<GlobalLobbyLoginWindow>().empty())
+	if (!ENGINE->windows().findWindows<GlobalLobbyLoginWindow>().empty())
 		return;
 
 	if (isLoggedIn())
-		GH.windows().pushWindow(createLobbyWindow());
+		ENGINE->windows().pushWindow(createLobbyWindow());
 	else
-		GH.windows().pushWindow(createLoginWindow());
+		ENGINE->windows().pushWindow(createLoginWindow());
 
-	GH.windows().topWindow<CIntObject>()->center();
+	ENGINE->windows().topWindow<CIntObject>()->center();
 }
 
 void GlobalLobbyClient::activateRoomInviteInterface()
 {
-	GH.windows().createAndPushWindow<GlobalLobbyInviteWindow>();
+	ENGINE->windows().createAndPushWindow<GlobalLobbyInviteWindow>();
 }
 
 void GlobalLobbyClient::setAccountID(const std::string & accountID)
@@ -647,7 +648,7 @@ void GlobalLobbyClient::sendMatchChatMessage(const std::string & messageText)
 
 	assert(TextOperations::isValidUnicodeString(messageText));
 
-	CSH->getGlobalLobby().sendMessage(toSend);
+	GAME->server().getGlobalLobby().sendMessage(toSend);
 }
 
 bool GlobalLobbyClient::isInvitedToRoom(const std::string & gameRoomID)
@@ -655,7 +656,7 @@ bool GlobalLobbyClient::isInvitedToRoom(const std::string & gameRoomID)
 	if (activeInvites.count(gameRoomID) > 0)
 		return true;
 
-	const auto & gameRoom = CSH->getGlobalLobby().getActiveRoomByName(gameRoomID);
+	const auto & gameRoom = GAME->server().getGlobalLobby().getActiveRoomByName(gameRoomID);
 	for (auto const & invited : gameRoom.invited)
 	{
 		if (invited.accountID == getAccountID())

+ 7 - 6
client/globalLobby/GlobalLobbyInviteWindow.cpp

@@ -14,7 +14,8 @@
 #include "GlobalLobbyClient.h"
 
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/GraphicalPrimitiveCanvas.h"
@@ -33,10 +34,10 @@ GlobalLobbyInviteAccountCard::GlobalLobbyInviteAccountCard(const GlobalLobbyAcco
 	addUsedEvents(LCLICK);
 
 	bool thisAccountInvited = false;
-	const auto & myRoomID = CSH->getGlobalLobby().getCurrentGameRoomID();
+	const auto & myRoomID = GAME->server().getGlobalLobby().getCurrentGameRoomID();
 	if (!myRoomID.empty())
 	{
-		const auto & myRoom = CSH->getGlobalLobby().getActiveRoomByName(myRoomID);
+		const auto & myRoom = GAME->server().getGlobalLobby().getActiveRoomByName(myRoomID);
 		for (auto const & invited : myRoom.invited)
 		{
 			if (invited.accountID == accountID)
@@ -67,7 +68,7 @@ void GlobalLobbyInviteAccountCard::clickPressed(const Point & cursorPosition)
 	message["type"].String() = "sendInvite";
 	message["accountID"].String() = accountID;
 
-	CSH->getGlobalLobby().sendMessage(message);
+	GAME->server().getGlobalLobby().sendMessage(message);
 }
 
 GlobalLobbyInviteWindow::GlobalLobbyInviteWindow()
@@ -86,7 +87,7 @@ GlobalLobbyInviteWindow::GlobalLobbyInviteWindow()
 
 	const auto & createAccountCardCallback = [](size_t index) -> std::shared_ptr<CIntObject>
 	{
-		const auto & accounts = CSH->getGlobalLobby().getActiveAccounts();
+		const auto & accounts = GAME->server().getGlobalLobby().getActiveAccounts();
 
 		if(index < accounts.size())
 			return std::make_shared<GlobalLobbyInviteAccountCard>(accounts[index]);
@@ -94,7 +95,7 @@ GlobalLobbyInviteWindow::GlobalLobbyInviteWindow()
 	};
 
 	listBackground = std::make_shared<TransparentFilledRectangle>(Rect(8, 48, 220, 324), ColorRGBA(0, 0, 0, 64), ColorRGBA(64, 80, 128, 255), 1);
-	accountList = std::make_shared<CListBox>(createAccountCardCallback, Point(10, 50), Point(0, 40), 8, CSH->getGlobalLobby().getActiveAccounts().size(), 0, 1 | 4, Rect(200, 0, 320, 320));
+	accountList = std::make_shared<CListBox>(createAccountCardCallback, Point(10, 50), Point(0, 40), 8, GAME->server().getGlobalLobby().getActiveAccounts().size(), 0, 1 | 4, Rect(200, 0, 320, 320));
 
 	buttonClose = std::make_shared<CButton>(Point(86, 384), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this]() { close(); }, EShortcut::GLOBAL_RETURN );
 

+ 16 - 15
client/globalLobby/GlobalLobbyLoginWindow.cpp

@@ -13,9 +13,9 @@
 
 #include "GlobalLobbyClient.h"
 
-#include "../CGameInfo.h"
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/CTextInput.h"
@@ -27,6 +27,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/texts/MetaString.h"
+#include "../../lib/GameLibrary.h"
 
 GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 	: CWindowObject(BORDERED)
@@ -38,11 +39,11 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 
 	MetaString loginAs;
 	loginAs.appendTextID("vcmi.lobby.login.as");
-	loginAs.replaceRawString(CSH->getGlobalLobby().getAccountDisplayName());
+	loginAs.replaceRawString(GAME->server().getGlobalLobby().getAccountDisplayName());
 
 	filledBackground = std::make_shared<FilledTexturePlayerColored>(Rect(0, 0, pos.w, pos.h));
-	labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.login.title"));
-	labelUsernameTitle = std::make_shared<CLabel>( 10, 65, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, CGI->generaltexth->translate("vcmi.lobby.login.username"));
+	labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.login.title"));
+	labelUsernameTitle = std::make_shared<CLabel>( 10, 65, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.lobby.login.username"));
 	labelUsername = std::make_shared<CLabel>( 10, 65, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, loginAs.toString(), 265);
 	backgroundUsername = std::make_shared<TransparentFilledRectangle>(Rect(10, 90, 264, 20), ColorRGBA(0,0,0,128), ColorRGBA(64,64,64,64));
 	inputUsername = std::make_shared<CTextInput>(Rect(15, 93, 260, 16), FONT_SMALL, ETextAlignment::CENTERLEFT, true);
@@ -52,8 +53,8 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 
 	auto buttonRegister = std::make_shared<CToggleButton>(Point(10, 40),  AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
 	auto buttonLogin = std::make_shared<CToggleButton>(Point(146, 40), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
-	buttonRegister->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.login.create"), EFonts::FONT_SMALL, Colors::YELLOW);
-	buttonLogin->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.login.login"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonRegister->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.login.create"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonLogin->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.login.login"), EFonts::FONT_SMALL, Colors::YELLOW);
 
 	toggleMode = std::make_shared<CToggleGroup>(nullptr);
 	toggleMode->addToggle(0, buttonRegister);
@@ -61,7 +62,7 @@ GlobalLobbyLoginWindow::GlobalLobbyLoginWindow()
 	toggleMode->setSelected(settings["lobby"]["roomType"].Integer());
 	toggleMode->addCallback([this](int index){onLoginModeChanged(index);});
 
-	if (CSH->getGlobalLobby().getAccountID().empty())
+	if (GAME->server().getGlobalLobby().getAccountID().empty())
 	{
 		buttonLogin->block(true);
 		toggleMode->setSelected(0);
@@ -109,9 +110,9 @@ void GlobalLobbyLoginWindow::onClose()
 
 void GlobalLobbyLoginWindow::onLogin()
 {
-	labelStatus->setText(CGI->generaltexth->translate("vcmi.lobby.login.connecting"));
-	if(!CSH->getGlobalLobby().isConnected())
-		CSH->getGlobalLobby().connect();
+	labelStatus->setText(LIBRARY->generaltexth->translate("vcmi.lobby.login.connecting"));
+	if(!GAME->server().getGlobalLobby().isConnected())
+		GAME->server().getGlobalLobby().connect();
 	else
 		onConnectionSuccess();
 
@@ -121,18 +122,18 @@ void GlobalLobbyLoginWindow::onLogin()
 
 void GlobalLobbyLoginWindow::onConnectionSuccess()
 {
-	std::string accountID = CSH->getGlobalLobby().getAccountID();
+	std::string accountID = GAME->server().getGlobalLobby().getAccountID();
 
 	if(toggleMode->getSelected() == 0)
-		CSH->getGlobalLobby().sendClientRegister(inputUsername->getText());
+		GAME->server().getGlobalLobby().sendClientRegister(inputUsername->getText());
 	else
-		CSH->getGlobalLobby().sendClientLogin();
+		GAME->server().getGlobalLobby().sendClientLogin();
 }
 
 void GlobalLobbyLoginWindow::onLoginSuccess()
 {
 	close();
-	CSH->getGlobalLobby().activateInterface();
+	GAME->server().getGlobalLobby().activateInterface();
 }
 
 void GlobalLobbyLoginWindow::onConnectionFailed(const std::string & reason)

+ 9 - 8
client/globalLobby/GlobalLobbyRoomWindow.cpp

@@ -15,9 +15,9 @@
 #include "GlobalLobbyDefines.h"
 #include "GlobalLobbyWindow.h"
 
-#include "../CGameInfo.h"
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../mainmenu/CMainMenu.h"
 #include "../widgets/Buttons.h"
@@ -30,6 +30,7 @@
 #include "../../lib/modding/ModDescription.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/texts/MetaString.h"
+#include "../../lib/GameLibrary.h"
 
 GlobalLobbyRoomAccountCard::GlobalLobbyRoomAccountCard(const GlobalLobbyAccount & accountDescription)
 {
@@ -63,7 +64,7 @@ GlobalLobbyRoomModCard::GlobalLobbyRoomModCard(const GlobalLobbyRoomModInfo & mo
 		statusColor = ColorRGBA(128, 128, 128);
 	else if(modInfo.status == ModVerificationStatus::VERSION_MISMATCH)
 		statusColor = Colors::YELLOW;
-	labelStatus = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, statusColor, CGI->generaltexth->translate("vcmi.lobby.mod.state." + statusToString.at(modInfo.status)));
+	labelStatus = std::make_shared<CLabel>(5, 30, FONT_SMALL, ETextAlignment::CENTERLEFT, statusColor, LIBRARY->generaltexth->translate("vcmi.lobby.mod.state." + statusToString.at(modInfo.status)));
 }
 
 static std::string getJoinRoomErrorMessage(const GlobalLobbyRoom & roomDescription, const std::vector<GlobalLobbyRoomModInfo> & modVerificationList)
@@ -71,8 +72,8 @@ static std::string getJoinRoomErrorMessage(const GlobalLobbyRoom & roomDescripti
 	bool publicRoom = roomDescription.statusID == "public";
 	bool privateRoom = roomDescription.statusID == "private";
 	bool gameStarted = !publicRoom && !privateRoom;
-	bool hasInvite = CSH->getGlobalLobby().isInvitedToRoom(roomDescription.gameRoomID);
-	bool alreadyInRoom = CSH->inGame();
+	bool hasInvite = GAME->server().getGlobalLobby().isInvitedToRoom(roomDescription.gameRoomID);
+	bool alreadyInRoom = GAME->server().inGame();
 
 	if (alreadyInRoom)
 		return "vcmi.lobby.preview.error.playing";
@@ -122,20 +123,20 @@ GlobalLobbyRoomWindow::GlobalLobbyRoomWindow(GlobalLobbyWindow * window, const s
 	pos.w = 400;
 	pos.h = 400;
 
-	GlobalLobbyRoom roomDescription = CSH->getGlobalLobby().getActiveRoomByName(roomUUID);
+	GlobalLobbyRoom roomDescription = GAME->server().getGlobalLobby().getActiveRoomByName(roomUUID);
 	for(const auto & modEntry : ModVerificationInfo::verifyListAgainstLocalMods(roomDescription.modList))
 	{
 		GlobalLobbyRoomModInfo modInfo;
 		modInfo.status = modEntry.second;
 		if (modEntry.second == ModVerificationStatus::EXCESSIVE)
-			modInfo.version = CGI->modh->getModInfo(modEntry.first).getVersion().toString();
+			modInfo.version = LIBRARY->modh->getModInfo(modEntry.first).getVersion().toString();
 		else
 			modInfo.version = roomDescription.modList.at(modEntry.first).version.toString();
 
 		if (modEntry.second == ModVerificationStatus::NOT_INSTALLED)
 			modInfo.modName = roomDescription.modList.at(modEntry.first).name;
 		else
-			modInfo.modName = CGI->modh->getModInfo(modEntry.first).getName();
+			modInfo.modName = LIBRARY->modh->getModInfo(modEntry.first).getName();
 
 		modVerificationList.push_back(modInfo);
 	}

+ 15 - 14
client/globalLobby/GlobalLobbyServerSetup.cpp

@@ -13,9 +13,9 @@
 
 #include "GlobalLobbyClient.h"
 
-#include "../CGameInfo.h"
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/Shortcut.h"
 #include "../mainmenu/CMainMenu.h"
 #include "../widgets/Buttons.h"
@@ -25,6 +25,7 @@
 #include "../../lib/CConfigHandler.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/texts/MetaString.h"
+#include "../../lib/GameLibrary.h"
 
 GlobalLobbyServerSetup::GlobalLobbyServerSetup()
 	: CWindowObject(BORDERED)
@@ -35,10 +36,10 @@ GlobalLobbyServerSetup::GlobalLobbyServerSetup()
 	pos.h = 340;
 
 	filledBackground = std::make_shared<FilledTexturePlayerColored>(Rect(0, 0, pos.w, pos.h));
-	labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.create"));
-	labelPlayerLimit = std::make_shared<CLabel>( pos.w / 2, 48, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.players.limit"));
-	labelRoomType = std::make_shared<CLabel>( pos.w / 2, 108, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.type"));
-	labelGameMode = std::make_shared<CLabel>( pos.w / 2, 158, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->translate("vcmi.lobby.room.mode"));
+	labelTitle = std::make_shared<CLabel>( pos.w / 2, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.room.create"));
+	labelPlayerLimit = std::make_shared<CLabel>( pos.w / 2, 48, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.room.players.limit"));
+	labelRoomType = std::make_shared<CLabel>( pos.w / 2, 108, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.room.type"));
+	labelGameMode = std::make_shared<CLabel>( pos.w / 2, 158, FONT_MEDIUM, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.room.mode"));
 
 	togglePlayerLimit = std::make_shared<CToggleGroup>(nullptr);
 	togglePlayerLimit->addToggle(2, std::make_shared<CToggleButton>(Point(10 + 39*0, 60), AnimationPath::builtin("RanNum2"), CButton::tooltip(), 0));
@@ -53,8 +54,8 @@ GlobalLobbyServerSetup::GlobalLobbyServerSetup()
 
 	auto buttonPublic  = std::make_shared<CToggleButton>(Point(10, 120),  AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
 	auto buttonPrivate = std::make_shared<CToggleButton>(Point(146, 120), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
-	buttonPublic->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.state.public"), EFonts::FONT_SMALL, Colors::YELLOW);
-	buttonPrivate->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.state.private"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonPublic->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.room.state.public"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonPrivate->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.room.state.private"), EFonts::FONT_SMALL, Colors::YELLOW);
 
 	toggleRoomType = std::make_shared<CToggleGroup>(nullptr);
 	toggleRoomType->addToggle(0, buttonPublic);
@@ -64,8 +65,8 @@ GlobalLobbyServerSetup::GlobalLobbyServerSetup()
 
 	auto buttonNewGame = std::make_shared<CToggleButton>(Point(10, 170),  AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
 	auto buttonLoadGame = std::make_shared<CToggleButton>(Point(146, 170), AnimationPath::builtin("GSPBUT2"), CButton::tooltip(), 0);
-	buttonNewGame->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.new"), EFonts::FONT_SMALL, Colors::YELLOW);
-	buttonLoadGame->setTextOverlay(CGI->generaltexth->translate("vcmi.lobby.room.load"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonNewGame->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.room.new"), EFonts::FONT_SMALL, Colors::YELLOW);
+	buttonLoadGame->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.room.load"), EFonts::FONT_SMALL, Colors::YELLOW);
 
 	toggleGameMode = std::make_shared<CToggleGroup>(nullptr);
 	toggleGameMode->addToggle(0, buttonNewGame);
@@ -128,12 +129,12 @@ void GlobalLobbyServerSetup::onGameModeChanged(int value)
 void GlobalLobbyServerSetup::onCreate()
 {
 	if(toggleGameMode->getSelected() == 0)
-		CSH->resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_HOST, { CSH->getGlobalLobby().getAccountDisplayName() });
+		GAME->server().resetStateForLobby(EStartMode::NEW_GAME, ESelectionScreen::newGame, EServerMode::LOBBY_HOST, { GAME->server().getGlobalLobby().getAccountDisplayName() });
 	else
-		CSH->resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOBBY_HOST, { CSH->getGlobalLobby().getAccountDisplayName() });
+		GAME->server().resetStateForLobby(EStartMode::LOAD_GAME, ESelectionScreen::loadGame, EServerMode::LOBBY_HOST, { GAME->server().getGlobalLobby().getAccountDisplayName() });
 
-	CSH->loadMode = ELoadMode::MULTI;
-	CSH->startLocalServerAndConnect(true);
+	GAME->server().loadMode = ELoadMode::MULTI;
+	GAME->server().startLocalServerAndConnect(true);
 
 	buttonCreate->block(true);
 	buttonClose->block(true);

+ 15 - 15
client/globalLobby/GlobalLobbyWidget.cpp

@@ -16,9 +16,9 @@
 #include "GlobalLobbyRoomWindow.h"
 #include "GlobalLobbyWindow.h"
 
-#include "../CGameInfo.h"
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../media/ISoundPlayer.h"
 #include "../render/Colors.h"
@@ -38,9 +38,9 @@
 GlobalLobbyWidget::GlobalLobbyWidget(GlobalLobbyWindow * window)
 	: window(window)
 {
-	addCallback("closeWindow", [](int) { GH.windows().popWindows(1); });
+	addCallback("closeWindow", [](int) { ENGINE->windows().popWindows(1); });
 	addCallback("sendMessage", [this](int) { this->window->doSendChatMessage(); });
-	addCallback("createGameRoom", [this](int) { if (!CSH->inGame()) this->window->doCreateGameRoom(); });//TODO: button should be blocked instead
+	addCallback("createGameRoom", [this](int) { if (!GAME->server().inGame()) this->window->doCreateGameRoom(); });//TODO: button should be blocked instead
 
 	REGISTER_BUILDER("lobbyItemList", &GlobalLobbyWidget::buildItemList);
 
@@ -52,7 +52,7 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
 {
 	const auto & createAccountCardCallback = [this](size_t index) -> std::shared_ptr<CIntObject>
 	{
-		const auto & accounts = CSH->getGlobalLobby().getActiveAccounts();
+		const auto & accounts = GAME->server().getGlobalLobby().getActiveAccounts();
 
 		if(index < accounts.size())
 			return std::make_shared<GlobalLobbyAccountCard>(this->window, accounts[index]);
@@ -61,7 +61,7 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
 
 	const auto & createRoomCardCallback = [this](size_t index) -> std::shared_ptr<CIntObject>
 	{
-		const auto & rooms = CSH->getGlobalLobby().getActiveRooms();
+		const auto & rooms = GAME->server().getGlobalLobby().getActiveRooms();
 
 		if(index < rooms.size())
 			return std::make_shared<GlobalLobbyRoomCard>(this->window, rooms[index]);
@@ -70,7 +70,7 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
 
 	const auto & createChannelCardCallback = [this](size_t index) -> std::shared_ptr<CIntObject>
 	{
-		const auto & channels = CSH->getGlobalLobby().getActiveChannels();
+		const auto & channels = GAME->server().getGlobalLobby().getActiveChannels();
 
 		if(index < channels.size())
 			return std::make_shared<GlobalLobbyChannelCard>(this->window, channels[index]);
@@ -78,7 +78,7 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
 		if(index == channels.size())
 		{
 			const auto buttonCallback = [](){
-				GH.windows().createAndPushWindow<GlobalLobbyAddChannelWindow>();
+				ENGINE->windows().createAndPushWindow<GlobalLobbyAddChannelWindow>();
 			};
 
 			auto result = std::make_shared<CButton>(Point(0,0), AnimationPath::builtin("lobbyAddChannel"), CButton::tooltip(), buttonCallback);
@@ -91,7 +91,7 @@ GlobalLobbyWidget::CreateFunc GlobalLobbyWidget::getItemListConstructorFunc(cons
 
 	const auto & createMatchCardCallback = [this](size_t index) -> std::shared_ptr<CIntObject>
 	{
-		const auto & matches = CSH->getGlobalLobby().getMatchesHistory();
+		const auto & matches = GAME->server().getGlobalLobby().getMatchesHistory();
 
 		if(index < matches.size())
 			return std::make_shared<GlobalLobbyMatchCard>(this->window, matches[index]);
@@ -222,7 +222,7 @@ GlobalLobbyChannelCardBase::GlobalLobbyChannelCardBase(GlobalLobbyWindow * windo
 
 void GlobalLobbyChannelCardBase::clickPressed(const Point & cursorPosition)
 {
-	CCS->soundh->playSound(soundBase::button);
+	ENGINE->sound().playSound(soundBase::button);
 	window->doOpenChannel(channelType, channelName, channelDescription);
 }
 
@@ -241,7 +241,7 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
 	OBJECT_CONSTRUCTION;
 	addUsedEvents(LCLICK);
 
-	bool hasInvite = CSH->getGlobalLobby().isInvitedToRoom(roomDescription.gameRoomID);
+	bool hasInvite = GAME->server().getGlobalLobby().isInvitedToRoom(roomDescription.gameRoomID);
 
 	auto roomSizeText = MetaString::createFromRawString("%d/%d");
 	roomSizeText.replaceNumber(roomDescription.participants.size());
@@ -270,7 +270,7 @@ GlobalLobbyRoomCard::GlobalLobbyRoomCard(GlobalLobbyWindow * window, const Globa
 
 void GlobalLobbyRoomCard::clickPressed(const Point & cursorPosition)
 {
-	GH.windows().createAndPushWindow<GlobalLobbyRoomWindow>(window, roomUUID);
+	ENGINE->windows().createAndPushWindow<GlobalLobbyRoomWindow>(window, roomUUID);
 }
 
 GlobalLobbyChannelCard::GlobalLobbyChannelCard(GlobalLobbyWindow * window, const std::string & channelName)
@@ -279,10 +279,10 @@ GlobalLobbyChannelCard::GlobalLobbyChannelCard(GlobalLobbyWindow * window, const
 	OBJECT_CONSTRUCTION;
 	labelName = std::make_shared<CLabel>(5, 20, FONT_SMALL, ETextAlignment::CENTERLEFT, Colors::WHITE, Languages::getLanguageOptions(channelName).nameNative);
 
-	if (CSH->getGlobalLobby().getActiveChannels().size() > 1)
+	if (GAME->server().getGlobalLobby().getActiveChannels().size() > 1)
 	{
 		pos.w = 110;
-		buttonClose = std::make_shared<CButton>(Point(113, 7), AnimationPath::builtin("lobbyCloseChannel"), CButton::tooltip(), [channelName](){CSH->getGlobalLobby().closeChannel(channelName);});
+		buttonClose = std::make_shared<CButton>(Point(113, 7), AnimationPath::builtin("lobbyCloseChannel"), CButton::tooltip(), [channelName](){GAME->server().getGlobalLobby().closeChannel(channelName);});
 		buttonClose->setOverlay(std::make_shared<CPicture>(ImagePath::builtin("lobby/closeChannel")));
 	}
 }
@@ -300,7 +300,7 @@ GlobalLobbyMatchCard::GlobalLobbyMatchCard(GlobalLobbyWindow * window, const Glo
 
 	if (matchDescription.participants.size() == 2)
 	{
-		std::string ourAccountID = CSH->getGlobalLobby().getAccountID();
+		std::string ourAccountID = GAME->server().getGlobalLobby().getAccountID();
 
 		opponentDescription.appendTextID("vcmi.lobby.match.duel");
 		// Find display name of our one and only opponent in this game

+ 10 - 9
client/globalLobby/GlobalLobbyWindow.cpp

@@ -16,7 +16,8 @@
 #include "GlobalLobbyWidget.h"
 
 #include "../CServerHandler.h"
-#include "../gui/CGuiHandler.h"
+#include "../GameEngine.h"
+#include "../GameInstance.h"
 #include "../gui/WindowHandler.h"
 #include "../widgets/CTextInput.h"
 #include "../widgets/Slider.h"
@@ -35,11 +36,11 @@ GlobalLobbyWindow::GlobalLobbyWindow()
 	pos = widget->pos;
 	center();
 
-	widget->getAccountNameLabel()->setText(CSH->getGlobalLobby().getAccountDisplayName());
+	widget->getAccountNameLabel()->setText(GAME->server().getGlobalLobby().getAccountDisplayName());
 	doOpenChannel("global", "english", Languages::getLanguageOptions("english").nameNative);
 
 	widget->getChannelListHeader()->setText(MetaString::createFromTextID("vcmi.lobby.header.channels").toString());
-	widget->getChannelList()->resize(CSH->getGlobalLobby().getActiveChannels().size()+1);
+	widget->getChannelList()->resize(GAME->server().getGlobalLobby().getActiveChannels().size()+1);
 }
 
 bool GlobalLobbyWindow::isChannelOpen(const std::string & testChannelType, const std::string & testChannelName) const
@@ -54,7 +55,7 @@ void GlobalLobbyWindow::doOpenChannel(const std::string & channelType, const std
 	chatHistory.clear();
 	unreadChannels.erase(channelType + "_" + channelName);
 
-	auto history = CSH->getGlobalLobby().getChannelHistory(channelType, channelName);
+	auto history = GAME->server().getGlobalLobby().getChannelHistory(channelType, channelName);
 
 	for(const auto & entry : history)
 		onGameChatMessage(entry.displayName, entry.messageText, entry.timeFormatted, channelType, channelName);
@@ -87,14 +88,14 @@ void GlobalLobbyWindow::doSendChatMessage()
 
 	assert(TextOperations::isValidUnicodeString(messageText));
 
-	CSH->getGlobalLobby().sendMessage(toSend);
+	GAME->server().getGlobalLobby().sendMessage(toSend);
 
 	widget->getMessageInput()->setText("");
 }
 
 void GlobalLobbyWindow::doCreateGameRoom()
 {
-	GH.windows().createAndPushWindow<GlobalLobbyServerSetup>();
+	ENGINE->windows().createAndPushWindow<GlobalLobbyServerSetup>();
 }
 
 void GlobalLobbyWindow::doInviteAccount(const std::string & accountID)
@@ -103,7 +104,7 @@ void GlobalLobbyWindow::doInviteAccount(const std::string & accountID)
 	toSend["type"].String() = "sendInvite";
 	toSend["accountID"].String() = accountID;
 
-	CSH->getGlobalLobby().sendMessage(toSend);
+	GAME->server().getGlobalLobby().sendMessage(toSend);
 }
 
 void GlobalLobbyWindow::doJoinRoom(const std::string & roomID)
@@ -112,7 +113,7 @@ void GlobalLobbyWindow::doJoinRoom(const std::string & roomID)
 	toSend["type"].String() = "joinGameRoom";
 	toSend["gameRoomID"].String() = roomID;
 
-	CSH->getGlobalLobby().sendMessage(toSend);
+	GAME->server().getGlobalLobby().sendMessage(toSend);
 }
 
 void GlobalLobbyWindow::onGameChatMessage(const std::string & sender, const std::string & message, const std::string & when, const std::string & channelType, const std::string & channelName)
@@ -185,7 +186,7 @@ void GlobalLobbyWindow::onMatchesHistory(const std::vector<GlobalLobbyRoom> & hi
 
 void GlobalLobbyWindow::refreshActiveChannels()
 {
-	const auto & activeChannels = CSH->getGlobalLobby().getActiveChannels();
+	const auto & activeChannels = GAME->server().getGlobalLobby().getActiveChannels();
 
 	if (activeChannels.size()+1 == widget->getChannelList()->size())
 		widget->getChannelList()->reset();

+ 11 - 11
client/gui/CIntObject.cpp

@@ -10,7 +10,7 @@
 #include "StdInc.h"
 #include "CIntObject.h"
 
-#include "CGuiHandler.h"
+#include "GameEngine.h"
 #include "WindowHandler.h"
 #include "EventDispatcher.h"
 #include "Shortcut.h"
@@ -27,8 +27,8 @@ CIntObject::CIntObject(int used_, Point pos_):
 	recActions(ALL_ACTIONS),
 	pos(pos_, Point())
 {
-	if(GH.captureChildren)
-		GH.createdObj.front()->addChild(this, true);
+	if(ENGINE->captureChildren)
+		ENGINE->createdObj.front()->addChild(this, true);
 }
 
 CIntObject::~CIntObject()
@@ -157,7 +157,7 @@ void CIntObject::setRedrawParent(bool on)
 
 void CIntObject::fitToScreen(int borderWidth, bool propagate)
 {
-	fitToRect(Rect(Point(0, 0), GH.screenDimensions()), borderWidth, propagate);
+	fitToRect(Rect(Point(0, 0), ENGINE->screenDimensions()), borderWidth, propagate);
 }
 
 void CIntObject::fitToRect(Rect rect, int borderWidth, bool propagate)
@@ -238,7 +238,7 @@ void CIntObject::redraw()
 		}
 		else
 		{
-			Canvas buffer = GH.screenHandler().getScreenCanvas();
+			Canvas buffer = ENGINE->screenHandler().getScreenCanvas();
 			showAll(buffer);
 		}
 	}
@@ -277,7 +277,7 @@ const Rect & CIntObject::center( const Rect &r, bool propagate )
 {
 	pos.w = r.w;
 	pos.h = r.h;
-	return center(Point(GH.screenDimensions().x/2, GH.screenDimensions().y/2), propagate);
+	return center(Point(ENGINE->screenDimensions().x/2, ENGINE->screenDimensions().y/2), propagate);
 }
 
 const Rect & CIntObject::center( bool propagate )
@@ -314,7 +314,7 @@ void CKeyShortcut::keyPressed(EShortcut key)
 	if( assignedKey == key && assignedKey != EShortcut::NONE && !shortcutPressed)
 	{
 		shortcutPressed = true;
-		clickPressed(GH.getCursorPosition());
+		clickPressed(ENGINE->getCursorPosition());
 	}
 }
 
@@ -323,7 +323,7 @@ void CKeyShortcut::keyReleased(EShortcut key)
 	if( assignedKey == key && assignedKey != EShortcut::NONE && shortcutPressed)
 	{
 		shortcutPressed = false;
-		clickReleased(GH.getCursorPosition());
+		clickReleased(ENGINE->getCursorPosition());
 	}
 }
 
@@ -335,10 +335,10 @@ WindowBase::WindowBase(int used_, Point pos_)
 
 void WindowBase::close()
 {
-	if(!GH.windows().isTopWindow(this))
+	if(!ENGINE->windows().isTopWindow(this))
 	{
-		auto topWindow = GH.windows().topWindow<IShowActivatable>().get();
+		auto topWindow = ENGINE->windows().topWindow<IShowActivatable>().get();
 		throw std::runtime_error(std::string("Only top interface can be closed! Top window is ") + typeid(*topWindow).name() + " but attempted to close " + typeid(*this).name());
 	}
-	GH.windows().popWindows(1);
+	ENGINE->windows().popWindows(1);
 }

+ 1 - 1
client/gui/CIntObject.h

@@ -15,7 +15,7 @@
 #include "../../lib/Color.h"
 #include "../../lib/GameConstants.h"
 
-class CGuiHandler;
+class GameEngine;
 class CPicture;
 class Canvas;
 

+ 17 - 15
client/gui/CursorHandler.cpp

@@ -11,7 +11,7 @@
 #include "StdInc.h"
 #include "CursorHandler.h"
 
-#include "CGuiHandler.h"
+#include "GameEngine.h"
 #include "FramerateManager.h"
 #include "../renderSDL/CursorSoftware.h"
 #include "../renderSDL/CursorHardware.h"
@@ -41,25 +41,27 @@ CursorHandler::CursorHandler()
 	, frameTime(0.f)
 	, showing(false)
 	, pos(0,0)
+	, dndObject(nullptr)
+	, type(Cursor::Type::DEFAULT)
 {
+	showType = dynamic_cast<CursorSoftware *>(cursor.get()) ? Cursor::ShowType::SOFTWARE : Cursor::ShowType::HARDWARE;
+}
 
-	type = Cursor::Type::DEFAULT;
-	dndObject = nullptr;
+CursorHandler::~CursorHandler() = default;
 
+void CursorHandler::init()
+{
 	cursors =
 	{
-		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRADVNTR"), EImageBlitMode::COLORKEY),
-		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT"), EImageBlitMode::COLORKEY),
-		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRDEFLT"), EImageBlitMode::COLORKEY),
-		GH.renderHandler().loadAnimation(AnimationPath::builtin("CRSPELL"), EImageBlitMode::COLORKEY)
+			ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRADVNTR"), EImageBlitMode::COLORKEY),
+			ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRCOMBAT"), EImageBlitMode::COLORKEY),
+			ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRDEFLT"), EImageBlitMode::COLORKEY),
+			ENGINE->renderHandler().loadAnimation(AnimationPath::builtin("CRSPELL"), EImageBlitMode::COLORKEY)
 	};
 
 	set(Cursor::Map::POINTER);
-	showType = dynamic_cast<CursorSoftware *>(cursor.get()) ? Cursor::ShowType::SOFTWARE : Cursor::ShowType::HARDWARE;
 }
 
-CursorHandler::~CursorHandler() = default;
-
 void CursorHandler::changeGraphic(Cursor::Type type, size_t index)
 {
 	assert(dndObject == nullptr);
@@ -102,7 +104,7 @@ void CursorHandler::dragAndDropCursor(std::shared_ptr<IImage> image)
 
 void CursorHandler::dragAndDropCursor (const AnimationPath & path, size_t index)
 {
-	auto anim = GH.renderHandler().loadAnimation(path, EImageBlitMode::COLORKEY);
+	auto anim = ENGINE->renderHandler().loadAnimation(path, EImageBlitMode::COLORKEY);
 	dragAndDropCursor(anim->getImage(index));
 }
 
@@ -176,7 +178,7 @@ Point CursorHandler::getPivotOffsetMap(size_t index)
 
 	assert(offsets.size() == size_t(Cursor::Map::COUNT)); //Invalid number of pivot offsets for cursor
 	assert(index < offsets.size());
-	return offsets[index] * GH.screenHandler().getScalingFactor();
+	return offsets[index] * ENGINE->screenHandler().getScalingFactor();
 }
 
 Point CursorHandler::getPivotOffsetCombat(size_t index)
@@ -206,12 +208,12 @@ Point CursorHandler::getPivotOffsetCombat(size_t index)
 
 	assert(offsets.size() == size_t(Cursor::Combat::COUNT)); //Invalid number of pivot offsets for cursor
 	assert(index < offsets.size());
-	return offsets[index] * GH.screenHandler().getScalingFactor();
+	return offsets[index] * ENGINE->screenHandler().getScalingFactor();
 }
 
 Point CursorHandler::getPivotOffsetSpellcast()
 {
-	return Point(18, 28) * GH.screenHandler().getScalingFactor();
+	return Point(18, 28) * ENGINE->screenHandler().getScalingFactor();
 }
 
 Point CursorHandler::getPivotOffset()
@@ -242,7 +244,7 @@ void CursorHandler::updateSpellcastCursor()
 {
 	static const float frameDisplayDuration = 0.1f; // H3 uses 100 ms per frame
 
-	frameTime += GH.framerate().getElapsedMilliseconds() / 1000.f;
+	frameTime += ENGINE->framerate().getElapsedMilliseconds() / 1000.f;
 	size_t newFrame = frame;
 
 	while (frameTime >= frameDisplayDuration)

+ 2 - 0
client/gui/CursorHandler.h

@@ -145,6 +145,8 @@ public:
 	CursorHandler();
 	~CursorHandler();
 
+	void init();
+
 	/// Replaces the cursor with a custom image.
 	/// @param image Image to replace cursor with or nullptr to use the normal cursor.
 	void dragAndDropCursor(std::shared_ptr<IImage> image);

+ 7 - 7
client/gui/EventDispatcher.cpp

@@ -12,7 +12,7 @@
 
 #include "EventsReceiver.h"
 #include "FramerateManager.h"
-#include "CGuiHandler.h"
+#include "GameEngine.h"
 #include "MouseButton.h"
 #include "WindowHandler.h"
 #include "gui/Shortcut.h"
@@ -80,10 +80,10 @@ void EventDispatcher::dispatchShortcutPressed(const std::vector<EShortcut> & sho
 	bool keysCaptured = false;
 
 	if (vstd::contains(shortcutsVector, EShortcut::MOUSE_LEFT))
-		dispatchMouseLeftButtonPressed(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
+		dispatchMouseLeftButtonPressed(ENGINE->getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
 
 	if (vstd::contains(shortcutsVector, EShortcut::MOUSE_RIGHT))
-		dispatchShowPopup(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
+		dispatchShowPopup(ENGINE->getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
 
 	for(auto & i : keyinterested)
 		for(EShortcut shortcut : shortcutsVector)
@@ -109,10 +109,10 @@ void EventDispatcher::dispatchShortcutReleased(const std::vector<EShortcut> & sh
 	bool keysCaptured = false;
 
 	if (vstd::contains(shortcutsVector, EShortcut::MOUSE_LEFT))
-		dispatchMouseLeftButtonReleased(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
+		dispatchMouseLeftButtonReleased(ENGINE->getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
 
 	if (vstd::contains(shortcutsVector, EShortcut::MOUSE_RIGHT))
-		dispatchClosePopup(GH.getCursorPosition());
+		dispatchClosePopup(ENGINE->getCursorPosition());
 
 	for(auto & i : keyinterested)
 		for(EShortcut shortcut : shortcutsVector)
@@ -201,7 +201,7 @@ void EventDispatcher::dispatchShowPopup(const Point & position, int tolerance)
 
 void EventDispatcher::dispatchClosePopup(const Point & position)
 {
-	bool popupOpen = GH.windows().isTopWindowPopup(); // popup can already be closed for mouse dragging with RMB
+	bool popupOpen = ENGINE->windows().isTopWindowPopup(); // popup can already be closed for mouse dragging with RMB
 
 	auto hlp = rclickable;
 
@@ -214,7 +214,7 @@ void EventDispatcher::dispatchClosePopup(const Point & position)
 	}
 
 	if(popupOpen)
-		GH.windows().popWindows(1);
+		ENGINE->windows().popWindows(1);
 }
 
 void EventDispatcher::handleLeftButtonClick(const Point & position, int tolerance, bool isPressed)

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików