From 91b17bed798e604c780c4094de3855053252e0c6 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Fri, 10 Feb 2023 23:29:13 +0200 Subject: [PATCH] Partial encapsulation of AdvMapInt --- client/CPlayerInterface.cpp | 64 ++-------- client/ClientCommandManager.cpp | 27 +---- client/adventureMap/CAdvMapInt.cpp | 107 +++++++++++++--- client/adventureMap/CAdvMapInt.h | 154 ++++++++++++++---------- client/adventureMap/CAdvMapPanel.cpp | 2 - client/adventureMap/CAdvMapPanel.h | 2 +- client/adventureMap/CAdventureOptions.h | 3 +- client/adventureMap/CInGameConsole.h | 9 +- client/adventureMap/CInfoBar.cpp | 21 ++-- client/adventureMap/CList.cpp | 24 ++-- client/adventureMap/CMinimap.cpp | 10 +- client/adventureMap/CResDataBar.cpp | 16 +-- client/adventureMap/CResDataBar.h | 11 +- client/adventureMap/CTerrainRect.cpp | 10 +- client/adventureMap/CTerrainRect.h | 2 +- client/battle/BattleInterface.cpp | 4 +- client/windows/InfoWindows.cpp | 12 +- 17 files changed, 247 insertions(+), 231 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index ce6e05cd8..8f9b92fcc 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -203,8 +203,7 @@ void CPlayerInterface::yourTurn() autosaveCount %= 5; } - if (adventureInt->player != playerID) - adventureInt->setPlayer(playerID); + adventureInt->setPlayer(playerID); if (CSH->howManyPlayerInterfaces() > 1) //hot seat message { @@ -360,7 +359,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose) #ifndef VCMI_ANDROID // currently android doesn't seem to be able to handle all these full redraws here, so let's disable it so at least it looks less choppy; // most likely this is connected with the way that this manual animation+framerate handling is solved - adventureInt->updateScreen = true; + adventureInt->requestRedrawMapOnNextFrame(); #endif //evil returns here ... @@ -1582,23 +1581,13 @@ void CPlayerInterface::update() dialogs.pop_front(); } - //in some conditions we may receive calls before selection is initialized - we must ignore them - if(adventureInt && GH.topInt() == adventureInt - && (!adventureInt->selection && !settings["session"]["spectate"].Bool())) - { - return; - } + assert(adventureInt); + assert(adventureInt->selection); // Handles mouse and key input GH.updateTime(); GH.handleEvents(); - - if (!adventureInt || adventureInt->isActive()) - GH.simpleRedraw(); - else if((adventureInt->swipeEnabled && adventureInt->swipeMovementRequested) || (adventureInt->scrollingDir && GH.isKeyboardCtrlDown())) - GH.totalRedraw(); //player forces map scrolling though interface is disabled - else - GH.simpleRedraw(); + GH.simpleRedraw(); } int CPlayerInterface::getLastIndex( std::string namePrefix) @@ -1858,7 +1847,7 @@ void CPlayerInterface::showPuzzleMap() void CPlayerInterface::viewWorldMap() { - adventureInt->changeMode(EAdvMapMode::WORLD_VIEW); + adventureInt->changeMode(EAdvMapMode::WORLD_VIEW, 0.36F); } void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellID) @@ -1935,10 +1924,8 @@ CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h) void CPlayerInterface::acceptTurn() { - bool centerView = true; if (settings["session"]["autoSkip"].Bool()) { - centerView = false; while(CInfoWindow *iw = dynamic_cast(GH.topInt().get())) iw->close(); } @@ -1950,44 +1937,7 @@ void CPlayerInterface::acceptTurn() adventureInt->startTurn(); } - adventureInt->heroList->update(); - adventureInt->townList->update(); - - const CGHeroInstance * heroToSelect = nullptr; - - // find first non-sleeping hero - for (auto hero : wanderingHeroes) - { - if (boost::range::find(sleepingHeroes, hero) == sleepingHeroes.end()) - { - heroToSelect = hero; - break; - } - } - - //select first hero if available. - if (heroToSelect != nullptr) - { - adventureInt->select(heroToSelect, centerView); - } - else if (towns.size()) - adventureInt->select(towns.front(), centerView); - else - adventureInt->select(wanderingHeroes.front()); - - //show new day animation and sound on infobar - adventureInt->infoBar->showDate(); - - adventureInt->updateNextHero(nullptr); - adventureInt->showAll(screen); - - if(settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown()) - { - if(CInfoWindow *iw = dynamic_cast(GH.topInt().get())) - iw->close(); - - adventureInt->fendTurn(); - } + adventureInt->initializeNewTurn(); // warn player if he has no town if (cb->howManyTowns() == 0) diff --git a/client/ClientCommandManager.cpp b/client/ClientCommandManager.cpp index 8f112a5c9..b39edcf94 100644 --- a/client/ClientCommandManager.cpp +++ b/client/ClientCommandManager.cpp @@ -115,25 +115,6 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle { exit(EXIT_SUCCESS); } - else if(commandName == std::string("activate")) - { - int what; - singleWordBuffer >> what; - switch (what) - { - case 0: - GH.topInt()->activate(); - break; - case 1: - adventureInt->activate(); - break; - case 2: - LOCPLINT->castleInt->activate(); - break; - default: - printCommandMessage("Wrong argument specified!", ELogLevel::ERROR); - } - } else if(commandName == "redraw") { GH.totalRedraw(); @@ -274,7 +255,7 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle } else if(commandName == "mp" && adventureInt) { - if(const CGHeroInstance *h = dynamic_cast(adventureInt->selection)) + if(const CGHeroInstance *h = adventureInt->curHero()) printCommandMessage(std::to_string(h->movement) + "; max: " + std::to_string(h->maxMovePoints(true)) + "/" + std::to_string(h->maxMovePoints(false)) + "\n"); } else if(commandName == "bonuses") @@ -288,12 +269,12 @@ void ClientCommandManager::processCommand(const std::string &message, bool calle ss << b; return ss.str(); }; - printCommandMessage("Bonuses of " + adventureInt->selection->getObjectName() + "\n"); - printCommandMessage(format(adventureInt->selection->getBonusList()) + "\n"); + printCommandMessage("Bonuses of " + adventureInt->curArmy()->getObjectName() + "\n"); + printCommandMessage(format(adventureInt->curArmy()->getBonusList()) + "\n"); printCommandMessage("\nInherited bonuses:\n"); TCNodes parents; - adventureInt->selection->getParents(parents); + adventureInt->curArmy()->getParents(parents); for(const CBonusSystemNode *parent : parents) { printCommandMessage(std::string("\nBonuses from ") + typeid(*parent).name() + "\n" + format(*parent->getAllBonuses(Selector::all, Selector::all)) + "\n"); diff --git a/client/adventureMap/CAdvMapInt.cpp b/client/adventureMap/CAdvMapInt.cpp index 9d8344159..01850c31e 100644 --- a/client/adventureMap/CAdvMapInt.cpp +++ b/client/adventureMap/CAdvMapInt.cpp @@ -52,7 +52,7 @@ std::shared_ptr adventureInt; -static void setScrollingCursor(ui8 direction) +void CAdvMapInt::setScrollingCursor(ui8 direction) const { if(direction & CAdvMapInt::RIGHT) { @@ -90,7 +90,7 @@ CAdvMapInt::CAdvMapInt(): terrain(new CTerrainRect), state(NA), spellBeingCasted(nullptr), position(int3(0, 0, 0)), selection(nullptr), - updateScreen(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0), + redrawOnNextFrame(false), anim(0), animValHitCount(0), heroAnim(0), heroAnimValHitCount(0), activeMapPanel(nullptr), duringAITurn(false), scrollingDir(0), scrollingState(false), swipeEnabled(settings["general"]["swipe"].Bool()), swipeMovementRequested(false), swipeTargetPosition(int3(-1, -1, -1)) @@ -237,7 +237,7 @@ CAdvMapInt::CAdvMapInt(): activeMapPanel = panelMain; - changeMode(EAdvMapMode::NORMAL); + changeMode(EAdvMapMode::NORMAL, 0.36F); underground->block(!CGI->mh->map->twoLevel); questlog->block(!CGI->mh->map->quests.size()); @@ -253,7 +253,7 @@ void CAdvMapInt::fshowOverview() void CAdvMapInt::fworldViewBack() { - changeMode(EAdvMapMode::NORMAL); + changeMode(EAdvMapMode::NORMAL, 0.36F); CGI->mh->discardWorldViewCache(); auto hero = curHero(); @@ -292,7 +292,7 @@ void CAdvMapInt::fswitchLevel() worldViewUnderground->setIndex(position.z, true); worldViewUnderground->redraw(); - updateScreen = true; + redrawOnNextFrame = true; minimap->setLevel(position.z); if (mode == EAdvMapMode::WORLD_VIEW) @@ -525,7 +525,7 @@ void CAdvMapInt::showAll(SDL_Surface * to) } activeMapPanel->showAll(to); - updateScreen = true; + redrawOnNextFrame = true; minimap->showAll(to); show(to); @@ -570,7 +570,7 @@ void CAdvMapInt::show(SDL_Surface * to) CGI->mh->updateWater(); animValHitCount = 0; ++anim; - updateScreen = true; + redrawOnNextFrame = true; } if(swipeEnabled) @@ -591,7 +591,7 @@ void CAdvMapInt::show(SDL_Surface * to) else gems[i]->setFrame(LOCPLINT->playerID.getNum()); } - if(updateScreen) + if(redrawOnNextFrame) { int3 betterPos = LOCPLINT->repairScreenPos(position); if (betterPos != position) @@ -603,7 +603,7 @@ void CAdvMapInt::show(SDL_Surface * to) terrain->show(to); for(int i = 0; i < 4; i++) gems[i]->showAll(to); - updateScreen=false; + redrawOnNextFrame=false; LOCPLINT->cingconsole->show(to); } else @@ -621,8 +621,7 @@ void CAdvMapInt::handleMapScrollingUpdate() { int scrollSpeed = static_cast(settings["adventure"]["scrollSpeed"].Float()); //if advmap needs updating AND (no dialog is shown OR ctrl is pressed) - if((animValHitCount % (4 / scrollSpeed)) == 0 - && GH.isKeyboardCtrlDown()) + if((animValHitCount % (4 / scrollSpeed)) == 0) { if((scrollingDir & LEFT) && (position.x > -CGI->mh->frameW)) position.x--; @@ -640,7 +639,7 @@ void CAdvMapInt::handleMapScrollingUpdate() { setScrollingCursor(scrollingDir); scrollingState = true; - updateScreen = true; + redrawOnNextFrame = true; minimap->redraw(); if(mode == EAdvMapMode::WORLD_VIEW) terrain->redraw(); @@ -661,7 +660,7 @@ void CAdvMapInt::handleSwipeUpdate() position.x = fixedPos.x; position.y = fixedPos.y; CCS->curh->set(Cursor::Map::POINTER); - updateScreen = true; + redrawOnNextFrame = true; minimap->redraw(); swipeMovementRequested = false; } @@ -700,7 +699,7 @@ void CAdvMapInt::centerOn(int3 on, bool fade) on = LOCPLINT->repairScreenPos(on); position = on; - updateScreen=true; + redrawOnNextFrame=true; underground->setIndex(on.z,true); //change underground switch button image underground->redraw(); worldViewUnderground->setIndex(on.z, true); @@ -877,11 +876,14 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key) (direction->y<0 ? UP : 0) | (direction->y>0 ? DOWN : 0) ; - scrollingDir |= Dir; + //ctrl makes arrow move screen, not hero if(GH.isKeyboardCtrlDown()) + { + scrollingDir |= Dir; return; + } if(!h || !isActive()) return; @@ -1057,13 +1059,16 @@ void CAdvMapInt::startHotSeatWait(PlayerColor Player) void CAdvMapInt::setPlayer(PlayerColor Player) { + if (Player == player) + return; + player = Player; bg->playerColored(player); panelMain->setPlayerColor(player); panelWorldView->setPlayerColor(player); panelWorldView->recolorIcons(player, player.getNum() * 19); - resdatabar->background->colorize(player); + resdatabar->colorize(player); } void CAdvMapInt::startTurn() @@ -1077,6 +1082,50 @@ void CAdvMapInt::startTurn() } } +void CAdvMapInt::initializeNewTurn() +{ + heroList->update(); + townList->update(); + + const CGHeroInstance * heroToSelect = nullptr; + + // find first non-sleeping hero + for (auto hero : LOCPLINT->wanderingHeroes) + { + if (boost::range::find(LOCPLINT->sleepingHeroes, hero) == LOCPLINT->sleepingHeroes.end()) + { + heroToSelect = hero; + break; + } + } + + bool centerView = !settings["session"]["autoSkip"].Bool(); + + //select first hero if available. + if (heroToSelect != nullptr) + { + select(heroToSelect, centerView); + } + else if (LOCPLINT->towns.size()) + select(LOCPLINT->towns.front(), centerView); + else + select(LOCPLINT->wanderingHeroes.front()); + + //show new day animation and sound on infobar + infoBar->showDate(); + + updateNextHero(nullptr); + showAll(screen); + + if(settings["session"]["autoSkip"].Bool() && !GH.isKeyboardShiftDown()) + { + if(CInfoWindow *iw = dynamic_cast(GH.topInt().get())) + iw->close(); + + endingTurn(); + } +} + void CAdvMapInt::endingTurn() { if(settings["session"]["spectate"].Bool()) @@ -1415,7 +1464,7 @@ void CAdvMapInt::leaveCastingMode(bool cast, int3 dest) const CGHeroInstance * CAdvMapInt::curHero() const { if(selection && selection->ID == Obj::HERO) - return static_cast(selection); + return dynamic_cast(selection); else return nullptr; } @@ -1423,11 +1472,29 @@ const CGHeroInstance * CAdvMapInt::curHero() const const CGTownInstance * CAdvMapInt::curTown() const { if(selection && selection->ID == Obj::TOWN) - return static_cast(selection); + return dynamic_cast(selection); else return nullptr; } +const CArmedInstance * CAdvMapInt::curArmy() const +{ + if (selection) + return dynamic_cast(selection); + else + return nullptr; +} + +Rect CAdvMapInt::terrainAreaPixels() const +{ + return terrain->pos; +} + +Rect CAdvMapInt::terrainAreaTiles() const +{ + return terrain->visibleTilesArea(); +} + const IShipyard * CAdvMapInt::ourInaccessibleShipyard(const CGObjectInstance *obj) const { const IShipyard *ret = IShipyard::castFrom(obj); @@ -1537,3 +1604,7 @@ void CAdvMapInt::WorldViewOptions::adjustDrawingInfo(MapDrawingInfo& info) info.additionalIcons = &iconPositions; } +void CAdvMapInt::requestRedrawMapOnNextFrame() +{ + redrawOnNextFrame = true; +} diff --git a/client/adventureMap/CAdvMapInt.h b/client/adventureMap/CAdvMapInt.h index 0156eb831..25b07283e 100644 --- a/client/adventureMap/CAdvMapInt.h +++ b/client/adventureMap/CAdvMapInt.h @@ -53,74 +53,77 @@ enum class EAdvMapMode /// can get to the towns and heroes. class CAdvMapInt : public CIntObject { - //Return object that must be active at this tile (=clickable) - const CGObjectInstance *getActiveObject(const int3 &tile); + //TODO: remove + friend class CPlayerInterface; + friend class CTerrainRect; - boost::optional keyToMoveDirection(const SDL_Keycode & key); - -public: - CAdvMapInt(); - - int3 position; //top left corner of visible map part - PlayerColor player; - - bool duringAITurn; - - enum{LEFT=1, RIGHT=2, UP=4, DOWN=8}; - ui8 scrollingDir; //uses enum: LEFT RIGHT, UP, DOWN - bool scrollingState; - bool swipeEnabled; - bool swipeMovementRequested; - int3 swipeTargetPosition; - - enum{NA, INGAME, WAITING} state; - - bool updateScreen; - ui8 anim, animValHitCount; //animation frame - ui8 heroAnim, heroAnimValHitCount; //animation frame - - EAdvMapMode mode; - float worldViewScale; +private: + enum EDirections {LEFT=1, RIGHT=2, UP=4, DOWN=8}; + enum EGameStates {NA, INGAME, WAITING}; struct WorldViewOptions { bool showAllTerrain; //for expert viewEarth - std::vector iconPositions; - WorldViewOptions(); - void clear(); - void adjustDrawingInfo(MapDrawingInfo & info); }; + bool swipeEnabled; + bool swipeMovementRequested; + int3 swipeTargetPosition; + + EGameStates state; + + ui8 anim, animValHitCount; //animation frame + ui8 heroAnim, heroAnimValHitCount; //animation frame + + /// top left corner of visible map part + int3 position; + + EAdvMapMode mode; + float worldViewScale; + WorldViewOptions worldViewOptions; + /// Currently selected object, can be town, hero or null + const CArmedInstance *selection; + + /// currently acting player + PlayerColor player; + + bool duringAITurn; + + /// uses EDirections enum + ui8 scrollingDir; + bool scrollingState; + + const CSpell *spellBeingCasted; //nullptr if none + + std::vector> gems; + std::shared_ptr bg; std::shared_ptr bgWorldView; - std::vector> gems; - std::shared_ptr minimap; - std::shared_ptr statusbar; - std::shared_ptr kingOverview; + std::shared_ptr sleepWake; std::shared_ptr underground; std::shared_ptr questlog; - std::shared_ptr sleepWake; std::shared_ptr moveHero; std::shared_ptr spellbook; std::shared_ptr advOptions; std::shared_ptr sysOptions; std::shared_ptr nextHero; std::shared_ptr endTurn; - std::shared_ptr worldViewUnderground; - std::shared_ptr terrain; //visible terrain - std::shared_ptr resdatabar; + std::shared_ptr terrain; + std::shared_ptr minimap; std::shared_ptr heroList; std::shared_ptr townList; std::shared_ptr infoBar; + std::shared_ptr statusbar; + std::shared_ptr resdatabar; std::shared_ptr panelMain; // panel that holds all right-side buttons in normal view std::shared_ptr panelWorldView; // panel that holds all buttons and other ui in world view @@ -128,10 +131,7 @@ public: std::shared_ptr worldViewIcons;// images for world view overlay - const CSpell *spellBeingCasted; //nullptr if none - - const CArmedInstance *selection; //currently selected town/hero - +private: //functions bound to buttons void fshowOverview(); void fworldViewBack(); @@ -148,21 +148,49 @@ public: void fnextHero(); void fendTurn(); + void setScrollingCursor(ui8 direction) const; + void selectionChanged(); + bool isActive(); + void adjustActiveness(bool aiTurnStart); //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 + //button updates + void updateSleepWake(const CGHeroInstance *h); + void updateSpellbook(const CGHeroInstance *h); + + void handleMapScrollingUpdate(); + void handleSwipeUpdate(); + + void showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode); + + const CGObjectInstance *getActiveObject(const int3 &tile); + + boost::optional keyToMoveDirection(const SDL_Keycode & key); + + bool redrawOnNextFrame; +public: + CAdvMapInt(); + + // CIntObject interface implementation + void activate() override; void deactivate() override; - void show(SDL_Surface * to) override; //redraws terrain - void showAll(SDL_Surface * to) override; //shows and activates adv. map interface + void show(SDL_Surface * to) override; + void showAll(SDL_Surface * to) override; - void select(const CArmedInstance *sel, bool centerView = true); - void selectionChanged(); - void centerOn(int3 on, bool fade = false); - void centerOn(const CGObjectInstance *obj, bool fade = false); - int3 verifyPos(int3 ver); void keyPressed(const SDL_Keycode & key) override; void keyReleased(const SDL_Keycode & key) override; void mouseMoved (const Point & cursorPosition) override; - bool isActive(); + + // public interface + + void requestRedrawMapOnNextFrame(); + + void select(const CArmedInstance *sel, bool centerView = true); + void centerOn(int3 on, bool fade = false); + void centerOn(const CGObjectInstance *obj, bool fade = false); + int3 verifyPos(int3 ver); bool isHeroSleeping(const CGHeroInstance *hero); void setHeroSleeping(const CGHeroInstance *hero, bool sleep); @@ -171,34 +199,34 @@ public: void setPlayer(PlayerColor Player); void startHotSeatWait(PlayerColor Player); void startTurn(); + void initializeNewTurn(); void endingTurn(); void aiTurnStarted(); - void adjustActiveness(bool aiTurnStart); //should be called every time at AI/human turn transition; blocks GUI during AI turn void quickCombatLock(); //should be called when quick battle started void quickCombatUnlock(); + void tileLClicked(const int3 &mapPos); void tileHovered(const int3 &mapPos); void tileRClicked(const int3 &mapPos); + void enterCastingMode(const CSpell * sp); void leaveCastingMode(bool cast = false, int3 dest = int3(-1, -1, -1)); const CGHeroInstance * curHero() const; const CGTownInstance * curTown() const; - const IShipyard * ourInaccessibleShipyard(const CGObjectInstance *obj) const; //checks if obj is our ashipyard and cursor is 0,0 -> returns shipyard or nullptr else - //button updates - void updateSleepWake(const CGHeroInstance *h); + const CArmedInstance * curArmy() const; + void updateMoveHero(const CGHeroInstance *h, tribool hasPath = boost::logic::indeterminate); - void updateSpellbook(const CGHeroInstance *h); void updateNextHero(const CGHeroInstance *h); + /// returns area of screen covered by terrain (main game area) + Rect terrainAreaPixels() const; + + /// returs visible section of game map, in tiles + Rect terrainAreaTiles() const; + /// changes current adventure map mode; used to switch between default view and world view; scale is ignored if EAdvMapMode == NORMAL - void changeMode(EAdvMapMode newMode, float newScale = 0.36f); - - void handleMapScrollingUpdate(); - void handleSwipeUpdate(); - -private: - void showMoveDetailsInStatusbar(const CGHeroInstance & hero, const CGPathNode & pathNode); + void changeMode(EAdvMapMode newMode, float newScale); }; extern std::shared_ptr adventureInt; diff --git a/client/adventureMap/CAdvMapPanel.cpp b/client/adventureMap/CAdvMapPanel.cpp index 027afc273..2a2c395c2 100644 --- a/client/adventureMap/CAdvMapPanel.cpp +++ b/client/adventureMap/CAdvMapPanel.cpp @@ -74,8 +74,6 @@ CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr _icons, } } -CAdvMapWorldViewPanel::~CAdvMapWorldViewPanel() = default; - void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOffset) { assert(iconsData.size() == currentIcons.size()); diff --git a/client/adventureMap/CAdvMapPanel.h b/client/adventureMap/CAdvMapPanel.h index 0f4ef172f..624b7a635 100644 --- a/client/adventureMap/CAdvMapPanel.h +++ b/client/adventureMap/CAdvMapPanel.h @@ -51,9 +51,9 @@ class CAdvMapWorldViewPanel : public CAdvMapPanel std::shared_ptr icons; public: CAdvMapWorldViewPanel(std::shared_ptr _icons, std::shared_ptr bg, Point position, int spaceBottom, const PlayerColor &color); - virtual ~CAdvMapWorldViewPanel(); void addChildIcon(std::pair data, int indexOffset); + /// recreates all pictures from given def to recolor them according to current player color void recolorIcons(const PlayerColor & color, int indexOffset); }; diff --git a/client/adventureMap/CAdventureOptions.h b/client/adventureMap/CAdventureOptions.h index aa651ce77..f51486742 100644 --- a/client/adventureMap/CAdventureOptions.h +++ b/client/adventureMap/CAdventureOptions.h @@ -16,7 +16,6 @@ class CButton; /// Adventure options dialog where you can view the world, dig, play the replay of the last turn,... class CAdventureOptions : public CWindowObject { -public: std::shared_ptr exit; std::shared_ptr viewWorld; std::shared_ptr puzzle; @@ -24,7 +23,9 @@ public: std::shared_ptr scenInfo; /*std::shared_ptr replay*/ +public: CAdventureOptions(); + static void showScenarioInfo(); }; diff --git a/client/adventureMap/CInGameConsole.h b/client/adventureMap/CInGameConsole.h index 5d52b4fd4..93d5a204d 100644 --- a/client/adventureMap/CInGameConsole.h +++ b/client/adventureMap/CInGameConsole.h @@ -22,12 +22,13 @@ private: int maxDisplayedTexts; //hiw many texts can be displayed simultaneously std::weak_ptr currentStatusBar; -public: std::string enteredText; - void show(SDL_Surface * to) override; - void print(const std::string &txt); - void keyPressed(const SDL_Keycode & key) override; +public: + void print(const std::string &txt); + + void show(SDL_Surface * to) override; + void keyPressed(const SDL_Keycode & key) override; void textInputed(const std::string & enteredText) override; void textEdited(const std::string & enteredText) override; diff --git a/client/adventureMap/CInfoBar.cpp b/client/adventureMap/CInfoBar.cpp index d15fed03a..2a9f4cc5c 100644 --- a/client/adventureMap/CInfoBar.cpp +++ b/client/adventureMap/CInfoBar.cpp @@ -197,19 +197,18 @@ void CInfoBar::reset() void CInfoBar::showSelection() { OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); - if(adventureInt->selection) + if(adventureInt->curHero()) { - if(auto hero = dynamic_cast(adventureInt->selection)) - { - showHeroSelection(hero); - return; - } - else if(auto town = dynamic_cast(adventureInt->selection)) - { - showTownSelection(town); - return; - } + showHeroSelection(adventureInt->curHero()); + return; } + + if(adventureInt->curTown()) + { + showTownSelection(adventureInt->curTown()); + return; + } + showGameStatus();//FIXME: may be incorrect but shouldn't happen in general } diff --git a/client/adventureMap/CList.cpp b/client/adventureMap/CList.cpp index b35918c99..bb08867d8 100644 --- a/client/adventureMap/CList.cpp +++ b/client/adventureMap/CList.cpp @@ -202,7 +202,7 @@ std::shared_ptr CHeroList::CHeroItem::genSelection() void CHeroList::CHeroItem::select(bool on) { - if(on && adventureInt->selection != hero) + if(on && adventureInt->curHero() != hero) adventureInt->select(hero); } @@ -253,12 +253,9 @@ void CHeroList::update(const CGHeroInstance * hero) //simplest solution for now: reset list and restore selection listBox->resize(LOCPLINT->wanderingHeroes.size()); - if (adventureInt->selection) - { - auto selectedHero = dynamic_cast(adventureInt->selection); - if (selectedHero) - select(selectedHero); - } + if (adventureInt->curHero()) + select(adventureInt->curHero()); + CList::update(); } @@ -294,8 +291,8 @@ void CTownList::CTownItem::update() void CTownList::CTownItem::select(bool on) { - if (on && adventureInt->selection != town) - adventureInt->select(town); + if (on && adventureInt->curTown() != town) + adventureInt->select(town); } void CTownList::CTownItem::open() @@ -328,12 +325,9 @@ void CTownList::update(const CGTownInstance *) //simplest solution for now: reset list and restore selection listBox->resize(LOCPLINT->towns.size()); - if (adventureInt->selection) - { - auto town = dynamic_cast(adventureInt->selection); - if (town) - select(town); - } + if (adventureInt->curTown()) + select(adventureInt->curTown()); + CList::update(); } diff --git a/client/adventureMap/CMinimap.cpp b/client/adventureMap/CMinimap.cpp index e3ce0d308..efed856ca 100644 --- a/client/adventureMap/CMinimap.cpp +++ b/client/adventureMap/CMinimap.cpp @@ -168,15 +168,15 @@ void CMinimap::showAll(SDL_Surface * to) Canvas target(to); int3 mapSizes = LOCPLINT->cb->getMapSize(); - int3 tileCountOnScreen = adventureInt->terrain->tileCountOnScreen(); + Rect screenArea = adventureInt->terrainAreaTiles(); //draw radar Rect radar = { - adventureInt->position.x * pos.w / mapSizes.x, - adventureInt->position.y * pos.h / mapSizes.y, - tileCountOnScreen.x * pos.w / mapSizes.x - 1, - tileCountOnScreen.y * pos.h / mapSizes.y - 1 + screenArea.x * pos.w / mapSizes.x, + screenArea.y * pos.h / mapSizes.y, + screenArea.w * pos.w / mapSizes.x - 1, + screenArea.h * pos.h / mapSizes.y - 1 }; Canvas clippedTarget(target, pos); diff --git a/client/adventureMap/CResDataBar.cpp b/client/adventureMap/CResDataBar.cpp index a4ed1eb7d..43c016b96 100644 --- a/client/adventureMap/CResDataBar.cpp +++ b/client/adventureMap/CResDataBar.cpp @@ -13,7 +13,6 @@ #include "../CGameInfo.h" #include "../CPlayerInterface.h" #include "../render/Colors.h" -#include "../renderSDL/SDL_Extensions.h" #include "../gui/CGuiHandler.h" #include "../widgets/Images.h" @@ -23,10 +22,6 @@ #define ADVOPT (conf.go()->ac) -void CResDataBar::clickRight(tribool down, bool previousState) -{ -} - CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, int offy, int resdist, int datedist) { pos.x += x; @@ -70,8 +65,6 @@ CResDataBar::CResDataBar() } -CResDataBar::~CResDataBar() = default; - std::string CResDataBar::buildDateString() { std::string pattern = "%s: %d, %s: %d, %s: %d"; @@ -96,14 +89,13 @@ void CResDataBar::draw(SDL_Surface * to) graphics->fonts[FONT_SMALL]->renderTextLeft(to, buildDateString(), Colors::WHITE, Point(txtpos[7].first, txtpos[7].second)); } -void CResDataBar::show(SDL_Surface * to) -{ - -} - void CResDataBar::showAll(SDL_Surface * to) { CIntObject::showAll(to); draw(to); } +void CResDataBar::colorize(PlayerColor player) +{ + background->colorize(player); +} diff --git a/client/adventureMap/CResDataBar.h b/client/adventureMap/CResDataBar.h index 821618c8a..5207678e3 100644 --- a/client/adventureMap/CResDataBar.h +++ b/client/adventureMap/CResDataBar.h @@ -17,18 +17,17 @@ class CResDataBar : public CIntObject { std::string buildDateString(); -public: std::shared_ptr background; std::vector > txtpos; - void clickRight(tribool down, bool previousState) override; - CResDataBar(); - CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist); - ~CResDataBar(); void draw(SDL_Surface * to); - void show(SDL_Surface * to) override; +public: + CResDataBar(); + CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist); + + void colorize(PlayerColor player); void showAll(SDL_Surface * to) override; }; diff --git a/client/adventureMap/CTerrainRect.cpp b/client/adventureMap/CTerrainRect.cpp index 41b6bce4a..54eef00a2 100644 --- a/client/adventureMap/CTerrainRect.cpp +++ b/client/adventureMap/CTerrainRect.cpp @@ -189,7 +189,7 @@ void CTerrainRect::hover(bool on) { if (!on) { - adventureInt->statusbar->clear(); + GH.statusbar->clear(); CCS->curh->set(Cursor::Map::POINTER); } //Hoverable::hover(on); @@ -381,17 +381,17 @@ int3 CTerrainRect::whichTileIsIt() return whichTileIsIt(GH.getCursorPosition().x, GH.getCursorPosition().y); } -int3 CTerrainRect::tileCountOnScreen() +Rect CTerrainRect::visibleTilesArea() { switch (adventureInt->mode) { default: logGlobal->error("Unknown map mode %d", (int)adventureInt->mode); - return int3(); + return Rect(); case EAdvMapMode::NORMAL: - return int3(tilesw, tilesh, 1); + return Rect(adventureInt->position.x, adventureInt->position.y, tilesw, tilesh); case EAdvMapMode::WORLD_VIEW: - return int3((si32)(tilesw / adventureInt->worldViewScale), (si32)(tilesh / adventureInt->worldViewScale), 1); + return Rect(adventureInt->position.x, adventureInt->position.y, tilesw / adventureInt->worldViewScale, tilesh / adventureInt->worldViewScale); } } diff --git a/client/adventureMap/CTerrainRect.h b/client/adventureMap/CTerrainRect.h index 93b5ff653..cd255fe69 100644 --- a/client/adventureMap/CTerrainRect.h +++ b/client/adventureMap/CTerrainRect.h @@ -63,7 +63,7 @@ public: void showAnim(SDL_Surface * to); /// @returns number of visible tiles on screen respecting current map scaling - int3 tileCountOnScreen(); + Rect visibleTilesArea(); /// animates view by caching current surface and crossfading it with normal screen void fadeFromCurrentView(); diff --git a/client/battle/BattleInterface.cpp b/client/battle/BattleInterface.cpp index 8d1ea2ee7..f3b0676e1 100644 --- a/client/battle/BattleInterface.cpp +++ b/client/battle/BattleInterface.cpp @@ -132,10 +132,10 @@ BattleInterface::~BattleInterface() CPlayerInterface::battleInt = nullptr; givenCommand.cond.notify_all(); //that two lines should make any stacksController->getActiveStack() waiting thread to finish - if (adventureInt && adventureInt->selection) + if (adventureInt && adventureInt->curArmy()) { //FIXME: this should be moved to adventureInt which should restore correct track based on selection/active player - const auto * terrain = LOCPLINT->cb->getTile(adventureInt->selection->visitablePos())->terType; + const auto * terrain = LOCPLINT->cb->getTile(adventureInt->curArmy()->visitablePos())->terType; CCS->musich->playMusicFromSet("terrain", terrain->getJsonKey(), true, false); } diff --git a/client/windows/InfoWindows.cpp b/client/windows/InfoWindows.cpp index 22c8613cf..18cc5dfbb 100644 --- a/client/windows/InfoWindows.cpp +++ b/client/windows/InfoWindows.cpp @@ -365,8 +365,10 @@ CRClickPopupInt::~CRClickPopupInt() Point CInfoBoxPopup::toScreen(Point p) { - vstd::abetween(p.x, adventureInt->terrain->pos.x + 100, adventureInt->terrain->pos.x + adventureInt->terrain->pos.w - 100); - vstd::abetween(p.y, adventureInt->terrain->pos.y + 100, adventureInt->terrain->pos.y + adventureInt->terrain->pos.h - 100); + auto bounds = adventureInt->terrainAreaPixels(); + + vstd::abetween(p.x, bounds.top() + 100, bounds.bottom() - 100); + vstd::abetween(p.y, bounds.left() + 100, bounds.right() - 100); return p; } @@ -375,7 +377,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGTownInstance * town) : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "TOWNQVBK", toScreen(position)) { InfoAboutTown iah; - LOCPLINT->cb->getTownInfo(town, iah, adventureInt->selection); //todo: should this be nearest hero? + LOCPLINT->cb->getTownInfo(town, iah, adventureInt->curTown()); //todo: should this be nearest hero? OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); tooltip = std::make_shared(Point(9, 10), iah); @@ -385,7 +387,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGHeroInstance * hero) : CWindowObject(RCLICK_POPUP | PLAYER_COLORED, "HEROQVBK", toScreen(position)) { InfoAboutHero iah; - LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->selection);//todo: should this be nearest hero? + LOCPLINT->cb->getHeroInfo(hero, iah, adventureInt->curHero());//todo: should this be nearest hero? OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); tooltip = std::make_shared(Point(9, 10), iah); @@ -404,7 +406,7 @@ CInfoBoxPopup::CInfoBoxPopup(Point position, const CGGarrison * garr) std::shared_ptr CRClickPopup::createInfoWin(Point position, const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero { if(nullptr == specific) - specific = adventureInt->selection; + specific = adventureInt->curArmy(); if(nullptr == specific) {