2
0
Эх сурвалжийг харах

Fixed toggleable buttons (sleep/wake & subterra/surface)

Ivan Savenko 2 жил өмнө
parent
commit
5ae507505a

+ 1 - 0
client/CMakeLists.txt

@@ -134,6 +134,7 @@ set(client_HEADERS
 	adventureMap/CAdventureMapInterface.h
 	adventureMap/CAdventureMapWidget.h
 	adventureMap/AdventureMapShortcuts.h
+	adventureMap/AdventureState.h
 	adventureMap/CAdventureOptions.h
 	adventureMap/CInGameConsole.h
 	adventureMap/CInfoBar.h

+ 84 - 31
client/adventureMap/AdventureMapShortcuts.cpp

@@ -24,6 +24,7 @@
 #include "../windows/settings/SettingsMainWindow.h"
 #include "CAdventureMapInterface.h"
 #include "CAdventureOptions.h"
+#include "AdventureState.h"
 
 #include "../../CCallback.h"
 #include "../../lib/CConfigHandler.h"
@@ -34,41 +35,57 @@
 #include "../../lib/mapping/CMap.h"
 
 AdventureMapShortcuts::AdventureMapShortcuts(CAdventureMapInterface & owner)
-	:owner(owner)
+	: owner(owner)
+	, state(EAdventureState::NOT_INITIALIZED)
+	, mapLevel(0)
 {}
 
+void AdventureMapShortcuts::setState(EAdventureState newState)
+{
+	state = newState;
+}
+
+void AdventureMapShortcuts::onMapViewMoved(const Rect & visibleArea, int newMapLevel)
+{
+	if(mapLevel == newMapLevel)
+		return;
+
+	mapLevel = newMapLevel;
+}
+
 std::vector<AdventureMapShortcutState> AdventureMapShortcuts::getShortcuts()
 {
 	std::vector<AdventureMapShortcutState> result = {
-		{ EShortcut::ADVENTURE_KINGDOM_OVERVIEW, optionDefault(),        [this]() { this->showOverview(); } },
-		{ EShortcut::ADVENTURE_EXIT_WORLD_VIEW,  optionDefault(),        [this]() { this->worldViewBack(); } },
-		{ EShortcut::ADVENTURE_VIEW_WORLD_X1,    optionDefault(),        [this]() { this->worldViewScale1x(); } },
-		{ EShortcut::ADVENTURE_VIEW_WORLD_X2,    optionDefault(),        [this]() { this->worldViewScale2x(); } },
-		{ EShortcut::ADVENTURE_VIEW_WORLD_X4,    optionDefault(),        [this]() { this->worldViewScale4x(); } },
+		{ EShortcut::ADVENTURE_KINGDOM_OVERVIEW, optionInMapView(),      [this]() { this->showOverview(); } },
+		{ EShortcut::ADVENTURE_EXIT_WORLD_VIEW,  optionInWorldView(),    [this]() { this->worldViewBack(); } },
+		{ EShortcut::ADVENTURE_VIEW_WORLD,       optionInMapView(),      [this]() { this->worldViewScale1x(); } },
+		{ EShortcut::ADVENTURE_VIEW_WORLD_X1,    optionInWorldView(),    [this]() { this->worldViewScale1x(); } },
+		{ EShortcut::ADVENTURE_VIEW_WORLD_X2,    optionInWorldView(),    [this]() { this->worldViewScale2x(); } },
+		{ EShortcut::ADVENTURE_VIEW_WORLD_X4,    optionInWorldView(),    [this]() { this->worldViewScale4x(); } },
 		{ EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL, optionHasUnderground(), [this]() { this->switchMapLevel(); } },
 		{ EShortcut::ADVENTURE_QUEST_LOG,        optionHasQuests(),      [this]() { this->showQuestlog(); } },
 		{ EShortcut::ADVENTURE_TOGGLE_SLEEP,     optionHeroSelected(),   [this]() { this->toggleSleepWake(); } },
-		{ EShortcut::ADVENTURE_SET_HERO_ASLEEP,  optionHeroSleeping(),   [this]() { this->setHeroSleeping(); } },
+		{ EShortcut::ADVENTURE_SET_HERO_ASLEEP,  optionHeroAwake(),      [this]() { this->setHeroSleeping(); } },
 		{ EShortcut::ADVENTURE_SET_HERO_AWAKE,   optionHeroSleeping(),   [this]() { this->setHeroAwake(); } },
 		{ EShortcut::ADVENTURE_MOVE_HERO,        optionHeroCanMove(),    [this]() { this->moveHeroAlongPath(); } },
 		{ EShortcut::ADVENTURE_CAST_SPELL,       optionHeroSelected(),   [this]() { this->showSpellbook(); } },
-		{ EShortcut::ADVENTURE_GAME_OPTIONS,     optionDefault(),        [this]() { this->adventureOptions(); } },
-		{ EShortcut::GLOBAL_OPTIONS,             optionDefault(),        [this]() { this->systemOptions(); } },
+		{ EShortcut::ADVENTURE_GAME_OPTIONS,     optionInMapView(),      [this]() { this->adventureOptions(); } },
+		{ EShortcut::GLOBAL_OPTIONS,             optionInMapView(),      [this]() { this->systemOptions(); } },
 		{ EShortcut::ADVENTURE_NEXT_HERO,        optionHasNextHero(),    [this]() { this->nextHero(); } },
-		{ EShortcut::GAME_END_TURN,              optionDefault(),        [this]() { this->endTurn(); } },
-		{ EShortcut::ADVENTURE_THIEVES_GUILD,    optionDefault(),        [this]() { this->showThievesGuild(); } },
-		{ EShortcut::ADVENTURE_VIEW_SCENARIO,    optionDefault(),        [this]() { this->showScenarioInfo(); } },
-		{ EShortcut::GAME_SAVE_GAME,             optionDefault(),        [this]() { this->saveGame(); } },
-		{ EShortcut::GAME_LOAD_GAME,             optionDefault(),        [this]() { this->loadGame(); } },
+		{ EShortcut::GAME_END_TURN,              optionInMapView(),      [this]() { this->endTurn(); } },
+		{ EShortcut::ADVENTURE_THIEVES_GUILD,    optionInMapView(),      [this]() { this->showThievesGuild(); } },
+		{ EShortcut::ADVENTURE_VIEW_SCENARIO,    optionInMapView(),      [this]() { this->showScenarioInfo(); } },
+		{ EShortcut::GAME_SAVE_GAME,             optionInMapView(),      [this]() { this->saveGame(); } },
+		{ EShortcut::GAME_LOAD_GAME,             optionInMapView(),      [this]() { this->loadGame(); } },
 		{ EShortcut::ADVENTURE_DIG_GRAIL,        optionHeroSelected(),   [this]() { this->digGrail(); } },
-		{ EShortcut::ADVENTURE_VIEW_PUZZLE,      optionDefault(),        [this]() { this->viewPuzzleMap(); } },
-		{ EShortcut::GAME_RESTART_GAME,          optionDefault(),        [this]() { this->restartGame(); } },
+		{ EShortcut::ADVENTURE_VIEW_PUZZLE,      optionInMapView(),      [this]() { this->viewPuzzleMap(); } },
+		{ EShortcut::GAME_RESTART_GAME,          optionInMapView(),      [this]() { this->restartGame(); } },
 		{ EShortcut::ADVENTURE_VISIT_OBJECT,     optionHeroSelected(),   [this]() { this->visitObject(); } },
-		{ EShortcut::ADVENTURE_VIEW_SELECTED,    optionDefault(),        [this]() { this->openObject(); } },
+		{ EShortcut::ADVENTURE_VIEW_SELECTED,    optionInMapView(),      [this]() { this->openObject(); } },
 		{ EShortcut::GLOBAL_CANCEL,              optionSpellcasting(),   [this]() { this->abortSpellcasting(); } },
-		{ EShortcut::GAME_OPEN_MARKETPLACE,      optionDefault(),        [this]() { this->showMarketplace(); } },
-		{ EShortcut::ADVENTURE_NEXT_TOWN,        optionDefault(),        [this]() { this->nextTown(); } },
-		{ EShortcut::ADVENTURE_NEXT_OBJECT,      optionDefault(),        [this]() { this->nextObject(); } },
+		{ EShortcut::GAME_OPEN_MARKETPLACE,      optionInMapView(),      [this]() { this->showMarketplace(); } },
+		{ EShortcut::ADVENTURE_NEXT_TOWN,        optionInMapView(),      [this]() { this->nextTown(); } },
+		{ EShortcut::ADVENTURE_NEXT_OBJECT,      optionInMapView(),      [this]() { this->nextObject(); } },
 		{ EShortcut::ADVENTURE_MOVE_HERO_SW,     optionHeroSelected(),   [this]() { this->moveHeroDirectional({-1, +1}); } },
 		{ EShortcut::ADVENTURE_MOVE_HERO_SS,     optionHeroSelected(),   [this]() { this->moveHeroDirectional({ 0, +1}); } },
 		{ EShortcut::ADVENTURE_MOVE_HERO_SE,     optionHeroSelected(),   [this]() { this->moveHeroDirectional({+1, +1}); } },
@@ -160,7 +177,7 @@ void AdventureMapShortcuts::setHeroAwake()
 	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
 	if (h)
 	{
-		LOCPLINT->localState->setHeroAsleep(h);
+		LOCPLINT->localState->setHeroAwaken(h);
 		owner.onHeroChanged(h);
 	}
 }
@@ -275,7 +292,6 @@ void AdventureMapShortcuts::digGrail()
 
 	if(h && LOCPLINT->makingTurn)
 		LOCPLINT->tryDiggging(h);
-	return;
 }
 
 void AdventureMapShortcuts::viewPuzzleMap()
@@ -306,8 +322,6 @@ void AdventureMapShortcuts::openObject()
 
 	if(t)
 		LOCPLINT->openTownWindow(t);
-
-	return;
 }
 
 void AdventureMapShortcuts::abortSpellcasting()
