Browse Source

Fixed widget disabling during enemy turn & spellcasting

Ivan Savenko 2 years ago
parent
commit
a6fda031ed

+ 22 - 12
client/adventureMap/AdventureMapShortcuts.cpp

@@ -62,8 +62,8 @@ std::vector<AdventureMapShortcutState> AdventureMapShortcuts::getShortcuts()
 		{ 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_MAP_LEVEL, optionCanToggleLevel(), [this]() { this->switchMapLevel(); } },
+		{ EShortcut::ADVENTURE_QUEST_LOG,        optionCanViewQuests(),  [this]() { this->showQuestlog(); } },
 		{ EShortcut::ADVENTURE_TOGGLE_SLEEP,     optionHeroSelected(),   [this]() { this->toggleSleepWake(); } },
 		{ EShortcut::ADVENTURE_SET_HERO_ASLEEP,  optionHeroAwake(),      [this]() { this->setHeroSleeping(); } },
 		{ EShortcut::ADVENTURE_SET_HERO_AWAKE,   optionHeroSleeping(),   [this]() { this->setHeroAwake(); } },
@@ -78,7 +78,7 @@ std::vector<AdventureMapShortcutState> AdventureMapShortcuts::getShortcuts()
 		{ 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,      optionInMapView(),      [this]() { this->viewPuzzleMap(); } },
+		{ EShortcut::ADVENTURE_VIEW_PUZZLE,      optionSidePanelActive(),[this]() { this->viewPuzzleMap(); } },
 		{ EShortcut::GAME_RESTART_GAME,          optionInMapView(),      [this]() { this->restartGame(); } },
 		{ EShortcut::ADVENTURE_VISIT_OBJECT,     optionHeroSelected(),   [this]() { this->visitObject(); } },
 		{ EShortcut::ADVENTURE_VIEW_SELECTED,    optionInMapView(),      [this]() { this->openObject(); } },
@@ -391,14 +391,14 @@ void AdventureMapShortcuts::moveHeroDirectional(const Point & direction)
 			LOCPLINT->moveHero(h, path);
 }
 
-bool AdventureMapShortcuts::optionHasQuests()
+bool AdventureMapShortcuts::optionCanViewQuests()
 {
-	return CGI->mh->getMap()->quests.empty();
+	return optionInMapView() && CGI->mh->getMap()->quests.empty();
 }
 
-bool AdventureMapShortcuts::optionHasUnderground()
+bool AdventureMapShortcuts::optionCanToggleLevel()
 {
-	return LOCPLINT->cb->getMapSize().z > 0;
+	return optionInMapView() && LOCPLINT->cb->getMapSize().z > 0;
 }
 
 bool AdventureMapShortcuts::optionMapLevelSurface()
@@ -409,24 +409,24 @@ bool AdventureMapShortcuts::optionMapLevelSurface()
 bool AdventureMapShortcuts::optionHeroSleeping()
 {
 	const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero();
-	return hero && LOCPLINT->localState->isHeroSleeping(hero);
+	return optionInMapView() && hero && LOCPLINT->localState->isHeroSleeping(hero);
 }
 
 bool AdventureMapShortcuts::optionHeroAwake()
 {
 	const CGHeroInstance *hero = LOCPLINT->localState->getCurrentHero();
-	return hero && !LOCPLINT->localState->isHeroSleeping(hero);
+	return optionInMapView() && hero && !LOCPLINT->localState->isHeroSleeping(hero);
 }
 
 bool AdventureMapShortcuts::optionHeroSelected()
 {
-	return LOCPLINT->localState->getCurrentHero() != nullptr;
+	return optionInMapView() && LOCPLINT->localState->getCurrentHero() != nullptr;
 }
 
 bool AdventureMapShortcuts::optionHeroCanMove()
 {
 	const auto * hero = LOCPLINT->localState->getCurrentHero();
-	return hero && hero->movement != 0 && LOCPLINT->localState->hasPath(hero);
+	return optionInMapView() && hero && hero->movement != 0 && LOCPLINT->localState->hasPath(hero);
 }
 
 bool AdventureMapShortcuts::optionHasNextHero()
@@ -434,7 +434,7 @@ bool AdventureMapShortcuts::optionHasNextHero()
 	const auto * hero = LOCPLINT->localState->getCurrentHero();
 	const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero);
 
-	return nextSuitableHero != nullptr;
+	return optionInMapView() && nextSuitableHero != nullptr;
 }
 
 bool AdventureMapShortcuts::optionSpellcasting()
@@ -451,3 +451,13 @@ bool AdventureMapShortcuts::optionInWorldView()
 {
 	return state == EAdventureState::WORLD_VIEW;
 }
