mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Refactored access to hero paths in CPlayerInterface
This commit is contained in:
parent
bb6e1f7ee1
commit
600054e001
@ -120,7 +120,164 @@ struct HeroObjectRetriever : boost::static_visitor<const CGHeroInstance *>
|
||||
}
|
||||
};
|
||||
|
||||
CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
||||
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->updateMoveHero(h, false);
|
||||
|
||||
}
|
||||
|
||||
void HeroPathStorage::verifyPath(const CGHeroInstance *h)
|
||||
{
|
||||
if (!hasPath(h))
|
||||
return;
|
||||
setPath(h, getPath(h).endPos());
|
||||
}
|
||||
|
||||
//CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
|
||||
//{
|
||||
// if (vstd::contains(paths,h)) //hero has assigned path
|
||||
// {
|
||||
// CGPath &path = paths[h];
|
||||
// if (!path.nodes.size())
|
||||
// {
|
||||
// logGlobal->warn("Warning: empty path found...");
|
||||
// paths.erasePath(h);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// assert(h->visitablePos() == path.startPos());
|
||||
// //update the hero path in case of something has changed on map
|
||||
// if (LOCPLINT->cb->getPathsInfo(h)->getPath(path, path.endPos()))
|
||||
// return &path;
|
||||
//
|
||||
// paths.erase(h);
|
||||
// return nullptr;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
//
|
||||
//CGPath * CPlayerInterface::getPath(const CGHeroInstance * h)
|
||||
//{
|
||||
// if (vstd::contains(paths,h)) //hero has assigned path
|
||||
// return &paths[h];
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
|
||||
//removeLastNode
|
||||
|
||||
|
||||
//void HeroPathStorage::setPath(const CGHeroInstance *h, const CGPath & path)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//const CGPath & HeroPathStorage::getPath(const CGHeroInstance *h)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
//
|
||||
//void HeroPathStorage::verifyPath(const CGHeroInstance *h)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
|
||||
//void CPlayerInterface::eraseCurrentPathOf(const CGHeroInstance * ho, bool checkForExistanceOfPath)
|
||||
//{
|
||||
// if (checkForExistanceOfPath)
|
||||
// {
|
||||
// assert(vstd::contains(paths, ho));
|
||||
// }
|
||||
// else if (!vstd::contains(paths, ho))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// assert(ho == adventureInt->selection);
|
||||
//
|
||||
// paths.erasePath(ho);
|
||||
// adventureInt->updateMoveHero(ho, false);
|
||||
//}
|
||||
|
||||
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)
|
||||
{
|
||||
logGlobal->trace("\tHuman player interface for player %s being constructed", Player.getStr());
|
||||
destinationTeleport = ObjectInstanceID();
|
||||
@ -260,8 +417,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
||||
|
||||
bool directlyAttackingCreature =
|
||||
details.attackedFrom
|
||||
&& adventureInt->terrain->currentPath //in case if movement has been canceled in the meantime and path was already erased
|
||||
&& adventureInt->terrain->currentPath->nodes.size() == 3;//FIXME should be 2 but works nevertheless...
|
||||
&& paths.hasPath(hero) //in case if movement has been canceled in the meantime and path was already erased
|
||||
&& paths.getPath(hero).nodes.size() == 3;//FIXME should be 2 but works nevertheless...
|
||||
|
||||
if(makingTurn && hero->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
||||
{
|
||||
@ -271,21 +428,21 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
|
||||
|
||||
if(details.result == TryMoveHero::TELEPORTATION)
|
||||
{
|
||||
if(adventureInt->terrain->currentPath)
|
||||
if(paths.hasPath(hero))
|
||||
{
|
||||
assert(adventureInt->terrain->currentPath->nodes.size() >= 2);
|
||||
std::vector<CGPathNode>::const_iterator nodesIt = adventureInt->terrain->currentPath->nodes.end() - 1;
|
||||
assert(paths.getPath(hero).nodes.size() >= 2);
|
||||
auto nodesIt = paths.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
|
||||
removeLastNodeFromPath(hero);
|
||||
paths.removeLastNode(hero);
|
||||
}
|
||||
else
|
||||
{
|
||||
//teleport was not along current path, it'll now be invalid (hero is somewhere else)
|
||||
eraseCurrentPathOf(hero);
|
||||
paths.erasePath(hero);
|
||||
|
||||
}
|
||||
}
|
||||
@ -299,12 +456,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.
|
||||
{
|
||||
eraseCurrentPathOf(hero, false);
|
||||
paths.erasePath(hero);
|
||||
}
|
||||
else if(adventureInt->terrain->currentPath && hero->pos == details.end) //&& hero is moving
|
||||
else if(paths.hasPath(hero) && hero->pos == details.end) //&& hero is moving
|
||||
{
|
||||
if(details.start != details.end) //so we don't touch path when revisiting with spacebar
|
||||
removeLastNodeFromPath(hero);
|
||||
paths.removeLastNode(hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,8 +601,7 @@ void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
else if (adventureInt->selection == hero)
|
||||
adventureInt->selection = nullptr;
|
||||
|
||||
if (vstd::contains(paths, hero))
|
||||
paths.erase(hero);
|
||||
paths.erasePath(hero);
|
||||
}
|
||||
|
||||
void CPlayerInterface::heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start)
|
||||
@ -1247,7 +1403,7 @@ 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
|
||||
eraseCurrentPathOf(hero, false);
|
||||
paths.erasePath(hero);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1256,33 +1412,7 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
|
||||
h & wanderingHeroes;
|
||||
h & towns;
|
||||
h & sleepingHeroes;
|
||||
|
||||
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 (cb)
|
||||
for (auto &p : pathsMap)
|
||||
{
|
||||
CGPath path;
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
h & paths;
|
||||
h & spellbookSettings;
|
||||
}
|
||||
|
||||
@ -1299,7 +1429,7 @@ void CPlayerInterface::loadGame( BinaryDeserializer & h, const int version )
|
||||
firstCall = -1;
|
||||
}
|
||||
|
||||
void CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
void CPlayerInterface::moveHero( const CGHeroInstance *h, const CGPath& path )
|
||||
{
|
||||
LOG_TRACE(logGlobal);
|
||||
if (!LOCPLINT->makingTurn)
|
||||
@ -1330,7 +1460,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 && adventureInt->terrain->currentPath && adventureInt->terrain->currentPath->nodes.size() > 1) //to ignore calls on passing through garrisons
|
||||
if (stillMoveHero.get() == DURING_MOVE && paths.hasPath(down) && paths.getPath(down).nodes.size() > 1) //to ignore calls on passing through garrisons
|
||||
{
|
||||
onEnd();
|
||||
return;
|
||||
@ -1641,7 +1771,7 @@ void CPlayerInterface::initMovement( const TryMoveHero &details, const CGHeroIns
|
||||
bool heroVisibleHere = false;
|
||||
auto & tile = subArr[tileX][tileY];
|
||||
|
||||
for ( auto const & obj : tile.objects)
|
||||
for(const auto & obj : tile.objects)
|
||||
{
|
||||
if (obj.obj == ho)
|
||||
{
|
||||
@ -1856,7 +1986,7 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
||||
GH.popInts(1);
|
||||
|
||||
if(spellID == SpellID::FLY || spellID == SpellID::WATER_WALK)
|
||||
eraseCurrentPathOf(caster, false);
|
||||
paths.erasePath(caster);
|
||||
|
||||
const spells::Spell * spell = CGI->spells()->getByIndex(spellID);
|
||||
|
||||
@ -1872,54 +2002,6 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
||||
CCS->soundh->playSound(castSoundPath);
|
||||
}
|
||||
|
||||
void CPlayerInterface::eraseCurrentPathOf(const CGHeroInstance * ho, bool checkForExistanceOfPath)
|
||||
{
|
||||
if (checkForExistanceOfPath)
|
||||
{
|
||||
assert(vstd::contains(paths, ho));
|
||||
}
|
||||
else if (!vstd::contains(paths, ho))
|
||||
{
|
||||
return;
|
||||
}
|
||||
assert(ho == adventureInt->selection);
|
||||
|
||||
paths.erase(ho);
|
||||
adventureInt->terrain->currentPath = nullptr;
|
||||
adventureInt->updateMoveHero(ho, false);
|
||||
}
|
||||
|
||||
void CPlayerInterface::removeLastNodeFromPath(const CGHeroInstance *ho)
|
||||
{
|
||||
adventureInt->terrain->currentPath->nodes.erase(adventureInt->terrain->currentPath->nodes.end()-1);
|
||||
if (adventureInt->terrain->currentPath->nodes.size() < 2) //if it was the last one, remove entire path and path with only one tile is not a real path
|
||||
eraseCurrentPathOf(ho);
|
||||
}
|
||||
|
||||
CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
|
||||
{
|
||||
if (vstd::contains(paths,h)) //hero has assigned path
|
||||
{
|
||||
CGPath &path = paths[h];
|
||||
if (!path.nodes.size())
|
||||
{
|
||||
logGlobal->warn("Warning: empty path found...");
|
||||
paths.erase(h);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(h->visitablePos() == path.startPos());
|
||||
//update the hero path in case of something has changed on map
|
||||
if (LOCPLINT->cb->getPathsInfo(h)->getPath(path, path.endPos()))
|
||||
return &path;
|
||||
else
|
||||
paths.erase(h);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CPlayerInterface::acceptTurn()
|
||||
{
|
||||
if (settings["session"]["autoSkip"].Bool())
|
||||
|
@ -64,12 +64,39 @@ namespace boost
|
||||
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
|
||||
{
|
||||
const CArmedInstance * currentSelection;
|
||||
|
||||
public:
|
||||
HeroPathStorage paths;
|
||||
|
||||
std::shared_ptr<Environment> env;
|
||||
ObjectInstanceID destinationTeleport; //contain -1 or object id if teleportation
|
||||
int3 destinationTeleportPos;
|
||||
@ -94,7 +121,6 @@ public:
|
||||
|
||||
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::map<const CGHeroInstance *, CGPath> paths; //maps hero => selected path in adventure map
|
||||
std::vector<const CGHeroInstance *> sleepingHeroes; //if hero is in here, he's sleeping
|
||||
|
||||
//During battle is quick combat mode is used
|
||||
@ -229,14 +255,11 @@ public:
|
||||
void showYesNoDialog(const std::string &text, CFunctionList<void()> onYes, CFunctionList<void()> onNo, const std::vector<std::shared_ptr<CComponent>> & components = std::vector<std::shared_ptr<CComponent>>());
|
||||
|
||||
void stopMovement();
|
||||
void moveHero(const CGHeroInstance *h, CGPath path);
|
||||
void moveHero(const CGHeroInstance *h, const CGPath& path);
|
||||
void initMovement(const TryMoveHero &details, const CGHeroInstance * ho, const int3 &hp );//initializing objects and performing first step of move
|
||||
void movementPxStep( const TryMoveHero &details, int i, const int3 &hp, const CGHeroInstance * ho );//performing step of movement
|
||||
void finishMovement( const TryMoveHero &details, const int3 &hp, const CGHeroInstance * ho ); //finish movement
|
||||
void eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath = true );
|
||||
|
||||
void removeLastNodeFromPath(const CGHeroInstance *ho);
|
||||
CGPath *getAndVerifyPath( const CGHeroInstance * h );
|
||||
void acceptTurn(); //used during hot seat after your turn message is close
|
||||
void tryDiggging(const CGHeroInstance *h);
|
||||
void showShipyardDialogOrProblemPopup(const IShipyard *obj); //obj may be town or shipyard;
|
||||
|
@ -324,10 +324,10 @@ void CAdvMapInt::fsleepWake()
|
||||
void CAdvMapInt::fmoveHero()
|
||||
{
|
||||
const CGHeroInstance *h = curHero();
|
||||
if (!h || !terrain->currentPath || !CGI->mh->canStartHeroMovement())
|
||||
if (!h || !LOCPLINT->paths.hasPath(h) || !CGI->mh->canStartHeroMovement())
|
||||
return;
|
||||
|
||||
LOCPLINT->moveHero(h, *terrain->currentPath);
|
||||
LOCPLINT->moveHero(h, LOCPLINT->paths.getPath(h));
|
||||
}
|
||||
|
||||
void CAdvMapInt::fshowSpellbok()
|
||||
@ -373,10 +373,18 @@ void CAdvMapInt::fendTurn()
|
||||
// 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
|
||||
auto path = LOCPLINT->getAndVerifyPath(hero);
|
||||
if(!path || path->nodes.size() < 2 || !path->nodes[path->nodes.size()-2].turns)
|
||||
LOCPLINT->paths.verifyPath(hero);
|
||||
|
||||
if(!LOCPLINT->paths.hasPath(hero))
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::bind(&CAdvMapInt::endingTurn, this), nullptr);
|
||||
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdvMapInt::endingTurn, this), nullptr );
|
||||
return;
|
||||
}
|
||||
|
||||
auto path = LOCPLINT->paths.getPath(hero);
|
||||
if (path.nodes.size() < 2 || path.nodes[path.nodes.size() - 2].turns)
|
||||
{
|
||||
LOCPLINT->showYesNoDialog( CGI->generaltexth->allTexts[55], std::bind(&CAdvMapInt::endingTurn, this), nullptr );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -405,7 +413,7 @@ void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath)
|
||||
}
|
||||
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
|
||||
if(boost::logic::indeterminate(hasPath))
|
||||
hasPath = LOCPLINT->paths[h].nodes.size() ? true : false;
|
||||
hasPath = LOCPLINT->paths.hasPath(h);
|
||||
|
||||
moveHero->block(!(bool)hasPath || (h->movement == 0));
|
||||
}
|
||||
@ -865,14 +873,15 @@ void CAdvMapInt::keyPressed(const SDL_Keycode & key)
|
||||
return;
|
||||
}
|
||||
|
||||
CGPath &path = LOCPLINT->paths[h];
|
||||
terrain->currentPath = &path;
|
||||
int3 dst = h->visitablePos() + int3(direction->x, direction->y, 0);
|
||||
if(dst != verifyPos(dst) || !LOCPLINT->cb->getPathsInfo(h)->getPath(path, dst))
|
||||
{
|
||||
terrain->currentPath = nullptr;
|
||||
|
||||
if(dst != verifyPos(dst))
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !LOCPLINT->paths.setPath(h, dst))
|
||||
return;
|
||||
|
||||
const CGPath & path = LOCPLINT->paths.getPath(h);
|
||||
|
||||
if (path.nodes.size() > 2)
|
||||
updateMoveHero(h);
|
||||
@ -938,7 +947,6 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
|
||||
if(centerView)
|
||||
centerOn(sel);
|
||||
|
||||
terrain->currentPath = nullptr;
|
||||
if(sel->ID==Obj::TOWN)
|
||||
{
|
||||
auto town = dynamic_cast<const CGTownInstance*>(sel);
|
||||
@ -959,8 +967,6 @@ void CAdvMapInt::select(const CArmedInstance *sel, bool centerView)
|
||||
heroList->select(hero);
|
||||
townList->select(nullptr);
|
||||
|
||||
terrain->currentPath = LOCPLINT->getAndVerifyPath(hero);
|
||||
|
||||
updateSleepWake(hero);
|
||||
updateMoveHero(hero);
|
||||
updateSpellbook(hero);
|
||||
@ -1155,7 +1161,6 @@ void CAdvMapInt::tileLClicked(const int3 &mapPos)
|
||||
bool isHero = false;
|
||||
if(selection->ID != Obj::HERO) //hero is not selected (presumably town)
|
||||
{
|
||||
assert(!terrain->currentPath); //path can be active only when hero is selected
|
||||
if(selection == topBlocking) //selected town clicked
|
||||
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
|
||||
else if(canSelect)
|
||||
@ -1178,25 +1183,16 @@ void CAdvMapInt::tileLClicked(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(terrain->currentPath && terrain->currentPath->endPos() == mapPos)//we'll be moving
|
||||
if(LOCPLINT->paths.hasPath(currentHero) &&
|
||||
LOCPLINT->paths.getPath(currentHero).endPos() == mapPos)//we'll be moving
|
||||
{
|
||||
if(CGI->mh->canStartHeroMovement())
|
||||
LOCPLINT->moveHero(currentHero, *terrain->currentPath);
|
||||
LOCPLINT->moveHero(currentHero, LOCPLINT->paths.getPath(currentHero));
|
||||
return;
|
||||
}
|
||||
else //remove old path and find a new one if we clicked on accessible tile
|
||||
{
|
||||
CGPath &path = LOCPLINT->paths[currentHero];
|
||||
CGPath newpath;
|
||||
bool gotPath = LOCPLINT->cb->getPathsInfo(currentHero)->getPath(newpath, mapPos); //try getting path, erase if failed
|
||||
if(gotPath && newpath.nodes.size())
|
||||
path = newpath;
|
||||
|
||||
if(path.nodes.size())
|
||||
terrain->currentPath = &path;
|
||||
else
|
||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||
|
||||
LOCPLINT->paths.setPath(currentHero, mapPos);
|
||||
updateMoveHero(currentHero);
|
||||
}
|
||||
}
|
||||
|
@ -35,11 +35,11 @@
|
||||
#define ADVOPT (conf.go()->ac)
|
||||
|
||||
CTerrainRect::CTerrainRect()
|
||||
: fadeSurface(nullptr),
|
||||
lastRedrawStatus(EMapAnimRedrawStatus::OK),
|
||||
fadeAnim(std::make_shared<CFadeAnimation>()),
|
||||
curHoveredTile(-1,-1,-1),
|
||||
currentPath(nullptr)
|
||||
: fadeSurface(nullptr)
|
||||
, lastRedrawStatus(EMapAnimRedrawStatus::OK)
|
||||
, fadeAnim(std::make_shared<CFadeAnimation>())
|
||||
, curHoveredTile(-1, -1, -1)
|
||||
, isSwiping(false)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE;
|
||||
|
||||
@ -90,13 +90,12 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
{
|
||||
if(down == false)
|
||||
return;
|
||||
#if defined(VCMI_MOBILE)
|
||||
}
|
||||
#endif
|
||||
|
||||
int3 mp = whichTileIsIt();
|
||||
if(mp.x < 0 || mp.y < 0 || mp.x >= LOCPLINT->cb->getMapSize().x || mp.y >= LOCPLINT->cb->getMapSize().y)
|
||||
return;
|
||||
@ -146,8 +145,8 @@ void CTerrainRect::handleSwipeMove(const Point & cursorPosition)
|
||||
if(!isSwiping)
|
||||
{
|
||||
// try to distinguish if this touch was meant to be a swipe or just fat-fingering press
|
||||
if(abs(cursorPosition.x - swipeInitialRealPos.x) > SwipeTouchSlop ||
|
||||
abs(cursorPosition.y - swipeInitialRealPos.y) > SwipeTouchSlop)
|
||||
if(std::abs(cursorPosition.x - swipeInitialRealPos.x) > SwipeTouchSlop ||
|
||||
std::abs(cursorPosition.y - swipeInitialRealPos.y) > SwipeTouchSlop)
|
||||
{
|
||||
isSwiping = true;
|
||||
}
|
||||
@ -169,7 +168,8 @@ bool CTerrainRect::handleSwipeStateChange(bool btnPressed)
|
||||
swipeInitialViewPos = getViewCenter();
|
||||
return true;
|
||||
}
|
||||
else if(isSwiping) // only accept this touch if it wasn't a swipe
|
||||
|
||||
if(isSwiping) // only accept this touch if it wasn't a swipe
|
||||
{
|
||||
isSwiping = false;
|
||||
return true;
|
||||
|
@ -51,7 +51,7 @@ class CTerrainRect : public CIntObject
|
||||
|
||||
bool needsAnimUpdate();
|
||||
public:
|
||||
CGPath * currentPath;
|
||||
//CGPath * currentPath;
|
||||
|
||||
CTerrainRect();
|
||||
~CTerrainRect();
|
||||
|
@ -365,7 +365,6 @@ private:
|
||||
int offsetY;
|
||||
|
||||
//terrain graphics
|
||||
private:
|
||||
//FIXME: unique_ptr should be enough, but fails to compile in MSVS 2013
|
||||
typedef std::map<std::string, std::array<std::shared_ptr<CAnimation>, 4>> TFlippedAnimations; //[type, rotation]
|
||||
typedef std::map<std::string, std::vector<std::array<std::shared_ptr<IImage>, 4>>> TFlippedCache;//[type, view type, rotation]
|
||||
|
@ -1219,7 +1219,7 @@ void CCastleInterface::castleTeleport(int where)
|
||||
const CGTownInstance * dest = LOCPLINT->cb->getTown(ObjectInstanceID(where));
|
||||
adventureInt->select(town->visitingHero);//according to assert(ho == adventureInt->selection) in the eraseCurrentPathOf
|
||||
LOCPLINT->cb->teleportHero(town->visitingHero, dest);
|
||||
LOCPLINT->eraseCurrentPathOf(town->visitingHero, false);
|
||||
LOCPLINT->paths.erasePath(town->visitingHero);
|
||||
}
|
||||
|
||||
void CCastleInterface::townChange()
|
||||
|
Loading…
Reference in New Issue
Block a user