mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
* Creatures now guard surrounding tiles.
This commit is contained in:
@@ -188,6 +188,11 @@ bool CCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest )
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int3 CCallback::guardingCreaturePosition (int3 pos) const
|
||||||
|
{
|
||||||
|
return gs->guardingCreaturePosition(pos);
|
||||||
|
}
|
||||||
|
|
||||||
int CCallback::howManyHeroes(bool includeGarrisoned) const
|
int CCallback::howManyHeroes(bool includeGarrisoned) const
|
||||||
{
|
{
|
||||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||||
|
@@ -278,6 +278,7 @@ public:
|
|||||||
void recalculatePaths(); //updates pathfinder info (should be called when moving hero is over)
|
void recalculatePaths(); //updates pathfinder info (should be called when moving hero is over)
|
||||||
bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
|
bool getHeroInfo(const CGObjectInstance *hero, InfoAboutHero &dest) const;
|
||||||
bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
|
bool getTownInfo(const CGObjectInstance *town, InfoAboutTown &dest) const;
|
||||||
|
int3 guardingCreaturePosition (int3 pos) const;
|
||||||
|
|
||||||
//battle
|
//battle
|
||||||
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
|
||||||
|
@@ -1854,6 +1854,8 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool guardingCreature = CGI->mh->map->isInTheMap(LOCPLINT->cb->guardingCreaturePosition(tile));
|
||||||
|
|
||||||
if(selection->ID == TOWNI_TYPE)
|
if(selection->ID == TOWNI_TYPE)
|
||||||
{
|
{
|
||||||
if(objAtTile && objAtTile->tempOwner == LOCPLINT->playerID)
|
if(objAtTile && objAtTile->tempOwner == LOCPLINT->playerID)
|
||||||
@@ -1917,13 +1919,6 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
|||||||
CGI->curh->changeGraphic(0, 3);
|
CGI->curh->changeGraphic(0, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(objAtTile->ID == 54) //monster
|
|
||||||
{
|
|
||||||
if(accessible)
|
|
||||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
|
||||||
else
|
|
||||||
CGI->curh->changeGraphic(0, 0);
|
|
||||||
}
|
|
||||||
else if(objAtTile->ID == 8) //boat
|
else if(objAtTile->ID == 8) //boat
|
||||||
{
|
{
|
||||||
if(accessible)
|
if(accessible)
|
||||||
@@ -1946,6 +1941,10 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
|||||||
else
|
else
|
||||||
CGI->curh->changeGraphic(0, 0);
|
CGI->curh->changeGraphic(0, 0);
|
||||||
}
|
}
|
||||||
|
else if (guardingCreature && accessible) //(objAtTile->ID == 54) //monster
|
||||||
|
{
|
||||||
|
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(accessible)
|
if(accessible)
|
||||||
@@ -1963,15 +1962,19 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
|||||||
{
|
{
|
||||||
if(accessible)
|
if(accessible)
|
||||||
{
|
{
|
||||||
if(pnode->land)
|
if (guardingCreature) {
|
||||||
{
|
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||||
if(LOCPLINT->cb->getTileInfo(h->getPosition(false))->tertype != TerrainTile::water)
|
} else {
|
||||||
CGI->curh->changeGraphic(0, 4 + turns*6);
|
if(pnode->land)
|
||||||
|
{
|
||||||
|
if(LOCPLINT->cb->getTileInfo(h->getPosition(false))->tertype != TerrainTile::water)
|
||||||
|
CGI->curh->changeGraphic(0, 4 + turns*6);
|
||||||
|
else
|
||||||
|
CGI->curh->changeGraphic(0, 7 + turns*6); //anchor
|
||||||
|
}
|
||||||
else
|
else
|
||||||
CGI->curh->changeGraphic(0, 7 + turns*6); //anchor
|
CGI->curh->changeGraphic(0, 6 + turns*6);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
CGI->curh->changeGraphic(0, 6 + turns*6);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
CGI->curh->changeGraphic(0, 0);
|
CGI->curh->changeGraphic(0, 0);
|
||||||
|
@@ -237,6 +237,9 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
adventureInt->minimap.draw(screen2);
|
adventureInt->minimap.draw(screen2);
|
||||||
adventureInt->heroList.draw(screen2);
|
adventureInt->heroList.draw(screen2);
|
||||||
|
|
||||||
|
bool directlyAttackingCreature =
|
||||||
|
CGI->mh->map->isInTheMap(details.attackedFrom)
|
||||||
|
&& adventureInt->terrain.currentPath->nodes.size() == 3;
|
||||||
|
|
||||||
if(makingTurn && ho->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
if(makingTurn && ho->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
|
||||||
{
|
{
|
||||||
@@ -248,7 +251,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
//TODO: smooth disappear / appear effect
|
//TODO: smooth disappear / appear effect
|
||||||
}
|
}
|
||||||
|
|
||||||
if (details.result != TryMoveHero::SUCCESS && details.result != TryMoveHero::FAILED) //hero didn't change tile but visit succeeded
|
if (details.result != TryMoveHero::SUCCESS && details.result != TryMoveHero::FAILED //hero didn't change tile but visit succeeded
|
||||||
|
|| directlyAttackingCreature) // or creature was attacked from endangering tile.
|
||||||
{
|
{
|
||||||
eraseCurrentPathOf(ho);
|
eraseCurrentPathOf(ho);
|
||||||
}
|
}
|
||||||
@@ -317,6 +321,18 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
|||||||
if(stillMoveHero.get() == WAITING_MOVE)
|
if(stillMoveHero.get() == WAITING_MOVE)
|
||||||
stillMoveHero.setn(DURING_MOVE);
|
stillMoveHero.setn(DURING_MOVE);
|
||||||
|
|
||||||
|
// Hero attacked creature directly, set direction to face it.
|
||||||
|
if (directlyAttackingCreature) {
|
||||||
|
// Get direction to attacker.
|
||||||
|
int3 posOffset = details.attackedFrom - details.end + int3(2, 1, 0);
|
||||||
|
const ui8 dirLookup[3][3] = {
|
||||||
|
1, 2, 3,
|
||||||
|
8, 0, 4,
|
||||||
|
7, 6, 5
|
||||||
|
};
|
||||||
|
// FIXME: Avoid const_cast, make moveDir mutable in some other way?
|
||||||
|
const_cast<CGHeroInstance *>(ho)->moveDir = dirLookup[posOffset.y][posOffset.x];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||||
{
|
{
|
||||||
@@ -976,6 +992,7 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
|||||||
stillMoveHero.data = STOP_MOVE;
|
stillMoveHero.data = STOP_MOVE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start a new sound for the hero movement or let the existing one carry on.
|
// Start a new sound for the hero movement or let the existing one carry on.
|
||||||
#if 0
|
#if 0
|
||||||
// TODO
|
// TODO
|
||||||
@@ -995,12 +1012,17 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
|||||||
stillMoveHero.data = WAITING_MOVE;
|
stillMoveHero.data = WAITING_MOVE;
|
||||||
|
|
||||||
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
|
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
|
||||||
|
bool guarded = CGI->mh->map->isInTheMap(cb->guardingCreaturePosition(endpos - int3(1, 0, 0)));
|
||||||
|
|
||||||
cb->moveHero(h,endpos);
|
cb->moveHero(h,endpos);
|
||||||
|
|
||||||
eventsM.unlock();
|
eventsM.unlock();
|
||||||
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
|
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
|
||||||
stillMoveHero.cond.wait(un);
|
stillMoveHero.cond.wait(un);
|
||||||
eventsM.lock();
|
eventsM.lock();
|
||||||
|
|
||||||
|
if (guarded) // Abort movement if a guard was fought.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGI->soundh->stopSound(sh);
|
CGI->soundh->stopSound(sh);
|
||||||
|
@@ -2124,6 +2124,12 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (map->isInTheMap(guardingCreaturePosition(int3(i, j, k)))
|
||||||
|
&& tinfo->blockingObjects.size() == 0)
|
||||||
|
{
|
||||||
|
// Monster close by; blocked visit for battle.
|
||||||
|
node.accessible = CGPathNode::BLOCKVIS;
|
||||||
|
}
|
||||||
|
|
||||||
if(onLand && !node.land) //hero can walk only on land and tile lays on the water
|
if(onLand && !node.land) //hero can walk only on land and tile lays on the water
|
||||||
{
|
{
|
||||||
@@ -2197,15 +2203,25 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
|
|||||||
remains = moveAtNextTile - cost;
|
remains = moveAtNextTile - cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(dp.turns==0xff //we haven't been here before
|
const bool guardedPosition = guardingCreaturePosition(cp->coord) != int3(-1, -1, -1);
|
||||||
|
const bool neighborIsGuard = guardingCreaturePosition(cp->coord) == dp.coord;
|
||||||
|
|
||||||
|
if((dp.turns==0xff //we haven't been here before
|
||||||
|| dp.turns > turnAtNextTile
|
|| dp.turns > turnAtNextTile
|
||||||
|| (dp.turns >= turnAtNextTile && dp.moveRemains < remains)) //this route is faster
|
|| (dp.turns >= turnAtNextTile && dp.moveRemains < remains)) //this route is faster
|
||||||
|
&& (!guardedPosition || neighborIsGuard)) // Can step into tile of guard
|
||||||
{
|
{
|
||||||
|
|
||||||
assert(&dp != cp->theNodeBefore); //two tiles can't point to each other
|
assert(&dp != cp->theNodeBefore); //two tiles can't point to each other
|
||||||
dp.moveRemains = remains;
|
dp.moveRemains = remains;
|
||||||
dp.turns = turnAtNextTile;
|
dp.turns = turnAtNextTile;
|
||||||
dp.theNodeBefore = cp;
|
dp.theNodeBefore = cp;
|
||||||
if(dp.accessible == CGPathNode::ACCESSIBLE)
|
|
||||||
|
const bool guardedNeighbor = guardingCreaturePosition(dp.coord) != int3(-1, -1, -1);
|
||||||
|
const bool positionIsGuard = guardingCreaturePosition(cp->coord) == cp->coord;
|
||||||
|
|
||||||
|
if (dp.accessible == CGPathNode::ACCESSIBLE
|
||||||
|
|| (guardedNeighbor && !positionIsGuard)) // Can step into a hostile tile once.
|
||||||
{
|
{
|
||||||
mq.push(&dp);
|
mq.push(&dp);
|
||||||
}
|
}
|
||||||
@@ -2214,6 +2230,51 @@ void CGameState::calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int
|
|||||||
} //queue loop
|
} //queue loop
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if the tile is guarded by a monster as well as the position
|
||||||
|
* of the monster that will attack on it.
|
||||||
|
*
|
||||||
|
* @return int3(-1, -1, -1) if the tile is unguarded, or the position of
|
||||||
|
* the monster guarding the tile.
|
||||||
|
*/
|
||||||
|
int3 CGameState::guardingCreaturePosition (int3 pos) const
|
||||||
|
{
|
||||||
|
// Give monster at position priority.
|
||||||
|
if (!map->isInTheMap(pos))
|
||||||
|
return int3(-1, -1, -1);
|
||||||
|
const TerrainTile &posTile = map->terrain[pos.x][pos.y][pos.z];
|
||||||
|
if (posTile.visitable) {
|
||||||
|
BOOST_FOREACH (CGObjectInstance* obj, posTile.visitableObjects) {
|
||||||
|
if (obj->ID == 54) { // Monster
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if there are any monsters adjacent.
|
||||||
|
pos -= int3(1, 1, 0); // Start with top left.
|
||||||
|
for (int dx = 0; dx < 3; dx++) {
|
||||||
|
for (int dy = 0; dy < 3; dy++) {
|
||||||
|
if (map->isInTheMap(pos)) {
|
||||||
|
TerrainTile &tile = map->terrain[pos.x][pos.y][pos.z];
|
||||||
|
if (tile.visitable) {
|
||||||
|
BOOST_FOREACH (CGObjectInstance* obj, tile.visitableObjects) {
|
||||||
|
if (obj->ID == 54) { // Monster
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pos.y++;
|
||||||
|
}
|
||||||
|
pos.y -= 3;
|
||||||
|
pos.x++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return int3(-1, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
bool CGameState::isVisible(int3 pos, int player)
|
bool CGameState::isVisible(int3 pos, int player)
|
||||||
{
|
{
|
||||||
if(player == 255) //neutral player
|
if(player == 255) //neutral player
|
||||||
|
@@ -400,6 +400,7 @@ public:
|
|||||||
bool checkForVisitableDir(const int3 & src, const TerrainTile *pom, const int3 & dst) const; //check if src tile is visitable from dst tile
|
bool checkForVisitableDir(const int3 & src, const TerrainTile *pom, const int3 & dst) const; //check if src tile is visitable from dst tile
|
||||||
bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
|
bool getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath &ret); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
|
||||||
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or NULL if path does not exists
|
void calculatePaths(const CGHeroInstance *hero, CPathsInfo &out, int3 src = int3(-1,-1,-1), int movement = -1); //calculates possible paths for hero, by default uses current hero position and movement left; returns pointer to newly allocated CPath or NULL if path does not exists
|
||||||
|
int3 guardingCreaturePosition (int3 pos) const;
|
||||||
int victoryCheck(ui8 player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else
|
int victoryCheck(ui8 player) const; //checks if given player is winner; -1 if std victory, 1 if special victory, 0 else
|
||||||
int lossCheck(ui8 player) const; //checks if given player is loser; -1 if std loss, 1 if special, 0 else
|
int lossCheck(ui8 player) const; //checks if given player is loser; -1 if std loss, 1 if special, 0 else
|
||||||
ui8 checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 if no winner
|
ui8 checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 if no winner
|
||||||
|
@@ -466,7 +466,7 @@ struct RemoveObject : public CPackForClient //500
|
|||||||
};
|
};
|
||||||
struct TryMoveHero : public CPackForClient //501
|
struct TryMoveHero : public CPackForClient //501
|
||||||
{
|
{
|
||||||
TryMoveHero(){type = 501;humanKnows=false;};
|
TryMoveHero(){type = 501;humanKnows=false; attackedFrom = int3(-1, -1, -1);};
|
||||||
void applyFirstCl(CClient *cl);
|
void applyFirstCl(CClient *cl);
|
||||||
void applyCl(CClient *cl);
|
void applyCl(CClient *cl);
|
||||||
void applyGs(CGameState *gs);
|
void applyGs(CGameState *gs);
|
||||||
@@ -480,12 +480,13 @@ struct TryMoveHero : public CPackForClient //501
|
|||||||
ui8 result; //uses EResult
|
ui8 result; //uses EResult
|
||||||
int3 start, end; //h3m format
|
int3 start, end; //h3m format
|
||||||
std::set<int3> fowRevealed; //revealed tiles
|
std::set<int3> fowRevealed; //revealed tiles
|
||||||
|
int3 attackedFrom; // Set when stepping into endangered tile.
|
||||||
|
|
||||||
bool humanKnows; //used locally during applying to client
|
bool humanKnows; //used locally during applying to client
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & id & result & start & end & movePoints & fowRevealed;
|
h & id & result & start & end & movePoints & fowRevealed & attackedFrom;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct SetGarrisons : public CPackForClient //502
|
struct SetGarrisons : public CPackForClient //502
|
||||||
|
@@ -342,8 +342,9 @@ void TryMoveHero::applyGs( CGameState *gs )
|
|||||||
CGHeroInstance *h = gs->getHero(id);
|
CGHeroInstance *h = gs->getHero(id);
|
||||||
h->movement = movePoints;
|
h->movement = movePoints;
|
||||||
|
|
||||||
if((result == SUCCESS || result == BLOCKING_VISIT || result == EMBARK || result == DISEMBARK) && start != end)
|
if((result == SUCCESS || result == BLOCKING_VISIT || result == EMBARK || result == DISEMBARK) && start != end) {
|
||||||
h->moveDir = getDir(start,end);
|
h->moveDir = getDir(start,end);
|
||||||
|
}
|
||||||
|
|
||||||
if(result == EMBARK) //hero enters boat at dest tile
|
if(result == EMBARK) //hero enters boat at dest tile
|
||||||
{
|
{
|
||||||
|
@@ -1562,7 +1562,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
|||||||
|
|
||||||
if(!gs->map->isInTheMap(hmpos))
|
if(!gs->map->isInTheMap(hmpos))
|
||||||
{
|
{
|
||||||
tlog1 << "Destination tile os out of the map!\n";
|
tlog1 << "Destination tile is outside the map!\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1663,13 +1663,16 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
|||||||
}
|
}
|
||||||
else //normal move
|
else //normal move
|
||||||
{
|
{
|
||||||
tmh.result = TryMoveHero::SUCCESS;
|
|
||||||
|
|
||||||
BOOST_FOREACH(CGObjectInstance *obj, gs->map->terrain[h->pos.x-1][h->pos.y][h->pos.z].visitableObjects)
|
BOOST_FOREACH(CGObjectInstance *obj, gs->map->terrain[h->pos.x-1][h->pos.y][h->pos.z].visitableObjects)
|
||||||
{
|
{
|
||||||
obj->onHeroLeave(h);
|
obj->onHeroLeave(h);
|
||||||
}
|
}
|
||||||
getTilesInRange(tmh.fowRevealed,h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner,1);
|
getTilesInRange(tmh.fowRevealed,h->getSightCenter()+(tmh.end-tmh.start),h->getSightRadious(),h->tempOwner,1);
|
||||||
|
|
||||||
|
int3 guardPos = gs->guardingCreaturePosition(int3(hmpos.x, hmpos.y, hmpos.z));
|
||||||
|
|
||||||
|
tmh.result = TryMoveHero::SUCCESS;
|
||||||
|
tmh.attackedFrom = guardPos;
|
||||||
sendAndApply(&tmh);
|
sendAndApply(&tmh);
|
||||||
tlog5 << "Moved to " <<tmh.end<<std::endl;
|
tlog5 << "Moved to " <<tmh.end<<std::endl;
|
||||||
|
|
||||||
@@ -1687,9 +1690,16 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
|||||||
// {
|
// {
|
||||||
// objectVisited(obj, h);
|
// objectVisited(obj, h);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// If a creature guards the tile, block visit.
|
||||||
|
if (gs->map->isInTheMap(guardPos)) {
|
||||||
|
const TerrainTile &guardTile = gs->map->terrain[guardPos.x][guardPos.y][guardPos.z];
|
||||||
|
objectVisited(guardTile.visitableObjects.back(), h);
|
||||||
|
}
|
||||||
|
|
||||||
|
tlog5 << "Movement end!\n";
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
tlog5 << "Movement end!\n";
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
else //instant move - teleportation
|
else //instant move - teleportation
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user