+
+bool AdventureMapShortcuts::optionSidePanelActive()
+{
+	return state == EAdventureState::MAKING_TURN || state == EAdventureState::WORLD_VIEW;
+}
+
+bool AdventureMapShortcuts::optionMapViewActive()
+{
+	return state == EAdventureState::MAKING_TURN || state == EAdventureState::WORLD_VIEW || state == EAdventureState::CASTING_SPELL;
+}

+ 4 - 2
client/adventureMap/AdventureMapShortcuts.h

@@ -69,8 +69,8 @@ public:
 
 	std::vector<AdventureMapShortcutState> getShortcuts();
 
-	bool optionHasQuests();
-	bool optionHasUnderground();
+	bool optionCanViewQuests();
+	bool optionCanToggleLevel();
 	bool optionMapLevelSurface();
 	bool optionHeroSleeping();
 	bool optionHeroAwake();
@@ -80,6 +80,8 @@ public:
 	bool optionSpellcasting();
 	bool optionInMapView();
 	bool optionInWorldView();
+	bool optionSidePanelActive();
+	bool optionMapViewActive();
 
 	void setState(EAdventureState newState);
 	void onMapViewMoved(const Rect & visibleArea, int mapLevel);

+ 36 - 39
client/adventureMap/CAdventureMapInterface.cpp

@@ -108,6 +108,8 @@ void CAdventureMapInterface::activate()
 {
 	CIntObject::activate();
 
+	adjustActiveness();
+
 	screenBuf = screen;
 	
 	if(LOCPLINT)
@@ -148,7 +150,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate()
 	uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
 	uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
 
-	bool scrollingActive = !GH.isKeyboardCtrlDown() && isActive() && shortcuts->optionInMapView();
+	bool scrollingActive = !GH.isKeyboardCtrlDown() && active && shortcuts->optionInMapView();
 
 	Point cursorPosition = GH.getCursorPosition();
 	Point scrollDirection;
@@ -258,11 +260,6 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel)
 	widget->getTownList()->redraw();
 }
 
-bool CAdventureMapInterface::isActive()
-{
-	return active & ~CIntObject::KEYBOARD;
-}
-
 void CAdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_set<int3>> positions)
 {
 	if (positions)
@@ -274,7 +271,7 @@ void CAdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_se
 void CAdventureMapInterface::onHotseatWaitStarted(PlayerColor playerID)
 {
 	onCurrentPlayerChanged(playerID);
-	shortcuts->setState(EAdventureState::HOTSEAT_WAIT);
+	setState(EAdventureState::HOTSEAT_WAIT);
 }
 
 void CAdventureMapInterface::onEnemyTurnStarted(PlayerColor playerID)
@@ -282,32 +279,36 @@ void CAdventureMapInterface::onEnemyTurnStarted(PlayerColor playerID)
 	if(settings["session"]["spectate"].Bool())
 		return;
 
-	adjustActiveness(true);
 	mapAudio->onEnemyTurnStarted();
 	widget->getMinimap()->setAIRadar(true);
 	widget->getInfoBar()->startEnemyTurn(LOCPLINT->cb->getCurrentPlayer());
-	widget->getMinimap()->showAll(screen);//force refresh on inactive object
-	widget->getInfoBar()->showAll(screen);//force refresh on inactive object
+	setState(EAdventureState::ENEMY_TURN);
+
 }
 
-void CAdventureMapInterface::adjustActiveness(bool aiTurnStart)
+void CAdventureMapInterface::setState(EAdventureState state)
 {
-	bool wasActive = isActive();
+	shortcuts->setState(state);
+	adjustActiveness();
+	widget->updateActiveState();
+}
 
-	if(wasActive)
-		deactivate();
+void CAdventureMapInterface::adjustActiveness()
+{
+	bool widgetMustBeActive = active && shortcuts->optionSidePanelActive();
+	bool mapViewMustBeActive = active && (shortcuts->optionMapViewActive());
 
-	if (aiTurnStart)
-	{
-		shortcuts->setState(EAdventureState::ENEMY_TURN);
-	}
-	else
-	{
-		shortcuts->setState(EAdventureState::MAKING_TURN);
-	}
+	if (widgetMustBeActive && !widget->active)
+		widget->activate();
+
+	if (!widgetMustBeActive && widget->active)
+		widget->deactivate();
+
+	if (mapViewMustBeActive && !widget->getMapView()->active)
+		widget->getMapView()->activate();
 
-	if(wasActive)
-		activate();
+	if (!mapViewMustBeActive && widget->getMapView()->active)
+		widget->getMapView()->deactivate();
 }
 
 void CAdventureMapInterface::onCurrentPlayerChanged(PlayerColor playerID)
