1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Fixed widget disabling during enemy turn & spellcasting

This commit is contained in:
Ivan Savenko 2023-05-07 01:34:11 +03:00
parent 7228b08d1d
commit a6fda031ed
5 changed files with 65 additions and 57 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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(wasActive)
activate();
if (!widgetMustBeActive && widget->active)
widget->deactivate();
if (mapViewMustBeActive && !widget->getMapView()->active)
widget->getMapView()->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();
}

View File

@ -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

View File

@ -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
}