@@ -336,17 +350,45 @@ void AdventureMapShortcuts::showMarketplace()
 
 void AdventureMapShortcuts::nextTown()
 {
-	//TODO
+	owner.hotkeyNextTown();
 }
 
 void AdventureMapShortcuts::nextObject()
 {
-	//TODO
+	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero();
+	const CGTownInstance *t = LOCPLINT->localState->getCurrentTown();
+	if(h)
+		nextHero();
+
+	if(t)
+		nextTown();
 }
 
 void AdventureMapShortcuts::moveHeroDirectional(const Point & direction)
 {
-	owner.hotkeyMoveHeroDirectional(direction);
+	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); //selected hero
+
+	if(!h)
+		return;
+
+	if (CGI->mh->hasOngoingAnimations())
+		return;
+
+	int3 dst = h->visitablePos() + int3(direction.x, direction.y, 0);
+
+	if (!CGI->mh->isInMap((dst)))
+		return;
+
+	if ( !LOCPLINT->localState->setPath(h, dst))
+		return;
+
+	const CGPath & path = LOCPLINT->localState->getPath(h);
+
+	if (path.nodes.size() > 2)
+		owner.onHeroChanged(h);
+	else
+		if(path.nodes[0].turns == 0)
+			LOCPLINT->moveHero(h, path);
 }
 
 bool AdventureMapShortcuts::optionHasQuests()