@@ -325,11 +326,10 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
 {
 	onCurrentPlayerChanged(playerID);
 
-	shortcuts->setState(EAdventureState::MAKING_TURN);
+	setState(EAdventureState::MAKING_TURN);
 	if(LOCPLINT->cb->getCurrentPlayer() == LOCPLINT->playerID
 		|| settings["session"]["spectate"].Bool())
 	{
-		adjustActiveness(false);
 		widget->getMinimap()->setAIRadar(false);
 		widget->getInfoBar()->showSelection();
 	}
@@ -401,7 +401,7 @@ const CGObjectInstance* CAdventureMapInterface::getActiveObject(const int3 &mapP
 
 void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 {
-	if(!shortcuts->optionInMapView())
+	if(!shortcuts->optionMapViewActive())
 		return;
 
 	//FIXME: this line breaks H3 behavior for Dimension Door
@@ -417,6 +417,8 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 	int3 selPos = LOCPLINT->localState->getCurrentArmy()->getSightCenter();
 	if(spellBeingCasted)
 	{
+		assert(shortcuts->optionSpellcasting());
+
 		if (!isInScreenRange(selPos, mapPos))
 			return;
 
@@ -492,7 +494,7 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
 
 void CAdventureMapInterface::onTileHovered(const int3 &mapPos)
 {
-	if(!shortcuts->optionInMapView())
+	if(!shortcuts->optionMapViewActive())
 		return;
 
 	//may occur just at the start of game (fake move before full intiialization)
@@ -659,7 +661,7 @@ void CAdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & h
 
 void CAdventureMapInterface::onTileRightClicked(const int3 &mapPos)
 {
-	if(!shortcuts->optionInMapView())
+	if(!shortcuts->optionMapViewActive())
 		return;
 
 	if(spellBeingCasted)
@@ -697,16 +699,14 @@ void CAdventureMapInterface::enterCastingMode(const CSpell * sp)
 	Settings config = settings.write["session"]["showSpellRange"];
 	config->Bool() = true;
 
-	shortcuts->setState(EAdventureState::CASTING_SPELL);
-	widget->updateActiveState();
+	setState(EAdventureState::CASTING_SPELL);
 }
 
 void CAdventureMapInterface::exitCastingMode()
 {
 	assert(spellBeingCasted);
 	spellBeingCasted = nullptr;
-	shortcuts->setState(EAdventureState::MAKING_TURN);
-	widget->updateActiveState();
+	setState(EAdventureState::MAKING_TURN);
 
 	Settings config = settings.write["session"]["showSpellRange"];
 	config->Bool() = false;
@@ -744,15 +744,13 @@ const IShipyard * CAdventureMapInterface::ourInaccessibleShipyard(const CGObject
 
 void CAdventureMapInterface::hotkeyExitWorldView()
 {
-	shortcuts->setState(EAdventureState::MAKING_TURN);
-	widget->updateActiveState();
+	setState(EAdventureState::MAKING_TURN);
 	widget->getMapView()->onViewMapActivated();
 }
 
 void CAdventureMapInterface::openWorldView(int tileSize)
 {
-	shortcuts->setState(EAdventureState::WORLD_VIEW);
-	widget->updateActiveState();
+	setState(EAdventureState::WORLD_VIEW);
 	widget->getMapView()->onViewWorldActivated(tileSize);
 }
 
@@ -791,6 +789,5 @@ void CAdventureMapInterface::onScreenResize()
 	widget->updateActiveState();
 	widget->getMinimap()->update();
 
-	if (isActive())
-		widget->activate();
+	adjustActiveness();
 }

+ 3 - 2
client/adventureMap/CAdventureMapInterface.h

@@ -39,6 +39,7 @@ class CTownList;
 class CInfoBar;
 class CMinimap;
 class MapAudioPlayer;
+enum class EAdventureState;
 
 struct MapDrawingInfo;
 
@@ -61,8 +62,8 @@ private:
 	std::shared_ptr<AdventureMapShortcuts> shortcuts;
 
 private:
-	bool isActive();
-	void adjustActiveness(bool aiTurnStart); //should be called every time at AI/human turn transition; blocks GUI during AI turn
+	void setState(EAdventureState state);
+	void adjustActiveness(); //should be called every time at AI/human turn transition; blocks GUI during AI turn
 
 	const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const; //checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or nullptr else
 

+ 0 - 2
client/adventureMap/CAdventureMapWidget.cpp

@@ -452,6 +452,4 @@ void CAdventureMapWidget::updateActiveState()
 
 	for (auto entry: shortcuts->getShortcuts())
 		setShortcutBlocked(entry.shortcut, !entry.isEnabled);
-
-	//GH.totalRedraw(); // FIXME: required to eliminate graphical artifacts on leaving world view mode
 }