mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-29 21:56:54 +02:00
Moved player-specific heroes & towns information to new class
This commit is contained in:
parent
4a169972f0
commit
f6d480cbb2
@ -110,6 +110,7 @@ set(client_SRCS
|
||||
CMT.cpp
|
||||
CMusicHandler.cpp
|
||||
CPlayerInterface.cpp
|
||||
PlayerLocalState.cpp
|
||||
CServerHandler.cpp
|
||||
CVideoHandler.cpp
|
||||
Client.cpp
|
||||
@ -238,6 +239,7 @@ set(client_HEADERS
|
||||
CMT.h
|
||||
CMusicHandler.h
|
||||
CPlayerInterface.h
|
||||
PlayerLocalState.h
|
||||
CServerHandler.h
|
||||
CVideoHandler.h
|
||||
Client.h
|
||||
|
@ -8,6 +8,7 @@
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "CPlayerInterface.h"
|
||||
|
||||
#include <vcmi/Artifact.h>
|
||||
|
||||
@ -25,12 +26,12 @@
|
||||
#include "gui/CursorHandler.h"
|
||||
#include "windows/CKingdomInterface.h"
|
||||
#include "CGameInfo.h"
|
||||
#include "PlayerLocalState.h"
|
||||
#include "CMT.h"
|
||||
#include "windows/CHeroWindow.h"
|
||||
#include "windows/CCreatureWindow.h"
|
||||
#include "windows/CQuestLog.h"
|
||||
#include "windows/CPuzzleWindow.h"
|
||||
#include "CPlayerInterface.h"
|
||||
#include "widgets/CComponent.h"
|
||||
#include "widgets/Buttons.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):
|
||||
paths(*this)
|
||||
localState(std::make_unique<PlayerLocalState>(*this))
|
||||
{
|
||||
logGlobal->trace("\tHuman player interface for player %s being constructed", Player.getStr());
|
||||
destinationTeleport = ObjectInstanceID();
|
||||
@ -401,27 +314,27 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
||||
};
|
||||
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(details.result == TryMoveHero::TELEPORTATION)
|
||||
{
|
||||
if(paths.hasPath(hero))
|
||||
if(localState->hasPath(hero))
|
||||
{
|
||||
assert(paths.getPath(hero).nodes.size() >= 2);
|
||||
auto nodesIt = paths.getPath(hero).nodes.end() - 1;
|
||||
assert(localState->getPath(hero).nodes.size() >= 2);
|
||||
auto nodesIt = localState->getPath(hero).nodes.end() - 1;
|
||||
|
||||
if((nodesIt)->coord == hero->convertToVisitablePos(details.start)
|
||||
&& (nodesIt - 1)->coord == hero->convertToVisitablePos(details.end))
|
||||
{
|
||||
//path was between entrance and exit of teleport -> OK, erase node as usual
|
||||
paths.removeLastNode(hero);
|
||||
localState->removeLastNode(hero);
|
||||
}
|
||||
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
|
||||
|| 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
|
||||
paths.removeLastNode(hero);
|
||||
localState->removeLastNode(hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -492,9 +405,9 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
LOG_TRACE_PARAMS(logGlobal, "Hero %s killed handler for player %s", hero->getNameTranslated() % playerID);
|
||||
wanderingHeroes -= hero;
|
||||
localState->wanderingHeroes -= hero;
|
||||
adventureInt->onHeroChanged(hero);
|
||||
paths.erasePath(hero);
|
||||
localState->erasePath(hero);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
wanderingHeroes.push_back(hero);
|
||||
localState->wanderingHeroes.push_back(hero);
|
||||
adventureInt->onHeroChanged(hero);
|
||||
}
|
||||
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->tempOwner == playerID && vstd::contains(wanderingHeroes,town->garrisonHero)) // our hero
|
||||
wanderingHeroes -= town->garrisonHero;
|
||||
if (town->garrisonHero->tempOwner == playerID && vstd::contains(localState->wanderingHeroes,town->garrisonHero)) // our hero
|
||||
localState->wanderingHeroes -= town->garrisonHero;
|
||||
}
|
||||
|
||||
if (town->visitingHero) //hero leaves garrison
|
||||
{
|
||||
if (town->visitingHero->tempOwner == playerID && !vstd::contains(wanderingHeroes,town->visitingHero)) // our hero
|
||||
wanderingHeroes.push_back(town->visitingHero);
|
||||
if (town->visitingHero->tempOwner == playerID && !vstd::contains(localState->wanderingHeroes,town->visitingHero)) // our hero
|
||||
localState->wanderingHeroes.push_back(town->visitingHero);
|
||||
}
|
||||
adventureInt->onHeroChanged(nullptr);
|
||||
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)
|
||||
{
|
||||
//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 )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
serializeTempl(h,version);
|
||||
h & localState;
|
||||
}
|
||||
|
||||
void CPlayerInterface::loadGame( BinaryDeserializer & h, const int version )
|
||||
{
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
serializeTempl(h,version);
|
||||
h & localState;
|
||||
firstCall = -1;
|
||||
}
|
||||
|
||||
@ -1362,7 +1266,7 @@ void CPlayerInterface::showGarrisonDialog( const CArmedInstance *up, const CGHer
|
||||
EVENT_HANDLER_CALLED_BY_CLIENT;
|
||||
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();
|
||||
return;
|
||||
@ -1441,9 +1345,9 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
auto town = static_cast<const CGTownInstance *>(obj);
|
||||
|
||||
if(obj->tempOwner == playerID)
|
||||
towns.push_back(town);
|
||||
localState->ownedTowns.push_back(town);
|
||||
else
|
||||
towns -= obj;
|
||||
localState->ownedTowns -= obj;
|
||||
|
||||
adventureInt->onTownChanged(town);
|
||||
}
|
||||
@ -1452,24 +1356,24 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
|
||||
std::unordered_set<int3> upos(pos.begin(), pos.end());
|
||||
adventureInt->onMapTilesChanged(upos);
|
||||
|
||||
assert(cb->getTownsInfo().size() == towns.size());
|
||||
assert(cb->getTownsInfo().size() == localState->ownedTowns.size());
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::initializeHeroTownList()
|
||||
{
|
||||
if(!wanderingHeroes.size())
|
||||
if(!localState->wanderingHeroes.size())
|
||||
{
|
||||
std::vector<const CGHeroInstance*> heroes = cb->getHeroesInfo();
|
||||
for(auto & hero : heroes)
|
||||
{
|
||||
if(!hero->inTownGarrison)
|
||||
wanderingHeroes.push_back(hero);
|
||||
localState->wanderingHeroes.push_back(hero);
|
||||
}
|
||||
}
|
||||
|
||||
if(!towns.size())
|
||||
towns = cb->getTownsInfo();
|
||||
if(!localState->ownedTowns.size())
|
||||
localState->ownedTowns = cb->getTownsInfo();
|
||||
|
||||
if(adventureInt)
|
||||
adventureInt->onHeroChanged(nullptr);
|
||||
@ -1736,7 +1640,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
||||
GH.popInts(1);
|
||||
|
||||
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
||||
paths.erasePath(caster);
|
||||
localState->erasePath(caster);
|
||||
|
||||
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
|
||||
auto castSoundPath = spell->getCastSound();
|
||||
@ -1972,12 +1876,6 @@ void CPlayerInterface::proposeLoadingGame()
|
||||
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()
|
||||
{
|
||||
if(duringMovement)
|
||||
|
@ -9,16 +9,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
#include "../lib/FunctionList.h"
|
||||
#include "../lib/CGameInterface.h"
|
||||
#include "../lib/NetPacksBase.h"
|
||||
#include "gui/CIntObject.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define sprintf_s snprintf
|
||||
#endif
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class Artifact;
|
||||
@ -51,43 +45,16 @@ class ClickableR;
|
||||
class Hoverable;
|
||||
class KeyInterested;
|
||||
class MotionInterested;
|
||||
class PlayerLocalState;
|
||||
class TimeInterested;
|
||||
class IShowable;
|
||||
|
||||
struct SDL_Surface;
|
||||
union SDL_Event;
|
||||
|
||||
namespace boost
|
||||
{
|
||||
class 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
|
||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||
{
|
||||
@ -107,7 +74,7 @@ class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||
public: // TODO: make private
|
||||
std::shared_ptr<Environment> env;
|
||||
|
||||
HeroPathStorage paths;
|
||||
std::unique_ptr<PlayerLocalState> localState;
|
||||
|
||||
//minor interfaces
|
||||
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::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
|
||||
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.
|
||||
|
||||
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:
|
||||
void update() override;
|
||||
void initializeHeroTownList();
|
||||
@ -267,8 +215,6 @@ public:
|
||||
~CPlayerInterface();
|
||||
|
||||
private:
|
||||
template <typename Handler> void serializeTempl(Handler &h, const int version);
|
||||
|
||||
struct IgnoreEvents
|
||||
{
|
||||
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 "../windows/settings/SettingsMainWindow.h"
|
||||
#include "../CMT.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
@ -309,10 +310,10 @@ void CAdventureMapInterface::fsleepWake()
|
||||
void CAdventureMapInterface::fmoveHero()
|
||||
{
|
||||
const CGHeroInstance *h = getCurrentHero();
|
||||
if (!h || !LOCPLINT->paths.hasPath(h) || CGI->mh->hasOngoingAnimations())
|
||||
if (!h || !LOCPLINT->localState->hasPath(h) || CGI->mh->hasOngoingAnimations())
|
||||
return;
|
||||
|
||||
LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
|
||||
LOCPLINT->moveHero(h, LOCPLINT->localState->getPath(h));
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::fshowSpellbok()
|
||||
@ -338,10 +339,10 @@ void CAdventureMapInterface::fsystemOptions()
|
||||
void CAdventureMapInterface::fnextHero()
|
||||
{
|
||||
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)
|
||||
return;
|
||||
setSelection(LOCPLINT->wanderingHeroes[next], true);
|
||||
setSelection(LOCPLINT->localState->wanderingHeroes[next], true);
|
||||
}
|
||||
|
||||
void CAdventureMapInterface::fendTurn()
|
||||
@ -351,22 +352,22 @@ void CAdventureMapInterface::fendTurn()
|
||||
|
||||
if(settings["adventure"]["heroReminder"].Bool())
|
||||
{
|
||||
for(auto hero : LOCPLINT->wanderingHeroes)
|
||||
for(auto hero : LOCPLINT->localState->wanderingHeroes)
|
||||
{
|
||||
if(!isHeroSleeping(hero) && hero->movement > 0)
|
||||
{
|
||||
// Only show hero reminder if conditions met:
|
||||
// - There still movement points
|
||||
// - 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 );
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (LOCPLINT->wanderingHeroes.size() == 0)
|
||||
if (LOCPLINT->localState->wanderingHeroes.size() == 0)
|
||||
return -1;
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
@ -404,12 +405,12 @@ int CAdventureMapInterface::getNextHeroIndex(int startIndex)
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if (i >= LOCPLINT->wanderingHeroes.size())
|
||||
if (i >= LOCPLINT->localState->wanderingHeroes.size())
|
||||
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;
|
||||
else
|
||||
return -1;
|
||||
@ -422,14 +423,14 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
|
||||
if (h == getCurrentHero())
|
||||
infoBar->showSelection();
|
||||
|
||||
int start = vstd::find_pos(LOCPLINT->wanderingHeroes, h);
|
||||
int start = vstd::find_pos(LOCPLINT->localState->wanderingHeroes, h);
|
||||
int next = getNextHeroIndex(start);
|
||||
if (next < 0)
|
||||
{
|
||||
nextHero->block(true);
|
||||
return;
|
||||
}
|
||||
const CGHeroInstance *nextH = LOCPLINT->wanderingHeroes[next];
|
||||
const CGHeroInstance *nextH = LOCPLINT->localState->wanderingHeroes[next];
|
||||
bool noActiveHeroes = (next == start) && ((nextH->movement == 0) || isHeroSleeping(nextH));
|
||||
nextHero->block(noActiveHeroes);
|
||||
|
||||
@ -439,7 +440,7 @@ void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h)
|
||||
return;
|
||||
}
|
||||
//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));
|
||||
}
|
||||
@ -538,7 +539,7 @@ bool CAdventureMapInterface::isHeroSleeping(const CGHeroInstance *hero)
|
||||
if (!hero)
|
||||
return false;
|
||||
|
||||
return vstd::contains(LOCPLINT->sleepingHeroes, hero);
|
||||
return vstd::contains(LOCPLINT->localState->sleepingHeroes, 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)
|
||||
{
|
||||
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
|
||||
LOCPLINT->sleepingHeroes -= hero;
|
||||
LOCPLINT->localState->sleepingHeroes -= hero;
|
||||
|
||||
onHeroChanged(hero);
|
||||
}
|
||||
@ -654,7 +655,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate()
|
||||
|
||||
void CAdventureMapInterface::selectionChanged()
|
||||
{
|
||||
const CGTownInstance *to = LOCPLINT->towns[townList->getSelectedIndex()];
|
||||
const CGTownInstance *to = LOCPLINT->localState->ownedTowns[townList->getSelectedIndex()];
|
||||
if (currentSelection != to)
|
||||
setSelection(to);
|
||||
}
|
||||
@ -685,12 +686,12 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
|
||||
{
|
||||
//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);
|
||||
});
|
||||
|
||||
if(itr != LOCPLINT->towns.end())
|
||||
if(itr != LOCPLINT->localState->ownedTowns.end())
|
||||
LOCPLINT->showThievesGuildWindow(*itr);
|
||||
else
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("vcmi.adventureMap.noTownWithTavern"));
|
||||
@ -819,10 +820,10 @@ void CAdventureMapInterface::keyPressed(const SDL_Keycode & key)
|
||||
if (!CGI->mh->isInMap((dst)))
|
||||
return;
|
||||
|
||||
if ( !LOCPLINT->paths.setPath(h, dst))
|
||||
if ( !LOCPLINT->localState->setPath(h, dst))
|
||||
return;
|
||||
|
||||
const CGPath & path = LOCPLINT->paths.getPath(h);
|
||||
const CGPath & path = LOCPLINT->localState->getPath(h);
|
||||
|
||||
if (path.nodes.size() > 2)
|
||||
onHeroChanged(h);
|
||||
@ -885,7 +886,7 @@ void CAdventureMapInterface::setSelection(const CArmedInstance *sel, bool center
|
||||
heroList->select(hero);
|
||||
townList->select(nullptr);
|
||||
|
||||
LOCPLINT->paths.verifyPath(hero);
|
||||
LOCPLINT->localState->verifyPath(hero);
|
||||
|
||||
updateSleepWake(hero);
|
||||
onHeroChanged(hero);
|
||||
@ -978,9 +979,9 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
|
||||
const CGHeroInstance * heroToSelect = nullptr;
|
||||
|
||||
// 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;
|
||||
break;
|
||||
@ -994,10 +995,10 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID)
|
||||
{
|
||||
setSelection(heroToSelect, centerView);
|
||||
}
|
||||
else if (LOCPLINT->towns.size())
|
||||
setSelection(LOCPLINT->towns.front(), centerView);
|
||||
else if (LOCPLINT->localState->ownedTowns.size())
|
||||
setSelection(LOCPLINT->localState->ownedTowns.front(), centerView);
|
||||
else
|
||||
setSelection(LOCPLINT->wanderingHeroes.front());
|
||||
setSelection(LOCPLINT->localState->wanderingHeroes.front());
|
||||
|
||||
//show new day animation and sound on infobar
|
||||
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
|
||||
{
|
||||
if(LOCPLINT->paths.hasPath(currentHero) &&
|
||||
LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
|
||||
if(LOCPLINT->localState->hasPath(currentHero) &&
|
||||
LOCPLINT->localState->getPath(currentHero).endPos() == mapPos)//we'll be moving
|
||||
{
|
||||
if(!CGI->mh->hasOngoingAnimations())
|
||||
LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
|
||||
LOCPLINT->moveHero(currentHero, LOCPLINT->localState->getPath(currentHero));
|
||||
return;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
|
||||
#include "../../CCallback.h"
|
||||
@ -114,7 +115,7 @@ CInfoBar::VisibleGameStatusInfo::VisibleGameStatusInfo()
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
|
||||
//get amount of halls of each level
|
||||
std::vector<int> halls(4, 0);
|
||||
for(auto town : LOCPLINT->towns)
|
||||
for(auto town : LOCPLINT->localState->ownedTowns)
|
||||
{
|
||||
int hallLevel = town->hallLevel();
|
||||
//negative value means no village hall, unlikely but possible
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "../windows/InfoWindows.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
|
||||
#include "../../lib/CGeneralTextHandler.h"
|
||||
@ -224,19 +225,19 @@ std::string CHeroList::CHeroItem::getHoverText()
|
||||
|
||||
std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index)
|
||||
{
|
||||
if (LOCPLINT->wanderingHeroes.size() > index)
|
||||
return std::make_shared<CHeroItem>(this, LOCPLINT->wanderingHeroes[index]);
|
||||
if (LOCPLINT->localState->wanderingHeroes.size() > index)
|
||||
return std::make_shared<CHeroItem>(this, LOCPLINT->localState->wanderingHeroes[index]);
|
||||
return std::make_shared<CEmptyHeroItem>();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
selectIndex(vstd::find_pos(LOCPLINT->wanderingHeroes, hero));
|
||||
selectIndex(vstd::find_pos(LOCPLINT->localState->wanderingHeroes, hero));
|
||||
}
|
||||
|
||||
void CHeroList::update(const CGHeroInstance * hero)
|
||||
@ -245,7 +246,7 @@ void CHeroList::update(const CGHeroInstance * hero)
|
||||
for(auto & elem : listBox->getItems())
|
||||
{
|
||||
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();
|
||||
return;
|
||||
@ -253,7 +254,7 @@ void CHeroList::update(const CGHeroInstance * hero)
|
||||
}
|
||||
//simplest solution for now: reset list and restore selection
|
||||
|
||||
listBox->resize(LOCPLINT->wanderingHeroes.size());
|
||||
listBox->resize(LOCPLINT->localState->wanderingHeroes.size());
|
||||
if (adventureInt->getCurrentHero())
|
||||
select(adventureInt->getCurrentHero());
|
||||
|
||||
@ -262,8 +263,8 @@ void CHeroList::update(const CGHeroInstance * hero)
|
||||
|
||||
std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index)
|
||||
{
|
||||
if (LOCPLINT->towns.size() > index)
|
||||
return std::make_shared<CTownItem>(this, LOCPLINT->towns[index]);
|
||||
if (LOCPLINT->localState->ownedTowns.size() > index)
|
||||
return std::make_shared<CTownItem>(this, LOCPLINT->localState->ownedTowns[index]);
|
||||
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):
|
||||
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)
|
||||
{
|
||||
selectIndex(vstd::find_pos(LOCPLINT->towns, town));
|
||||
selectIndex(vstd::find_pos(LOCPLINT->localState->ownedTowns, town));
|
||||
}
|
||||
|
||||
void CTownList::update(const CGTownInstance *)
|
||||
{
|
||||
//simplest solution for now: reset list and restore selection
|
||||
|
||||
listBox->resize(LOCPLINT->towns.size());
|
||||
listBox->resize(LOCPLINT->localState->ownedTowns.size());
|
||||
if (adventureInt->getCurrentTown())
|
||||
select(adventureInt->getCurrentTown());
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "../../CCallback.h"
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../adventureMap/CAdventureMapInterface.h"
|
||||
|
||||
#include "../../lib/CPathfinder.h"
|
||||
@ -211,10 +212,10 @@ const CGPath * MapRendererAdventureContext::currentPath() const
|
||||
if(!hero)
|
||||
return nullptr;
|
||||
|
||||
if(!LOCPLINT->paths.hasPath(hero))
|
||||
if(!LOCPLINT->localState->hasPath(hero))
|
||||
return nullptr;
|
||||
|
||||
return &LOCPLINT->paths.getPath(hero);
|
||||
return &LOCPLINT->localState->getPath(hero);
|
||||
}
|
||||
|
||||
size_t MapRendererAdventureContext::objectImageIndex(ObjectInstanceID objectID, size_t groupSize) const
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CMusicHandler.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../widgets/MiscWidgets.h"
|
||||
#include "../widgets/CComponent.h"
|
||||
@ -1241,13 +1242,13 @@ void CCastleInterface::castleTeleport(int where)
|
||||
const CGTownInstance * dest = LOCPLINT->cb->getTown(ObjectInstanceID(where));
|
||||
adventureInt->setSelection(town->visitingHero);//according to assert(ho == adventureInt->selection) in the eraseCurrentPathOf
|
||||
LOCPLINT->cb->teleportHero(town->visitingHero, dest);
|
||||
LOCPLINT->paths.erasePath(town->visitingHero);
|
||||
LOCPLINT->localState->erasePath(town->visitingHero);
|
||||
}
|
||||
|
||||
void CCastleInterface::townChange()
|
||||
{
|
||||
//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
|
||||
if ( dest == town )
|
||||
return;
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../CVideoHandler.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);
|
||||
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
|
||||
vstd::abetween(cp, 0, std::max(0, pagesWithinCurrentTab() - 1));
|
||||
setCurrentPage(cp);
|
||||
@ -237,8 +238,8 @@ CSpellWindow::~CSpellWindow()
|
||||
|
||||
void CSpellWindow::fexitb()
|
||||
{
|
||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastTabBattle : myInt->spellbookSettings.spellbookLastTabAdvmap) = selectedTab;
|
||||
(myInt->battleInt ? myInt->spellbookSettings.spellbookLastPageBattle : myInt->spellbookSettings.spellbokLastPageAdvmap) = currentPage;
|
||||
(myInt->battleInt ? myInt->localState->spellbookSettings.spellbookLastTabBattle : myInt->localState->spellbookSettings.spellbookLastTabAdvmap) = selectedTab;
|
||||
(myInt->battleInt ? myInt->localState->spellbookSettings.spellbookLastPageBattle : myInt->localState->spellbookSettings.spellbokLastPageAdvmap) = currentPage;
|
||||
|
||||
close();
|
||||
}
|
||||
@ -556,8 +557,8 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
|
||||
auto guard = vstd::makeScopeGuard([this]()
|
||||
{
|
||||
owner->myInt->spellbookSettings.spellbookLastTabAdvmap = owner->selectedTab;
|
||||
owner->myInt->spellbookSettings.spellbokLastPageAdvmap = owner->currentPage;
|
||||
owner->myInt->localState->spellbookSettings.spellbookLastTabAdvmap = owner->selectedTab;
|
||||
owner->myInt->localState->spellbookSettings.spellbokLastPageAdvmap = owner->currentPage;
|
||||
});
|
||||
|
||||
if(mySpell->getTargetType() == spells::AimType::LOCATION)
|
||||
|
Loading…
x
Reference in New Issue
Block a user