mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Moved player-specific heroes & towns information to new class
This commit is contained in:
@@ -110,6 +110,7 @@ set(client_SRCS
|
|||||||
CMT.cpp
|
CMT.cpp
|
||||||
CMusicHandler.cpp
|
CMusicHandler.cpp
|
||||||
CPlayerInterface.cpp
|
CPlayerInterface.cpp
|
||||||
|
PlayerLocalState.cpp
|
||||||
CServerHandler.cpp
|
CServerHandler.cpp
|
||||||
CVideoHandler.cpp
|
CVideoHandler.cpp
|
||||||
Client.cpp
|
Client.cpp
|
||||||
@@ -238,6 +239,7 @@ set(client_HEADERS
|
|||||||
CMT.h
|
CMT.h
|
||||||
CMusicHandler.h
|
CMusicHandler.h
|
||||||
CPlayerInterface.h
|
CPlayerInterface.h
|
||||||
|
PlayerLocalState.h
|
||||||
CServerHandler.h
|
CServerHandler.h
|
||||||
CVideoHandler.h
|
CVideoHandler.h
|
||||||
Client.h
|
Client.h
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
|
#include "CPlayerInterface.h"
|
||||||
|
|
||||||
#include <vcmi/Artifact.h>
|
#include <vcmi/Artifact.h>
|
||||||
|
|
||||||
@@ -25,12 +26,12 @@
|
|||||||
#include "gui/CursorHandler.h"
|
#include "gui/CursorHandler.h"
|
||||||
#include "windows/CKingdomInterface.h"
|
#include "windows/CKingdomInterface.h"
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
|
#include "PlayerLocalState.h"
|
||||||
#include "CMT.h"
|
#include "CMT.h"
|
||||||
#include "windows/CHeroWindow.h"
|
#include "windows/CHeroWindow.h"
|
||||||
#include "windows/CCreatureWindow.h"
|
#include "windows/CCreatureWindow.h"
|
||||||
#include "windows/CQuestLog.h"
|
#include "windows/CQuestLog.h"
|
||||||
#include "windows/CPuzzleWindow.h"
|
#include "windows/CPuzzleWindow.h"
|
||||||
#include "CPlayerInterface.h"
|
|
||||||
#include "widgets/CComponent.h"
|
#include "widgets/CComponent.h"
|
||||||
#include "widgets/Buttons.h"
|
#include "widgets/Buttons.h"
|
||||||
#include "windows/CTradeWindow.h"
|
#include "windows/CTradeWindow.h"
|
||||||
@@ -114,96 +115,8 @@ struct HeroObjectRetriever
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
HeroPathStorage::HeroPathStorage(CPlayerInterface & owner):
|
|
||||||
owner(owner)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void HeroPathStorage::setPath(const CGHeroInstance *h, const CGPath & path)
|
|
||||||
{
|
|
||||||
paths[h] = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CGPath & HeroPathStorage::getPath(const CGHeroInstance *h) const
|
|
||||||
{
|
|
||||||
assert(hasPath(h));
|
|
||||||
return paths.at(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HeroPathStorage::hasPath(const CGHeroInstance *h) const
|
|
||||||
{
|
|
||||||
return paths.count(h) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HeroPathStorage::setPath(const CGHeroInstance *h, const int3 & destination)
|
|
||||||
{
|
|
||||||
CGPath path;
|
|
||||||
if (!owner.cb->getPathsInfo(h)->getPath(path, destination))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
setPath(h, path);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void HeroPathStorage::removeLastNode(const CGHeroInstance *h)
|
|
||||||
{
|
|
||||||
assert(hasPath(h));
|
|
||||||
if (!hasPath(h))
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto & path = paths[h];
|
|
||||||
path.nodes.pop_back();
|
|
||||||
if (path.nodes.size() < 2) //if it was the last one, remove entire path and path with only one tile is not a real path
|
|
||||||
erasePath(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HeroPathStorage::erasePath(const CGHeroInstance *h)
|
|
||||||
{
|
|
||||||
paths.erase(h);
|
|
||||||
adventureInt->onHeroChanged(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HeroPathStorage::verifyPath(const CGHeroInstance *h)
|
|
||||||
{
|
|
||||||
if (!hasPath(h))
|
|
||||||
return;
|
|
||||||
setPath(h, getPath(h).endPos());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Handler>
|
|
||||||
void HeroPathStorage::serialize(Handler & h, int version)
|
|
||||||
{
|
|
||||||
std::map<const CGHeroInstance *, int3> pathsMap; //hero -> dest
|
|
||||||
if (h.saving)
|
|
||||||
{
|
|
||||||
for (auto &p : paths)
|
|
||||||
{
|
|
||||||
if (p.second.nodes.size())
|
|
||||||
pathsMap[p.first] = p.second.endPos();
|
|
||||||
else
|
|
||||||
logGlobal->debug("%s has assigned an empty path! Ignoring it...", p.first->getNameTranslated());
|
|
||||||
}
|
|
||||||
h & pathsMap;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h & pathsMap;
|
|
||||||
|
|
||||||
if (owner.cb)
|
|
||||||
{
|
|
||||||
for (auto &p : pathsMap)
|
|
||||||
{
|
|
||||||
CGPath path;
|
|
||||||
owner.cb->getPathsInfo(p.first)->getPath(path, p.second);
|
|
||||||
paths[p.first] = path;
|
|
||||||
logGlobal->trace("Restored path for hero %s leading to %s with %d nodes", p.first->nodeName(), p.second.toString(), path.nodes.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CPlayerInterface::CPlayerInterface(PlayerColor Player):
|
CPlayerInterface::CPlayerInterface(PlayerColor Player):
|
||||||
paths(*this)
|
localState(std::make_unique<PlayerLocalState>(*this))
|
||||||
{
|
{
|
||||||
logGlobal->trace("\tHuman player interface for player %s being constructed", Player.getStr());
|
logGlobal->trace("\tHuman player interface for player %s being constructed", Player.getStr());
|
||||||
destinationTeleport = ObjectInstanceID();
|
destinationTeleport = ObjectInstanceID();
|
||||||
@@ -401,27 +314,27 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
|||||||
};
|
};
|
||||||
adventureInt->onMapTilesChanged(changedTiles);
|
adventureInt->onMapTilesChanged(changedTiles);
|
||||||
|
|
||||||
bool directlyAttackingCreature = details.attackedFrom && paths.hasPath(hero) && paths.getPath(hero).endPos() == *details.attackedFrom;
|
bool directlyAttackingCreature = details.attackedFrom && localState->hasPath(hero) && localState->getPath(hero).endPos() == *details.attackedFrom;
|
||||||
|
|
||||||
if(makingTurn && hero->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
if(makingTurn && hero->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
||||||
{
|
{
|
||||||
if(details.result == TryMoveHero::TELEPORTATION)
|
if(details.result == TryMoveHero::TELEPORTATION)
|
||||||
{
|
{
|
||||||
if(paths.hasPath(hero))
|
if(localState->hasPath(hero))
|
||||||
{
|
{
|
||||||
assert(paths.getPath(hero).nodes.size() >= 2);
|
assert(localState->getPath(hero).nodes.size() >= 2);
|
||||||
auto nodesIt = paths.getPath(hero).nodes.end() - 1;
|
auto nodesIt = localState->getPath(hero).nodes.end() - 1;
|
||||||
|
|
||||||
if((nodesIt)->coord == hero->convertToVisitablePos(details.start)
|
if((nodesIt)->coord == hero->convertToVisitablePos(details.start)
|
||||||
&& (nodesIt - 1)->coord == hero->convertToVisitablePos(details.end))
|
&& (nodesIt - 1)->coord == hero->convertToVisitablePos(details.end))
|
||||||
{
|
{
|
||||||
//path was between entrance and exit of teleport -> OK, erase node as usual
|
//path was between entrance and exit of teleport -> OK, erase node as usual
|
||||||
paths.removeLastNode(hero);
|
localState->removeLastNode(hero);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//teleport was not along current path, it'll now be invalid (hero is somewhere else)
|
//teleport was not along current path, it'll now be invalid (hero is somewhere else)
|
||||||
paths.erasePath(hero);
|
localState->erasePath(hero);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -430,12 +343,12 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
|||||||
if(hero->pos != details.end //hero didn't change tile but visit succeeded
|
if(hero->pos != details.end //hero didn't change tile but visit succeeded
|
||||||
|| directlyAttackingCreature) // or creature was attacked from endangering tile.
|
|| directlyAttackingCreature) // or creature was attacked from endangering tile.
|
||||||
{
|
{
|
||||||
paths.erasePath(hero);
|
localState->erasePath(hero);
|
||||||
}
|
}
|
||||||
else if(paths.hasPath(hero) && hero->pos == details.end) //&& hero is moving
|
else if(localState->hasPath(hero) && hero->pos == details.end) //&& hero is moving
|
||||||
{
|
{
|
||||||
if(details.start != details.end) //so we don't touch path when revisiting with spacebar
|
if(details.start != details.end) //so we don't touch path when revisiting with spacebar
|
||||||
paths.removeLastNode(hero);
|
localState->removeLastNode(hero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -492,9 +405,9 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
|||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
|
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
|
||||||
wanderingHeroes -= hero;
|
localState->wanderingHeroes -= hero;
|
||||||
adventureInt->onHeroChanged(hero);
|
adventureInt->onHeroChanged(hero);
|
||||||
paths.erasePath(hero);
|
localState->erasePath(hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start)
|
void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start)
|
||||||
@@ -510,7 +423,7 @@ void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectI
|
|||||||
void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
wanderingHeroes.push_back(hero);
|
localState->wanderingHeroes.push_back(hero);
|
||||||
adventureInt->onHeroChanged(hero);
|
adventureInt->onHeroChanged(hero);
|
||||||
}
|
}
|
||||||
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
||||||
@@ -596,14 +509,14 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
|||||||
|
|
||||||
if (town->garrisonHero) //wandering hero moved to the garrison
|
if (town->garrisonHero) //wandering hero moved to the garrison
|
||||||
{
|
{
|
||||||
if (town->garrisonHero->tempOwner == playerID && vstd::contains(wanderingHeroes,town->garrisonHero)) // our hero
|
if (town->garrisonHero->tempOwner == playerID && vstd::contains(localState->wanderingHeroes,town->garrisonHero)) // our hero
|
||||||
wanderingHeroes -= town->garrisonHero;
|
localState->wanderingHeroes -= town->garrisonHero;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (town->visitingHero) //hero leaves garrison
|
if (town->visitingHero) //hero leaves garrison
|
||||||
{
|
{
|
||||||
if (town->visitingHero->tempOwner == playerID && !vstd::contains(wanderingHeroes,town->visitingHero)) // our hero
|
if (town->visitingHero->tempOwner == playerID && !vstd::contains(localState->wanderingHeroes,town->visitingHero)) // our hero
|
||||||
wanderingHeroes.push_back(town->visitingHero);
|
localState->wanderingHeroes.push_back(town->visitingHero);
|
||||||
}
|
}
|
||||||
adventureInt->onHeroChanged(nullptr);
|
adventureInt->onHeroChanged(nullptr);
|
||||||
adventureInt->onTownChanged(town);
|
adventureInt->onTownChanged(town);
|
||||||
@@ -1311,29 +1224,20 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
|
|||||||
if ((bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING) && !gain)
|
if ((bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING) && !gain)
|
||||||
{
|
{
|
||||||
//recalculate paths because hero has lost bonus influencing pathfinding
|
//recalculate paths because hero has lost bonus influencing pathfinding
|
||||||
paths.erasePath(hero);
|
localState->erasePath(hero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
|
||||||
{
|
|
||||||
h & wanderingHeroes;
|
|
||||||
h & towns;
|
|
||||||
h & sleepingHeroes;
|
|
||||||
h & paths;
|
|
||||||
h & spellbookSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPlayerInterface::saveGame( BinarySerializer & h, const int version )
|
void CPlayerInterface::saveGame( BinarySerializer & h, const int version )
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
serializeTempl(h,version);
|
h & localState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::loadGame( BinaryDeserializer & h, const int version )
|
void CPlayerInterface::loadGame( BinaryDeserializer & h, const int version )
|
||||||
{
|
{
|
||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
serializeTempl(h,version);
|
h & localState;
|
||||||
firstCall = -1;
|
firstCall = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1362,7 +1266,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
|||||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||||
auto onEnd = [=](){ cb->selectionMade(0, queryID); };
|
auto onEnd = [=](){ cb->selectionMade(0, queryID); };
|
||||||
|
|
||||||
if (stillMoveHero.get() == DURING_MOVE && paths.hasPath(down) && paths.getPath(down).nodes.size() > 1) //to ignore calls on passing through garrisons
|
if (stillMoveHero.get() == DURING_MOVE && localState->hasPath(down) && localState->getPath(down).nodes.size() > 1) //to ignore calls on passing through garrisons
|
||||||
{
|
{
|
||||||
onEnd();
|
onEnd();
|
||||||
return;
|
return;
|
||||||
@@ -1441,9 +1345,9 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
|||||||
auto town = static_cast<const CGTownInstance *>(obj);
|
auto town = static_cast<const CGTownInstance *>(obj);
|
||||||
|
|
||||||
if(obj->tempOwner == playerID)
|
if(obj->tempOwner == playerID)
|
||||||
towns.push_back(town);
|
localState->ownedTowns.push_back(town);
|
||||||
else
|
else
|
||||||
towns -= obj;
|
localState->ownedTowns -= obj;
|
||||||
|
|
||||||
adventureInt->onTownChanged(town);
|
adventureInt->onTownChanged(town);
|
||||||
}
|
}
|
||||||
@@ -1452,24 +1356,24 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
|||||||
std::unordered_set<int3> upos(pos.begin(), pos.end());
|
std::unordered_set<int3> upos(pos.begin(), pos.end());
|
||||||
adventureInt->onMapTilesChanged(upos);
|
adventureInt->onMapTilesChanged(upos);
|
||||||
|
|
||||||
assert(cb->getTownsInfo().size() == towns.size());
|
assert(cb->getTownsInfo().size() == localState->ownedTowns.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPlayerInterface::initializeHeroTownList()
|
void CPlayerInterface::initializeHeroTownList()
|
||||||
{
|
{
|
||||||
if(!wanderingHeroes.size())
|
if(!localState->wanderingHeroes.size())
|
||||||
{
|
{
|
||||||
std::vector<const CGHeroInstance*> heroes = cb->getHeroesInfo();
|
std::vector<const CGHeroInstance*> heroes = cb->getHeroesInfo();
|
||||||
for(auto & hero : heroes)
|
for(auto & hero : heroes)
|
||||||
{
|
{
|
||||||
if(!hero->inTownGarrison)
|
if(!hero->inTownGarrison)
|
||||||
wanderingHeroes.push_back(hero);
|
localState->wanderingHeroes.push_back(hero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!towns.size())
|
if(!localState->ownedTowns.size())
|
||||||
towns = cb->getTownsInfo();
|
localState->ownedTowns = cb->getTownsInfo();
|
||||||
|
|
||||||
if(adventureInt)
|
if(adventureInt)
|
||||||
adventureInt->onHeroChanged(nullptr);
|
adventureInt->onHeroChanged(nullptr);
|
||||||
@@ -1736,7 +1640,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
|||||||
GH.popInts(1);
|
GH.popInts(1);
|
||||||
|
|
||||||
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
||||||
paths.erasePath(caster);
|
localState->erasePath(caster);
|
||||||
|
|
||||||
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
|
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
|
||||||
auto castSoundPath = spell->getCastSound();
|
auto castSoundPath = spell->getCastSound();
|
||||||
@@ -1972,12 +1876,6 @@ void CPlayerInterface::proposeLoadingGame()
|
|||||||
showYesNoDialog(CGI->generaltexth->allTexts[68], [](){ GH.pushUserEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
|
showYesNoDialog(CGI->generaltexth->allTexts[68], [](){ GH.pushUserEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlayerInterface::SpellbookLastSetting::SpellbookLastSetting()
|
|
||||||
{
|
|
||||||
spellbookLastPageBattle = spellbokLastPageAdvmap = 0;
|
|
||||||
spellbookLastTabBattle = spellbookLastTabAdvmap = 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPlayerInterface::capturedAllEvents()
|
bool CPlayerInterface::capturedAllEvents()
|
||||||
{
|
{
|
||||||
if(duringMovement)
|
if(duringMovement)
|
||||||
|
@@ -9,16 +9,10 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
#include "../lib/FunctionList.h"
|
#include "../lib/FunctionList.h"
|
||||||
#include "../lib/CGameInterface.h"
|
#include "../lib/CGameInterface.h"
|
||||||
#include "../lib/NetPacksBase.h"
|
|
||||||
#include "gui/CIntObject.h"
|
#include "gui/CIntObject.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define sprintf_s snprintf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
class Artifact;
|
class Artifact;
|
||||||
@@ -51,43 +45,16 @@ class ClickableR;
|
|||||||
class Hoverable;
|
class Hoverable;
|
||||||
class KeyInterested;
|
class KeyInterested;
|
||||||
class MotionInterested;
|
class MotionInterested;
|
||||||
|
class PlayerLocalState;
|
||||||
class TimeInterested;
|
class TimeInterested;
|
||||||
class IShowable;
|
class IShowable;
|
||||||
|
|
||||||
struct SDL_Surface;
|
|
||||||
union SDL_Event;
|
|
||||||
|
|
||||||
namespace boost
|
namespace boost
|
||||||
{
|
{
|
||||||
class mutex;
|
class mutex;
|
||||||
class recursive_mutex;
|
class recursive_mutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CPlayerInterface;
|
|
||||||
|
|
||||||
class HeroPathStorage
|
|
||||||
{
|
|
||||||
CPlayerInterface & owner;
|
|
||||||
|
|
||||||
std::map<const CGHeroInstance *, CGPath> paths; //maps hero => selected path in adventure map
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit HeroPathStorage(CPlayerInterface &owner);
|
|
||||||
|
|
||||||
void setPath(const CGHeroInstance *h, const CGPath & path);
|
|
||||||
bool setPath(const CGHeroInstance *h, const int3 & destination);
|
|
||||||
|
|
||||||
const CGPath & getPath(const CGHeroInstance *h) const;
|
|
||||||
bool hasPath(const CGHeroInstance *h) const;
|
|
||||||
|
|
||||||
void removeLastNode(const CGHeroInstance *h);
|
|
||||||
void erasePath(const CGHeroInstance *h);
|
|
||||||
void verifyPath(const CGHeroInstance *h);
|
|
||||||
|
|
||||||
template <typename Handler>
|
|
||||||
void serialize( Handler &h, int version );
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Central class for managing user interface logic
|
/// Central class for managing user interface logic
|
||||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||||
{
|
{
|
||||||
@@ -107,7 +74,7 @@ class CPlayerInterface : public CGameInterface, public IUpdateable
|
|||||||
public: // TODO: make private
|
public: // TODO: make private
|
||||||
std::shared_ptr<Environment> env;
|
std::shared_ptr<Environment> env;
|
||||||
|
|
||||||
HeroPathStorage paths;
|
std::unique_ptr<PlayerLocalState> localState;
|
||||||
|
|
||||||
//minor interfaces
|
//minor interfaces
|
||||||
CondSh<bool> *showingDialog; //indicates if dialog box is displayed
|
CondSh<bool> *showingDialog; //indicates if dialog box is displayed
|
||||||
@@ -121,29 +88,10 @@ public: // TODO: make private
|
|||||||
|
|
||||||
std::shared_ptr<CCallback> cb; //to communicate with engine
|
std::shared_ptr<CCallback> cb; //to communicate with engine
|
||||||
|
|
||||||
std::vector<const CGHeroInstance *> wanderingHeroes; //our heroes on the adventure map (not the garrisoned ones)
|
|
||||||
std::vector<const CGTownInstance *> towns; //our towns on the adventure map
|
|
||||||
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
|
||||||
|
|
||||||
//During battle is quick combat mode is used
|
//During battle is quick combat mode is used
|
||||||
std::shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
std::shared_ptr<CBattleGameInterface> autofightingAI; //AI that makes decisions
|
||||||
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
bool isAutoFightOn; //Flag, switch it to stop quick combat. Don't touch if there is no battle interface.
|
||||||
|
|
||||||
struct SpellbookLastSetting
|
|
||||||
{
|
|
||||||
int spellbookLastPageBattle, spellbokLastPageAdvmap; //on which page we left spellbook
|
|
||||||
int spellbookLastTabBattle, spellbookLastTabAdvmap; //on which page we left spellbook
|
|
||||||
|
|
||||||
SpellbookLastSetting();
|
|
||||||
template <typename Handler> void serialize( Handler &h, const int version )
|
|
||||||
{
|
|
||||||
h & spellbookLastPageBattle;
|
|
||||||
h & spellbokLastPageAdvmap;
|
|
||||||
h & spellbookLastTabBattle;
|
|
||||||
h & spellbookLastTabAdvmap;
|
|
||||||
}
|
|
||||||
} spellbookSettings;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void update() override;
|
void update() override;
|
||||||
void initializeHeroTownList();
|
void initializeHeroTownList();
|
||||||
@@ -267,8 +215,6 @@ public:
|
|||||||
~CPlayerInterface();
|
~CPlayerInterface();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename Handler> void serializeTempl(Handler &h, const int version);
|
|
||||||
|
|
||||||
struct IgnoreEvents
|
struct IgnoreEvents
|
||||||
{
|
{
|
||||||
CPlayerInterface & owner;
|
CPlayerInterface & owner;
|
||||||
|
105
client/PlayerLocalState.cpp
Normal file
105
client/PlayerLocalState.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* PlayerLocalState.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 "PlayerLocalState.h"
|
||||||
|
|
||||||
|
#include "../CCallback.h"
|
||||||
|
#include "../lib/CPathfinder.h"
|
||||||
|
#include "../lib/mapObjects/CGHeroInstance.h"
|
||||||
|
#include "CPlayerInterface.h"
|
||||||
|
#include "adventureMap/CAdventureMapInterface.h"
|
||||||
|
|
||||||
|
PlayerLocalState::PlayerLocalState()
|
||||||
|
: owner(*LOCPLINT)
|
||||||
|
{
|
||||||
|
// should never be called, method required for serializer methods template instantiations
|
||||||
|
throw std::runtime_error("Can not create PlayerLocalState without interface!");
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerLocalState::PlayerLocalState(CPlayerInterface & owner)
|
||||||
|
: owner(owner)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::saveHeroPaths(std::map<const CGHeroInstance *, int3> & pathsMap)
|
||||||
|
{
|
||||||
|
for(auto & p : paths)
|
||||||
|
{
|
||||||
|
if(p.second.nodes.size())
|
||||||
|
pathsMap[p.first] = p.second.endPos();
|
||||||
|
else
|
||||||
|
logGlobal->debug("%s has assigned an empty path! Ignoring it...", p.first->getNameTranslated());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::loadHeroPaths(std::map<const CGHeroInstance *, int3> & pathsMap)
|
||||||
|
{
|
||||||
|
if(owner.cb)
|
||||||
|
{
|
||||||
|
for(auto & p : pathsMap)
|
||||||
|
{
|
||||||
|
CGPath path;
|
||||||
|
owner.cb->getPathsInfo(p.first)->getPath(path, p.second);
|
||||||
|
paths[p.first] = path;
|
||||||
|
logGlobal->trace("Restored path for hero %s leading to %s with %d nodes", p.first->nodeName(), p.second.toString(), path.nodes.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::setPath(const CGHeroInstance * h, const CGPath & path)
|
||||||
|
{
|
||||||
|
paths[h] = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CGPath & PlayerLocalState::getPath(const CGHeroInstance * h) const
|
||||||
|
{
|
||||||
|
assert(hasPath(h));
|
||||||
|
return paths.at(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerLocalState::hasPath(const CGHeroInstance * h) const
|
||||||
|
{
|
||||||
|
return paths.count(h) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PlayerLocalState::setPath(const CGHeroInstance * h, const int3 & destination)
|
||||||
|
{
|
||||||
|
CGPath path;
|
||||||
|
if(!owner.cb->getPathsInfo(h)->getPath(path, destination))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
setPath(h, path);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::removeLastNode(const CGHeroInstance * h)
|
||||||
|
{
|
||||||
|
assert(hasPath(h));
|
||||||
|
if(!hasPath(h))
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto & path = paths[h];
|
||||||
|
path.nodes.pop_back();
|
||||||
|
if(path.nodes.size() < 2) //if it was the last one, remove entire path and path with only one tile is not a real path
|
||||||
|
erasePath(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::erasePath(const CGHeroInstance * h)
|
||||||
|
{
|
||||||
|
paths.erase(h);
|
||||||
|
adventureInt->onHeroChanged(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerLocalState::verifyPath(const CGHeroInstance * h)
|
||||||
|
{
|
||||||
|
if(!hasPath(h))
|
||||||
|
return;
|
||||||
|
setPath(h, getPath(h).endPos());
|
||||||
|
}
|
84
client/PlayerLocalState.h
Normal file
84
client/PlayerLocalState.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/*
|
||||||
|
* PlayerLocalState.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
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
|
class CGHeroInstance;
|
||||||
|
class CGTownInstance;
|
||||||
|
struct CGPath;
|
||||||
|
class int3;
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
|
class CPlayerInterface;
|
||||||
|
|
||||||
|
/// Class that contains potentially serializeable state of a local player
|
||||||
|
class PlayerLocalState
|
||||||
|
{
|
||||||
|
CPlayerInterface & owner;
|
||||||
|
|
||||||
|
std::map<const CGHeroInstance *, CGPath> paths; //maps hero => selected path in adventure map
|
||||||
|
|
||||||
|
void saveHeroPaths(std::map<const CGHeroInstance *, int3> & paths);
|
||||||
|
void loadHeroPaths(std::map<const CGHeroInstance *, int3> & paths);
|
||||||
|
public:
|
||||||
|
struct SpellbookLastSetting
|
||||||
|
{
|
||||||
|
//on which page we left spellbook
|
||||||
|
int spellbookLastPageBattle = 0;
|
||||||
|
int spellbokLastPageAdvmap = 0;
|
||||||
|
int spellbookLastTabBattle = 4;
|
||||||
|
int spellbookLastTabAdvmap = 4;
|
||||||
|
|
||||||
|
template <typename Handler> void serialize( Handler &h, const int version )
|
||||||
|
{
|
||||||
|
h & spellbookLastPageBattle;
|
||||||
|
h & spellbokLastPageAdvmap;
|
||||||
|
h & spellbookLastTabBattle;
|
||||||
|
h & spellbookLastTabAdvmap;
|
||||||
|
}
|
||||||
|
} spellbookSettings;
|
||||||
|
|
||||||
|
std::vector<const CGHeroInstance *> wanderingHeroes; //our heroes on the adventure map (not the garrisoned ones)
|
||||||
|
std::vector<const CGTownInstance *> ownedTowns; //our towns on the adventure map
|
||||||
|
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
||||||
|
|
||||||
|
PlayerLocalState();
|
||||||
|
explicit PlayerLocalState(CPlayerInterface & owner);
|
||||||
|
|
||||||
|
void setPath(const CGHeroInstance *h, const CGPath & path);
|
||||||
|
bool setPath(const CGHeroInstance *h, const int3 & destination);
|
||||||
|
|
||||||
|
const CGPath & getPath(const CGHeroInstance *h) const;
|
||||||
|
bool hasPath(const CGHeroInstance *h) const;
|
||||||
|
|
||||||
|
void removeLastNode(const CGHeroInstance *h);
|
||||||
|
void erasePath(const CGHeroInstance *h);
|
||||||
|
void verifyPath(const CGHeroInstance *h);
|
||||||
|
|
||||||
|
template <typename Handler>
|
||||||
|
void serialize( Handler &h, int version )
|
||||||
|
{
|
||||||
|
//WARNING: this code is broken and not used. See CClient::loadGame
|
||||||
|
std::map<const CGHeroInstance *, int3> pathsMap; //hero -> dest
|
||||||
|
if(h.saving)
|
||||||
|
saveHeroPaths(pathsMap);
|
||||||
|
|
||||||
|
h & pathsMap;
|
||||||
|
|
||||||
|
if(!h.saving)
|
||||||
|
loadHeroPaths(pathsMap);
|
||||||
|
|
||||||
|
h & ownedTowns;
|
||||||
|
h & wanderingHeroes;
|
||||||
|
h & sleepingHeroes;
|
||||||
|
}
|
||||||
|
};
|
@@ -38,6 +38,7 @@
|
|||||||
#include "../widgets/Buttons.h"
|
#include "../widgets/Buttons.h"
|
||||||
#include "../windows/settings/SettingsMainWindow.h"
|
#include "../windows/settings/SettingsMainWindow.h"
|
||||||
#include "../CMT.h"
|
#include "../CMT.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
|
|
||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
#include "../../lib/CConfigHandler.h"
|
#include "../../lib/CConfigHandler.h"
|
||||||
@@ -309,10 +310,10 @@ void CAdventureMapInterface::fsleepWake()
|
|||||||
void CAdventureMapInterface::fmoveHero()
|
void CAdventureMapInterface::fmoveHero()
|
||||||
{
|
{
|
||||||
const CGHeroInstance *h = getCurrentHero();
|
const CGHeroInstance *h = getCurrentHero();
|
||||||
if (!h || !LOCPLINT->paths.hasPath(h) || CGI->mh->hasOngoingAnimations())
|
if (!h || !LOCPLINT->localState->hasPath(h) || CGI->mh->hasOngoingAnimations())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
|
LOCPLINT->moveHero(h, LOCPLINT->localState->getPath(h));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureMapInterface::fshowSpellbok()
|
void CAdventureMapInterface::fshowSpellbok()
|
||||||
@@ -338,10 +339,10 @@ void CAdventureMapInterface::fsystemOptions()
|
|||||||
void CAdventureMapInterface::fnextHero()
|
void CAdventureMapInterface::fnextHero()
|
||||||
{
|
{
|
||||||
auto hero = dynamic_cast<const CGHeroInstance*>(currentSelection);
|
auto hero = dynamic_cast<const CGHeroInstance*>(currentSelection);
|
||||||
int next = getNextHeroIndex(vstd::find_pos(LOCPLINT->wanderingHeroes, hero));
|
int next = getNextHeroIndex(vstd::find_pos(LOCPLINT->localState->wanderingHeroes, hero));
|
||||||
if (next < 0)
|
if (next < 0)
|
||||||
return;
|
return;
|
||||||
setSelection(LOCPLINT->wanderingHeroes[next], true);
|
setSelection(LOCPLINT->localState->wanderingHeroes[next], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureMapInterface::fendTurn()
|
void CAdventureMapInterface::fendTurn()
|
||||||
@@ -351,22 +352,22 @@ void CAdventureMapInterface::fendTurn()
|
|||||||
|
|
||||||
if(settings["adventure"]["heroReminder"].Bool())
|
if(settings["adventure"]["heroReminder"].Bool())
|
||||||
{
|
{
|
||||||
for(auto hero : LOCPLINT->wanderingHeroes)
|
for(auto hero : LOCPLINT->localState->wanderingHeroes)
|
||||||
{
|
{
|
||||||
if(!isHeroSleeping(hero) && hero->movement > 0)
|
if(!isHeroSleeping(hero) && hero->movement > 0)
|
||||||
{
|
{
|
||||||
// Only show hero reminder if conditions met:
|
// Only show hero reminder if conditions met:
|
||||||
// - There still movement points
|
// - There still movement points
|
||||||
// - Hero don't have a path or there not points for first step on path
|
// - Hero don't have a path or there not points for first step on path
|
||||||
LOCPLINT->paths.verifyPath(hero);
|
LOCPLINT->localState->verifyPath(hero);
|
||||||
|
|
||||||
if(!LOCPLINT->paths.hasPath(hero))
|
if(!LOCPLINT->localState->hasPath(hero))
|
||||||
{
|
{
|
||||||
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdventureMapInterface::endingTurn, this), nullptr );
|
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdventureMapInterface::endingTurn, this), nullptr );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path = LOCPLINT->paths.getPath(hero);
|
auto path = LOCPLINT->localState->getPath(hero);
|
||||||
if (path.nodes.size() < 2 || path.nodes[path.nodes.size() - 2].turns)
|
if (path.nodes.size() < 2 || path.nodes[path.nodes.size() - 2].turns)
|
||||||
{
|
{
|
||||||
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdventureMapInterface::endingTurn, this), nullptr );
|
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdventureMapInterface::endingTurn, this), nullptr );
|
||||||
@@ -396,7 +397,7 @@ void CAdventureMapInterface::updateSpellbook(const CGHeroInstance *h)
|
|||||||
|
|
||||||
int CAdventureMapInterface::getNextHeroIndex(int startIndex)
|
int CAdventureMapInterface::getNextHeroIndex(int startIndex)
|
||||||
{
|
{
|
||||||
if (LOCPLINT->wanderingHeroes.size() == 0)
|
if (LOCPLINT->localState->wanderingHeroes.size() == 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (startIndex < 0)
|
if (startIndex < 0)
|
||||||
startIndex = 0;
|
startIndex = 0;
|
||||||
@@ -404,12 +405,12 @@ int CAdventureMapInterface::getNextHeroIndex(int startIndex)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
if (i >= LOCPLINT->wanderingHeroes.size())
|
if (i >= LOCPLINT->localState->wanderingHeroes.size())
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
while (((LOCPLINT->wanderingHeroes[i]->movement == 0) || isHeroSleeping(LOCPLINT->wanderingHeroes[i])) && (i != startIndex));
|
while (((LOCPLINT->localState->wanderingHeroes[i]->movement == 0) || isHeroSleeping(LOCPLINT->localState->wanderingHeroes[i])) && (i != startIndex));
|
||||||
|
|
||||||
if ((LOCPLINT->wanderingHeroes[i]->movement != 0) && !isHeroSleeping(LOCPLINT->wanderingHeroes[i]))
|
if ((LOCPLINT->localState->wanderingHeroes[i]->movement != 0) && !isHeroSleeping(LOCPLINT->localState->wanderingHeroes[i]))
|
||||||
return i;
|
return i;
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
@@ -422,14 +423,14 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
|
|||||||
if (h == getCurrentHero())
|
if (h == getCurrentHero())
|
||||||
infoBar->showSelection();
|
infoBar->showSelection();
|
||||||
|
|
||||||
int start = vstd::find_pos(LOCPLINT->wanderingHeroes, h);
|
int start = vstd::find_pos(LOCPLINT->localState->wanderingHeroes, h);
|
||||||
int next = getNextHeroIndex(start);
|
int next = getNextHeroIndex(start);
|
||||||
if (next < 0)
|
if (next < 0)
|
||||||
{
|
{
|
||||||
nextHero->block(true);
|
nextHero->block(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const CGHeroInstance *nextH = LOCPLINT->wanderingHeroes[next];
|
const CGHeroInstance *nextH = LOCPLINT->localState->wanderingHeroes[next];
|
||||||
bool noActiveHeroes = (next == start) && ((nextH->movement == 0) || isHeroSleeping(nextH));
|
bool noActiveHeroes = (next == start) && ((nextH->movement == 0) || isHeroSleeping(nextH));
|
||||||
nextHero->block(noActiveHeroes);
|
nextHero->block(noActiveHeroes);
|
||||||
|
|
||||||
@@ -439,7 +440,7 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
|
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
|
||||||
bool hasPath = LOCPLINT->paths.hasPath(h);
|
bool hasPath = LOCPLINT->localState->hasPath(h);
|
||||||
|
|
||||||
moveHero->block(!(bool)hasPath || (h->movement == 0));
|
moveHero->block(!(bool)hasPath || (h->movement == 0));
|
||||||
}
|
}
|
||||||
@@ -538,7 +539,7 @@ bool CAdventureMapInterface::isHeroSleeping(const CGHeroInstance *hero)
|
|||||||
if (!hero)
|
if (!hero)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return vstd::contains(LOCPLINT->sleepingHeroes, hero);
|
return vstd::contains(LOCPLINT->localState->sleepingHeroes, hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAdventureMapInterface::onHeroWokeUp(const CGHeroInstance * hero)
|
void CAdventureMapInterface::onHeroWokeUp(const CGHeroInstance * hero)
|
||||||
@@ -556,9 +557,9 @@ void CAdventureMapInterface::onHeroWokeUp(const CGHeroInstance * hero)
|
|||||||
void CAdventureMapInterface::setHeroSleeping(const CGHeroInstance *hero, bool sleep)
|
void CAdventureMapInterface::setHeroSleeping(const CGHeroInstance *hero, bool sleep)
|
||||||
{
|
{
|
||||||
if (sleep)
|
if (sleep)
|
||||||
LOCPLINT->sleepingHeroes.push_back(hero); //FIXME: should we check for existence?
|
LOCPLINT->localState->sleepingHeroes.push_back(hero); //FIXME: should we check for existence?
|
||||||
else
|
else
|
||||||
LOCPLINT->sleepingHeroes -= hero;
|
LOCPLINT->localState->sleepingHeroes -= hero;
|
||||||
|
|
||||||
onHeroChanged(hero);
|
onHeroChanged(hero);
|
||||||
}
|
}
|
||||||
@@ -654,7 +655,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate()
|
|||||||
|
|
||||||
void CAdventureMapInterface::selectionChanged()
|
void CAdventureMapInterface::selectionChanged()
|
||||||
{
|
{
|
||||||
const CGTownInstance *to = LOCPLINT->towns[townList->getSelectedIndex()];
|
const CGTownInstance *to = LOCPLINT->localState->ownedTowns[townList->getSelectedIndex()];
|
||||||
if (currentSelection != to)
|
if (currentSelection != to)
|
||||||
setSelection(to);
|
setSelection(to);
|
||||||
}
|
}
|
||||||
@@ -685,12 +686,12 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
|||||||
|
|
||||||
{
|
{
|
||||||
//find first town with tavern
|
//find first town with tavern
|
||||||
auto itr = range::find_if(LOCPLINT->towns, [](const CGTownInstance * town)
|
auto itr = range::find_if(LOCPLINT->localState->ownedTowns, [](const CGTownInstance * town)
|
||||||
{
|
{
|
||||||
return town->hasBuilt(BuildingID::TAVERN);
|
return town->hasBuilt(BuildingID::TAVERN);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(itr != LOCPLINT->towns.end())
|
if(itr != LOCPLINT->localState->ownedTowns.end())
|
||||||
LOCPLINT->showThievesGuildWindow(*itr);
|
LOCPLINT->showThievesGuildWindow(*itr);
|
||||||
else
|
else
|
||||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
|
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
|
||||||
@@ -819,10 +820,10 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
|||||||
if (!CGI->mh->isInMap((dst)))
|
if (!CGI->mh->isInMap((dst)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( !LOCPLINT->paths.setPath(h, dst))
|
if ( !LOCPLINT->localState->setPath(h, dst))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const CGPath & path = LOCPLINT->paths.getPath(h);
|
const CGPath & path = LOCPLINT->localState->getPath(h);
|
||||||
|
|
||||||
if (path.nodes.size() > 2)
|
if (path.nodes.size() > 2)
|
||||||
onHeroChanged(h);
|
onHeroChanged(h);
|
||||||
@@ -885,7 +886,7 @@ void CAdventureMapInterface::setSelection(const CArmedInstance *sel, bool center
|
|||||||
heroList->select(hero);
|
heroList->select(hero);
|
||||||
townList->select(nullptr);
|
townList->select(nullptr);
|
||||||
|
|
||||||
LOCPLINT->paths.verifyPath(hero);
|
LOCPLINT->localState->verifyPath(hero);
|
||||||
|
|
||||||
updateSleepWake(hero);
|
updateSleepWake(hero);
|
||||||
onHeroChanged(hero);
|
onHeroChanged(hero);
|
||||||
@@ -978,9 +979,9 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
|
|||||||
const CGHeroInstance * heroToSelect = nullptr;
|
const CGHeroInstance * heroToSelect = nullptr;
|
||||||
|
|
||||||
// find first non-sleeping hero
|
// find first non-sleeping hero
|
||||||
for (auto hero : LOCPLINT->wanderingHeroes)
|
for (auto hero : LOCPLINT->localState->wanderingHeroes)
|
||||||
{
|
{
|
||||||
if (boost::range::find(LOCPLINT->sleepingHeroes, hero) == LOCPLINT->sleepingHeroes.end())
|
if (boost::range::find(LOCPLINT->localState->sleepingHeroes, hero) == LOCPLINT->localState->sleepingHeroes.end())
|
||||||
{
|
{
|
||||||
heroToSelect = hero;
|
heroToSelect = hero;
|
||||||
break;
|
break;
|
||||||
@@ -994,10 +995,10 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
|
|||||||
{
|
{
|
||||||
setSelection(heroToSelect, centerView);
|
setSelection(heroToSelect, centerView);
|
||||||
}
|
}
|
||||||
else if (LOCPLINT->towns.size())
|
else if (LOCPLINT->localState->ownedTowns.size())
|
||||||
setSelection(LOCPLINT->towns.front(), centerView);
|
setSelection(LOCPLINT->localState->ownedTowns.front(), centerView);
|
||||||
else
|
else
|
||||||
setSelection(LOCPLINT->wanderingHeroes.front());
|
setSelection(LOCPLINT->localState->wanderingHeroes.front());
|
||||||
|
|
||||||
//show new day animation and sound on infobar
|
//show new day animation and sound on infobar
|
||||||
infoBar->showDate();
|
infoBar->showDate();
|
||||||
@@ -1102,16 +1103,16 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos)
|
|||||||
}
|
}
|
||||||
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
|
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
|
||||||
{
|
{
|
||||||
if(LOCPLINT->paths.hasPath(currentHero) &&
|
if(LOCPLINT->localState->hasPath(currentHero) &&
|
||||||
LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
|
LOCPLINT->localState->getPath(currentHero).endPos() == mapPos)//we'll be moving
|
||||||
{
|
{
|
||||||
if(!CGI->mh->hasOngoingAnimations())
|
if(!CGI->mh->hasOngoingAnimations())
|
||||||
LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
|
LOCPLINT->moveHero(currentHero, LOCPLINT->localState->getPath(currentHero));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else //remove old path and find a new one if we clicked on accessible tile
|
else //remove old path and find a new one if we clicked on accessible tile
|
||||||
{
|
{
|
||||||
LOCPLINT->paths.setPath(currentHero, mapPos);
|
LOCPLINT->localState->setPath(currentHero, mapPos);
|
||||||
onHeroChanged(currentHero);
|
onHeroChanged(currentHero);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CMusicHandler.h"
|
#include "../CMusicHandler.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
|
|
||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
@@ -114,7 +115,7 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
|
|||||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||||
//get amount of halls of each level
|
//get amount of halls of each level
|
||||||
std::vector<int> halls(4, 0);
|
std::vector<int> halls(4, 0);
|
||||||
for(auto town : LOCPLINT->towns)
|
for(auto town : LOCPLINT->localState->ownedTowns)
|
||||||
{
|
{
|
||||||
int hallLevel = town->hallLevel();
|
int hallLevel = town->hallLevel();
|
||||||
//negative value means no village hall, unlikely but possible
|
//negative value means no village hall, unlikely but possible
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
#include "../windows/InfoWindows.h"
|
#include "../windows/InfoWindows.h"
|
||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
|
|
||||||
#include "../../lib/CGeneralTextHandler.h"
|
#include "../../lib/CGeneralTextHandler.h"
|
||||||
@@ -224,19 +225,19 @@ std::string CHeroList::CHeroItem::getHoverText()
|
|||||||
|
|
||||||
std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)
|
std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)
|
||||||
{
|
{
|
||||||
if (LOCPLINT->wanderingHeroes.size() > index)
|
if (LOCPLINT->localState->wanderingHeroes.size() > index)
|
||||||
return std::make_shared<CHeroItem>(this, LOCPLINT->wanderingHeroes[index]);
|
return std::make_shared<CHeroItem>(this, LOCPLINT->localState->wanderingHeroes[index]);
|
||||||
return std::make_shared<CEmptyHeroItem>();
|
return std::make_shared<CEmptyHeroItem>();
|
||||||
}
|
}
|
||||||
|
|
||||||
CHeroList::CHeroList(int size, Point position, std::string btnUp, std::string btnDown):
|
CHeroList::CHeroList(int size, Point position, std::string btnUp, std::string btnDown):
|
||||||
CList(size, position, btnUp, btnDown, LOCPLINT->wanderingHeroes.size(), 303, 304, std::bind(&CHeroList::createHeroItem, this, _1))
|
CList(size, position, btnUp, btnDown, LOCPLINT->localState->wanderingHeroes.size(), 303, 304, std::bind(&CHeroList::createHeroItem, this, _1))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroList::select(const CGHeroInstance * hero)
|
void CHeroList::select(const CGHeroInstance * hero)
|
||||||
{
|
{
|
||||||
selectIndex(vstd::find_pos(LOCPLINT->wanderingHeroes, hero));
|
selectIndex(vstd::find_pos(LOCPLINT->localState->wanderingHeroes, hero));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHeroList::update(const CGHeroInstance * hero)
|
void CHeroList::update(const CGHeroInstance * hero)
|
||||||
@@ -245,7 +246,7 @@ void CHeroList::update(const CGHeroInstance * hero)
|
|||||||
for(auto & elem : listBox->getItems())
|
for(auto & elem : listBox->getItems())
|
||||||
{
|
{
|
||||||
auto item = std::dynamic_pointer_cast<CHeroItem>(elem);
|
auto item = std::dynamic_pointer_cast<CHeroItem>(elem);
|
||||||
if(item && item->hero == hero && vstd::contains(LOCPLINT->wanderingHeroes, hero))
|
if(item && item->hero == hero && vstd::contains(LOCPLINT->localState->wanderingHeroes, hero))
|
||||||
{
|
{
|
||||||
item->update();
|
item->update();
|
||||||
return;
|
return;
|
||||||
@@ -253,7 +254,7 @@ void CHeroList::update(const CGHeroInstance * hero)
|
|||||||
}
|
}
|
||||||
//simplest solution for now: reset list and restore selection
|
//simplest solution for now: reset list and restore selection
|
||||||
|
|
||||||
listBox->resize(LOCPLINT->wanderingHeroes.size());
|
listBox->resize(LOCPLINT->localState->wanderingHeroes.size());
|
||||||
if (adventureInt->getCurrentHero())
|
if (adventureInt->getCurrentHero())
|
||||||
select(adventureInt->getCurrentHero());
|
select(adventureInt->getCurrentHero());
|
||||||
|
|
||||||
@@ -262,8 +263,8 @@ void CHeroList::update(const CGHeroInstance * hero)
|
|||||||
|
|
||||||
std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index)
|
std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index)
|
||||||
{
|
{
|
||||||
if (LOCPLINT->towns.size() > index)
|
if (LOCPLINT->localState->ownedTowns.size() > index)
|
||||||
return std::make_shared<CTownItem>(this, LOCPLINT->towns[index]);
|
return std::make_shared<CTownItem>(this, LOCPLINT->localState->ownedTowns[index]);
|
||||||
return std::make_shared<CAnimImage>("ITPA", 0);
|
return std::make_shared<CAnimImage>("ITPA", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,20 +313,20 @@ std::string CTownList::CTownItem::getHoverText()
|
|||||||
}
|
}
|
||||||
|
|
||||||
CTownList::CTownList(int size, Point position, std::string btnUp, std::string btnDown):
|
CTownList::CTownList(int size, Point position, std::string btnUp, std::string btnDown):
|
||||||
CList(size, position, btnUp, btnDown, LOCPLINT->towns.size(), 306, 307, std::bind(&CTownList::createTownItem, this, _1))
|
CList(size, position, btnUp, btnDown, LOCPLINT->localState->ownedTowns.size(), 306, 307, std::bind(&CTownList::createTownItem, this, _1))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTownList::select(const CGTownInstance * town)
|
void CTownList::select(const CGTownInstance * town)
|
||||||
{
|
{
|
||||||
selectIndex(vstd::find_pos(LOCPLINT->towns, town));
|
selectIndex(vstd::find_pos(LOCPLINT->localState->ownedTowns, town));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CTownList::update(const CGTownInstance *)
|
void CTownList::update(const CGTownInstance *)
|
||||||
{
|
{
|
||||||
//simplest solution for now: reset list and restore selection
|
//simplest solution for now: reset list and restore selection
|
||||||
|
|
||||||
listBox->resize(LOCPLINT->towns.size());
|
listBox->resize(LOCPLINT->localState->ownedTowns.size());
|
||||||
if (adventureInt->getCurrentTown())
|
if (adventureInt->getCurrentTown())
|
||||||
select(adventureInt->getCurrentTown());
|
select(adventureInt->getCurrentTown());
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include "../../CCallback.h"
|
#include "../../CCallback.h"
|
||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
#include "../adventureMap/CAdventureMapInterface.h"
|
#include "../adventureMap/CAdventureMapInterface.h"
|
||||||
|
|
||||||
#include "../../lib/CPathfinder.h"
|
#include "../../lib/CPathfinder.h"
|
||||||
@@ -211,10 +212,10 @@ const CGPath * MapRendererAdventureContext::currentPath() const
|
|||||||
if(!hero)
|
if(!hero)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if(!LOCPLINT->paths.hasPath(hero))
|
if(!LOCPLINT->localState->hasPath(hero))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
return &LOCPLINT->paths.getPath(hero);
|
return &LOCPLINT->localState->getPath(hero);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MapRendererAdventureContext::objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const
|
size_t MapRendererAdventureContext::objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CMusicHandler.h"
|
#include "../CMusicHandler.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../widgets/MiscWidgets.h"
|
#include "../widgets/MiscWidgets.h"
|
||||||
#include "../widgets/CComponent.h"
|
#include "../widgets/CComponent.h"
|
||||||
@@ -1241,13 +1242,13 @@ void CCastleInterface::castleTeleport(int where)
|
|||||||
const CGTownInstance * dest = LOCPLINT->cb->getTown(ObjectInstanceID(where));
|
const CGTownInstance * dest = LOCPLINT->cb->getTown(ObjectInstanceID(where));
|
||||||
adventureInt->setSelection(town->visitingHero);//according to assert(ho == adventureInt->selection) in the eraseCurrentPathOf
|
adventureInt->setSelection(town->visitingHero);//according to assert(ho == adventureInt->selection) in the eraseCurrentPathOf
|
||||||
LOCPLINT->cb->teleportHero(town->visitingHero, dest);
|
LOCPLINT->cb->teleportHero(town->visitingHero, dest);
|
||||||
LOCPLINT->paths.erasePath(town->visitingHero);
|
LOCPLINT->localState->erasePath(town->visitingHero);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCastleInterface::townChange()
|
void CCastleInterface::townChange()
|
||||||
{
|
{
|
||||||
//TODO: do not recreate window
|
//TODO: do not recreate window
|
||||||
const CGTownInstance * dest = LOCPLINT->towns[townlist->getSelectedIndex()];
|
const CGTownInstance * dest = LOCPLINT->localState->ownedTowns[townlist->getSelectedIndex()];
|
||||||
const CGTownInstance * town = this->town;// "this" is going to be deleted
|
const CGTownInstance * town = this->town;// "this" is going to be deleted
|
||||||
if ( dest == town )
|
if ( dest == town )
|
||||||
return;
|
return;
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../PlayerLocalState.h"
|
||||||
#include "../CVideoHandler.h"
|
#include "../CVideoHandler.h"
|
||||||
|
|
||||||
#include "../battle/BattleInterface.h"
|
#include "../battle/BattleInterface.h"
|
||||||
@@ -221,9 +222,9 @@ CSpellWindow::CSpellWindow(const CGHeroInstance * _myHero, CPlayerInterface * _m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedTab = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap;
|
selectedTab = battleSpellsOnly ? myInt->localState->spellbookSettings.spellbookLastTabBattle : myInt->localState->spellbookSettings.spellbookLastTabAdvmap;
|
||||||
schoolTab->setFrame(selectedTab, 0);
|
schoolTab->setFrame(selectedTab, 0);
|
||||||
int cp = battleSpellsOnly ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap;
|
int cp = battleSpellsOnly ? myInt->localState->spellbookSettings.spellbookLastPageBattle : myInt->localState->spellbookSettings.spellbokLastPageAdvmap;
|
||||||
// spellbook last page battle index is not reset after battle, so this needs to stay here
|
// spellbook last page battle index is not reset after battle, so this needs to stay here
|
||||||
vstd::abetween(cp, 0, std::max(0, pagesWithinCurrentTab() - 1));
|
vstd::abetween(cp, 0, std::max(0, pagesWithinCurrentTab() - 1));
|
||||||
setCurrentPage(cp);
|
setCurrentPage(cp);
|
||||||
@@ -237,8 +238,8 @@ CSpellWindow::~CSpellWindow()
|
|||||||
|
|
||||||
void CSpellWindow::fexitb()
|
void CSpellWindow::fexitb()
|
||||||
{
|
{
|
||||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap) = selectedTab;
|
(myInt->battleInt ? myInt->localState->spellbookSettings.spellbookLastTabBattle : myInt->localState->spellbookSettings.spellbookLastTabAdvmap) = selectedTab;
|
||||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap) = currentPage;
|
(myInt->battleInt ? myInt->localState->spellbookSettings.spellbookLastPageBattle : myInt->localState->spellbookSettings.spellbokLastPageAdvmap) = currentPage;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
@@ -556,8 +557,8 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
|||||||
|
|
||||||
auto guard = vstd::makeScopeGuard([this]()
|
auto guard = vstd::makeScopeGuard([this]()
|
||||||
{
|
{
|
||||||
owner->myInt->spellbookSettings.spellbookLastTabAdvmap = owner->selectedTab;
|
owner->myInt->localState->spellbookSettings.spellbookLastTabAdvmap = owner->selectedTab;
|
||||||
owner->myInt->spellbookSettings.spellbokLastPageAdvmap = owner->currentPage;
|
owner->myInt->localState->spellbookSettings.spellbokLastPageAdvmap = owner->currentPage;
|
||||||
});
|
});
|
||||||
|
|
||||||
if(mySpell->getTargetType() == spells::AimType::LOCATION)
|
if(mySpell->getTargetType() == spells::AimType::LOCATION)
|
||||||
|
Reference in New Issue
Block a user