@@ -361,7 +403,7 @@ bool AdventureMapShortcuts::optionHasUnderground()
 
 bool AdventureMapShortcuts::optionMapLevelSurface()
 {
-	return false; //TODO
+	return mapLevel == 0;
 }
 
 bool AdventureMapShortcuts::optionHeroSleeping()
@@ -370,6 +412,12 @@ bool AdventureMapShortcuts::optionHeroSleeping()
 	return hero && LOCPLINT->localState->isHeroSleeping(hero);
 }
 
+bool AdventureMapShortcuts::optionHeroAwake()
+{
+	const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero();
+	return hero && !LOCPLINT->localState->isHeroSleeping(hero);
+}
+
 bool AdventureMapShortcuts::optionHeroSelected()
 {
 	return LOCPLINT->localState->getCurrentHero() != nullptr;
@@ -391,10 +439,15 @@ bool AdventureMapShortcuts::optionHasNextHero()
 
 bool AdventureMapShortcuts::optionSpellcasting()
 {
-	return true; //TODO
+	return state == EAdventureState::CASTING_SPELL;
+}
+
+bool AdventureMapShortcuts::optionInMapView()
+{
+	return state == EAdventureState::MAKING_TURN;
 }
 
-bool AdventureMapShortcuts::optionDefault()
+bool AdventureMapShortcuts::optionInWorldView()
 {
-	return true; //TODO
+	return state == EAdventureState::WORLD_VIEW;
 }

+ 10 - 1
client/adventureMap/AdventureMapShortcuts.h

@@ -12,10 +12,12 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 class Point;
+class Rect;
 VCMI_LIB_NAMESPACE_END
 
 enum class EShortcut;
 class CAdventureMapInterface;
+enum class EAdventureState;
 
 struct AdventureMapShortcutState
 {
@@ -28,6 +30,8 @@ struct AdventureMapShortcutState
 class AdventureMapShortcuts
 {
 	CAdventureMapInterface & owner;
+	EAdventureState state;
+	int mapLevel;
 
 	void showOverview();
 	void worldViewBack();
@@ -69,9 +73,14 @@ public:
 	bool optionHasUnderground();
 	bool optionMapLevelSurface();
 	bool optionHeroSleeping();
+	bool optionHeroAwake();
 	bool optionHeroSelected();
 	bool optionHeroCanMove();
 	bool optionHasNextHero();
 	bool optionSpellcasting();
-	bool optionDefault();
+	bool optionInMapView();
+	bool optionInWorldView();
+
+	void setState(EAdventureState newState);
+	void onMapViewMoved(const Rect & visibleArea, int mapLevel);
 };

+ 20 - 0
client/adventureMap/AdventureState.h

@@ -0,0 +1,20 @@
+/*
+ * AdventureState.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
+
+enum class EAdventureState
+{
+	NOT_INITIALIZED,
+	HOTSEAT_WAIT,
+	MAKING_TURN,
+	ENEMY_TURN,
+	CASTING_SPELL,
+	WORLD_VIEW
+};

+ 31 - 48
client/adventureMap/CAdventureMapInterface.cpp

@@ -11,6 +11,7 @@
 #include "CAdventureMapInterface.h"
 
 #include "CAdventureOptions.h"
+#include "AdventureState.h"
 #include "CInGameConsole.h"
 #include "CMinimap.h"
 #include "CList.h"
@@ -53,14 +54,16 @@ CAdventureMapInterface::CAdventureMapInterface():
 	shortcuts = std::make_shared<AdventureMapShortcuts>(*this);
 
 	widget = std::make_shared<CAdventureMapWidget>(shortcuts);
-	widget->setState(EGameState::MAKING_TURN);
+	widget->setState(EAdventureState::MAKING_TURN);
+	shortcuts->setState(EAdventureState::MAKING_TURN);
 	widget->getMapView()->onViewMapActivated();
 }
 
 void CAdventureMapInterface::onMapViewMoved(const Rect & visibleArea, int mapLevel)
 {
+	shortcuts->onMapViewMoved(visibleArea, mapLevel);
 	widget->getMinimap()->onMapViewMoved(visibleArea, mapLevel);
-	widget->updateActiveState();
+	widget->onMapViewMoved(visibleArea, mapLevel);
 }
 
 void CAdventureMapInterface::onAudioResumed()
@@ -146,7 +149,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate()
 	uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
 	uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
 
-	bool scrollingActive = !GH.isKeyboardCtrlDown() && isActive() && widget->getState() == EGameState::MAKING_TURN;
+	bool scrollingActive = !GH.isKeyboardCtrlDown() && isActive() && widget->getState() == EAdventureState::MAKING_TURN;
 
 	Point cursorPosition = GH.getCursorPosition();
 	Point scrollDirection;
@@ -219,39 +222,6 @@ void CAdventureMapInterface::keyPressed(EShortcut key)
 	GH.fakeMouseMove();
 }
 
-void CAdventureMapInterface::hotkeyMoveHeroDirectional(Point direction)
-{
-	const CGHeroInstance *h = LOCPLINT->localState->getCurrentHero(); //selected hero
-
-	if(!h || !isActive())
-		return;
-
-	if (CGI->mh->hasOngoingAnimations())
-		return;
-
-	if(direction == Point(0,0))
-	{
-		centerOnObject(h);
-		return;
-	}
-
-	int3 dst = h->visitablePos() + int3(direction.x, direction.y, 0);
-
-	if (!CGI->mh->isInMap((dst)))
-		return;
-
-	if ( !LOCPLINT->localState->setPath(h, dst))
-		return;
-
-	const CGPath & path = LOCPLINT->localState->getPath(h);
-
-	if (path.nodes.size() > 2)
-		onHeroChanged(h);
-	else
-		if(!path.nodes[0].turns)
-			LOCPLINT->moveHero(h, path);
-}
-
 void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
 {
 	assert(sel);
@@ -305,7 +275,8 @@ void CAdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_se
 void CAdventureMapInterface::onHotseatWaitStarted(PlayerColor playerID)
 {
 	onCurrentPlayerChanged(playerID);
-	widget->setState(EGameState::HOTSEAT_WAIT);
+	widget->setState(EAdventureState::HOTSEAT_WAIT);
+	shortcuts->setState(EAdventureState::HOTSEAT_WAIT);
 }
 
 void CAdventureMapInterface::onEnemyTurnStarted(PlayerColor playerID)
@@ -329,9 +300,15 @@ void CAdventureMapInterface::adjustActiveness(bool aiTurnStart)
 		deactivate();
 
 	if (aiTurnStart)
-		widget->setState(EGameState::ENEMY_TURN);
+	{
+		widget->setState(EAdventureState::ENEMY_TURN);
+		shortcuts->setState(EAdventureState::ENEMY_TURN);
+	}
 	else
-		widget->setState(EGameState::MAKING_TURN);
+	{
+		widget->setState(EAdventureState::MAKING_TURN);
+		shortcuts->setState(EAdventureState::MAKING_TURN);
+	}
 
 	if(wasActive)
 		activate();
@@ -352,7 +329,8 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
 {
 	onCurrentPlayerChanged(playerID);
 
-	widget->setState(EGameState::MAKING_TURN);
+	widget->setState(EAdventureState::MAKING_TURN);
+	shortcuts->setState(EAdventureState::MAKING_TURN);
 	if(LOCPLINT->cb->getCurrentPlayer() == LOCPLINT->playerID
 		|| settings["session"]["spectate"].Bool())
 	{
@@ -428,7 +406,7 @@ const CGObjectInstance* CAdventureMapInterface::getActiveObject(const int3 &mapP
 
 void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 {
-	if(widget->getState() != EGameState::MAKING_TURN)
+	if(widget->getState() != EAdventureState::MAKING_TURN)
 		return;
 
 	//FIXME: this line breaks H3 behavior for Dimension Door
@@ -519,7 +497,7 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 
 void CAdventureMapInterface::onTileHovered(const int3 &mapPos)
 {
-	if(widget->getState() != EGameState::MAKING_TURN)
+	if(widget->getState() != EAdventureState::MAKING_TURN)
 		return;
 
 	//may occur just at the start of game (fake move before full intiialization)
@@ -686,7 +664,7 @@ void CAdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & h
 
 void CAdventureMapInterface::onTileRightClicked(const int3 &mapPos)
 {
-	if(widget->getState() != EGameState::MAKING_TURN)
+	if(widget->getState() != EAdventureState::MAKING_TURN)
 		return;
 
 	if(spellBeingCasted)
@@ -724,14 +702,16 @@ void CAdventureMapInterface::enterCastingMode(const CSpell * sp)
 	Settings config = settings.write["session"]["showSpellRange"];
 	config->Bool() = true;
 
-	widget->setState(EGameState::CASTING_SPELL);
+	widget->setState(EAdventureState::CASTING_SPELL);
+	shortcuts->setState(EAdventureState::CASTING_SPELL);
 }
 
 void CAdventureMapInterface::exitCastingMode()
 {
 	assert(spellBeingCasted);
 	spellBeingCasted = nullptr;
-	widget->setState(EGameState::MAKING_TURN);
+	widget->setState(EAdventureState::MAKING_TURN);
+	shortcuts->setState(EAdventureState::MAKING_TURN);
 
 	Settings config = settings.write["session"]["showSpellRange"];
 	config->Bool() = false;
@@ -769,13 +749,15 @@ const IShipyard * CAdventureMapInterface::ourInaccessibleShipyard(const CGObject
 
 void CAdventureMapInterface::hotkeyExitWorldView()
 {
-	widget->setState(EGameState::MAKING_TURN);
+	widget->setState(EAdventureState::MAKING_TURN);
+	shortcuts->setState(EAdventureState::MAKING_TURN);
 	widget->getMapView()->onViewMapActivated();
 }
 
 void CAdventureMapInterface::openWorldView(int tileSize)
 {
-	widget->setState(EGameState::WORLD_VIEW);
+	widget->setState(EAdventureState::WORLD_VIEW);
+	shortcuts->setState(EAdventureState::WORLD_VIEW);
 	widget->getMapView()->onViewWorldActivated(tileSize);
 }
 
@@ -803,13 +785,14 @@ void CAdventureMapInterface::hotkeySwitchMapLevel()
 void CAdventureMapInterface::onScreenResize()
 {
 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
+	EAdventureState oldState = widget->getState();
 	widget.reset();
 	pos.x = pos.y = 0;
 	pos.w = GH.screenDimensions().x;
 	pos.h = GH.screenDimensions().y;
 
 	widget = std::make_shared<CAdventureMapWidget>(shortcuts);
-	widget->setState(EGameState::MAKING_TURN);
+	widget->setState(oldState);
 	widget->getMapView()->onViewMapActivated();
 	widget->setPlayer(currentPlayerID);
 

+ 0 - 1
client/adventureMap/CAdventureMapInterface.h

@@ -92,7 +92,6 @@ protected:
 public:
 	CAdventureMapInterface();
 
-	void hotkeyMoveHeroDirectional(Point direction);
 	void hotkeyAbortCastingMode();
 	void hotkeyExitWorldView();
 	void hotkeyEndingTurn();

+ 16 - 5
client/adventureMap/CAdventureMapWidget.cpp

@@ -15,6 +15,7 @@
 #include "CList.h"
 #include "CMinimap.h"
 #include "CResDataBar.h"
+#include "AdventureState.h"
 
 #include "../gui/CGuiHandler.h"
 #include "../gui/Shortcut.h"
@@ -32,8 +33,9 @@
 #include "../../lib/filesystem/ResourceID.h"
 
 CAdventureMapWidget::CAdventureMapWidget( std::shared_ptr<AdventureMapShortcuts> shortcuts )
-	: state(EGameState::NOT_INITIALIZED)
+	: state(EAdventureState::NOT_INITIALIZED)
 	, shortcuts(shortcuts)
+	, mapLevel(0)
 {
 	pos.x = pos.y = 0;
 	pos.w = GH.screenDimensions().x;
@@ -63,10 +65,18 @@ CAdventureMapWidget::CAdventureMapWidget( std::shared_ptr<AdventureMapShortcuts>
 	}
 
 	build(config);
-
 	addUsedEvents(KEYBOARD);
 }
 
+void CAdventureMapWidget::onMapViewMoved(const Rect & visibleArea, int newMapLevel)
+{
+	if(mapLevel == newMapLevel)
+		return;
+
+	mapLevel = newMapLevel;
+	updateActiveState();
+}
+
 Rect CAdventureMapWidget::readSourceArea(const JsonNode & source, const JsonNode & sourceCommon)
 {
 	const auto & input = source.isNull() ? sourceCommon : source;
@@ -368,17 +378,17 @@ void CAdventureMapWidget::setPlayerChildren(CIntObject * widget, const PlayerCol
 	redraw();
 }
 
-void CAdventureMapWidget::setState(EGameState newState)
+void CAdventureMapWidget::setState(EAdventureState newState)
 {
 	state = newState;
 
-	if(newState == EGameState::WORLD_VIEW)
+	if(newState == EAdventureState::WORLD_VIEW)
 		widget<CIntObject>("worldViewContainer")->enable();
 	else
 		widget<CIntObject>("worldViewContainer")->disable();
 }
 
-EGameState CAdventureMapWidget::getState()
+EAdventureState CAdventureMapWidget::getState()
 {
 	return state;
 }
@@ -422,6 +432,7 @@ void CAdventureMapWidget::updateActiveStateChildden(CIntObject * widget)
 			if (container->disableCondition == "mapLayerUnderground")
 				container->setEnabled(!shortcuts->optionMapLevelSurface());
 
+			updateActiveStateChildden(container);
 		}
 
 	}

+ 6 - 14
client/adventureMap/CAdventureMapWidget.h

@@ -18,21 +18,13 @@ class MapView;
 class CInfoBar;
 class IImage;
 class AdventureMapShortcuts;
-
-enum class EGameState
-{
-	NOT_INITIALIZED,
-	HOTSEAT_WAIT,
-	MAKING_TURN,
-	ENEMY_TURN,
-	CASTING_SPELL,
-	WORLD_VIEW
-};
+enum class EAdventureState;
 
 /// Internal class of AdventureMapInterface that contains actual UI elements
 class CAdventureMapWidget : public InterfaceObjectConfigurable
 {
-	EGameState state;
+	EAdventureState state;
+	int mapLevel;
 	/// temporary stack of sizes of currently building widgets
 	std::vector<Rect> subwidgetSizes;
 
@@ -83,11 +75,11 @@ public:
 	std::shared_ptr<CInfoBar> getInfoBar();
 
 	void setPlayer(const PlayerColor & player);
-	void setState(EGameState newState);
-	EGameState getState();
+	void setState(EAdventureState newState);
+	EAdventureState getState();
 
+	void onMapViewMoved(const Rect & visibleArea, int mapLevel);
 	void updateActiveState();
-
 };
 
 /// Small helper class that provides ownership for shared_ptr's of child elements

+ 3 - 0
client/gui/CIntObject.cpp

@@ -199,7 +199,10 @@ void CIntObject::disable()
 void CIntObject::enable()
 {
 	if(!active_m && (!parent_m || parent_m->active))
+	{
 		activate();
+		redraw();
+	}
 
 	recActions = 255;
 }

+ 1 - 0
client/gui/Shortcut.h

@@ -95,6 +95,7 @@ enum class EShortcut
 	ADVENTURE_VIEW_SCENARIO,// View Scenario Information window
 	ADVENTURE_DIG_GRAIL,
 	ADVENTURE_VIEW_PUZZLE,
+	ADVENTURE_VIEW_WORLD,
 	ADVENTURE_VIEW_WORLD_X1,
 	ADVENTURE_VIEW_WORLD_X2,
 	ADVENTURE_VIEW_WORLD_X4,

+ 5 - 1
client/gui/ShortcutHandler.cpp

@@ -105,7 +105,10 @@ std::vector<EShortcut> ShortcutHandler::translateKeycode(SDL_Keycode key) const
 		{SDLK_i,         EShortcut::ADVENTURE_VIEW_SCENARIO   },
 		{SDLK_d,         EShortcut::ADVENTURE_DIG_GRAIL       },
 		{SDLK_p,         EShortcut::ADVENTURE_VIEW_PUZZLE     },
-		{SDLK_v,         EShortcut::ADVENTURE_VIEW_WORLD_X1   },
+		{SDLK_v,         EShortcut::ADVENTURE_VIEW_WORLD      },
+		{SDLK_1,         EShortcut::ADVENTURE_VIEW_WORLD_X1   },
+		{SDLK_2,         EShortcut::ADVENTURE_VIEW_WORLD_X2   },
+		{SDLK_4,         EShortcut::ADVENTURE_VIEW_WORLD_X4   },
 		{SDLK_u,         EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL},
 		{SDLK_k,         EShortcut::ADVENTURE_KINGDOM_OVERVIEW},
 		{SDLK_q,         EShortcut::ADVENTURE_QUEST_LOG       },
@@ -238,6 +241,7 @@ EShortcut ShortcutHandler::findShortcut(const std::string & identifier ) const
 		{"adventureViewScenario",    EShortcut::ADVENTURE_VIEW_SCENARIO   },
 		{"adventureDigGrail",        EShortcut::ADVENTURE_DIG_GRAIL       },
 		{"adventureViewPuzzle",      EShortcut::ADVENTURE_VIEW_PUZZLE     },
+		{"adventureViewWorld",       EShortcut::ADVENTURE_VIEW_WORLD      },
 		{"adventureViewWorld1",      EShortcut::ADVENTURE_VIEW_WORLD_X1   },
 		{"adventureViewWorld2",      EShortcut::ADVENTURE_VIEW_WORLD_X2   },
 		{"adventureViewWorld4",      EShortcut::ADVENTURE_VIEW_WORLD_X4   },

+ 2 - 2
config/widgets/adventureMap.json

@@ -127,7 +127,7 @@
 				},
 				{
 					"type": "adventureMapContainer",
-					"hideWhen" : "mapLayerUnderground",
+					"hideWhen" : "mapLayerSurface",
 					"area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 }
 					"items" : [
 						{
@@ -143,7 +143,7 @@
 				},
 				{
 					"type": "adventureMapContainer",
-					"hideWhen" : "mapLayerSurface",
+					"hideWhen" : "mapLayerUnderground",
 					"area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 }
 					"items" : [
 						{