mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-17 00:07:41 +02:00
Do not allow visiting objects blocked by visit of another player
This commit is contained in:
@ -1086,8 +1086,18 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
|
|
||||||
const TerrainTile t = *getTile(hmpos);
|
const TerrainTile t = *getTile(hmpos);
|
||||||
const int3 guardPos = gs->guardingCreaturePosition(hmpos);
|
const int3 guardPos = gs->guardingCreaturePosition(hmpos);
|
||||||
|
CGObjectInstance * objectToVisit = nullptr;
|
||||||
|
CGObjectInstance * guardian = nullptr;
|
||||||
|
|
||||||
const bool embarking = !h->boat && !t.visitableObjects.empty() && t.visitableObjects.back()->ID == Obj::BOAT;
|
if (!t.visitableObjects.empty())
|
||||||
|
objectToVisit = t.visitableObjects.back();
|
||||||
|
|
||||||
|
if (isInTheMap(guardPos))
|
||||||
|
guardian = getTile(guardPos)->visitableObjects.back();
|
||||||
|
|
||||||
|
assert(guardian == nullptr || dynamic_cast<CGCreature*>(guardian) != nullptr);
|
||||||
|
|
||||||
|
const bool embarking = !h->boat && objectToVisit && objectToVisit->ID == Obj::BOAT;
|
||||||
const bool disembarking = h->boat
|
const bool disembarking = h->boat
|
||||||
&& t.terType->isLand()
|
&& t.terType->isLand()
|
||||||
&& (dst == h->pos
|
&& (dst == h->pos
|
||||||
@ -1110,7 +1120,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movementPointsRemaining());
|
const int cost = pathfinderHelper->getMovementCost(h->visitablePos(), hmpos, nullptr, nullptr, h->movementPointsRemaining());
|
||||||
|
|
||||||
const bool standAtObstacle = t.blocked && !t.visitable;
|
const bool standAtObstacle = t.blocked && !t.visitable;
|
||||||
const bool standAtWater = !h->boat && t.terType->isWater() && (t.visitableObjects.empty() || !t.visitableObjects.back()->isCoastVisitable());
|
const bool standAtWater = !h->boat && t.terType->isWater() && (objectToVisit || !objectToVisit->isCoastVisitable());
|
||||||
|
|
||||||
const auto complainRet = [&](const std::string & message)
|
const auto complainRet = [&](const std::string & message)
|
||||||
{
|
{
|
||||||
@ -1120,6 +1130,18 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (guardian && isVisitActiveForAny(guardian))
|
||||||
|
complainRet("Cannot move hero, destination monster is busy!");
|
||||||
|
|
||||||
|
if (objectToVisit && isVisitActiveForAny(objectToVisit))
|
||||||
|
complainRet("Cannot move hero, destination object is busy!");
|
||||||
|
|
||||||
|
if (objectToVisit &&
|
||||||
|
objectToVisit->getOwner().isValidPlayer() &&
|
||||||
|
getPlayerRelations(objectToVisit->getOwner(), h->getOwner()) == PlayerRelations::ENEMIES &&
|
||||||
|
!turnOrder->isContactAllowed(objectToVisit->getOwner(), h->getOwner()))
|
||||||
|
complainRet("Cannot move hero, destination player is busy!");
|
||||||
|
|
||||||
//it's a rock or blocked and not visitable tile
|
//it's a rock or blocked and not visitable tile
|
||||||
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
//OR hero is on land and dest is water and (there is not present only one object - boat)
|
||||||
if (!t.terType->isPassable() || (standAtObstacle && !canFly))
|
if (!t.terType->isPassable() || (standAtObstacle && !canFly))
|
||||||
@ -1179,8 +1201,7 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
}
|
}
|
||||||
else if (lookForGuards == CHECK_FOR_GUARDS && isInTheMap(guardPos))
|
else if (lookForGuards == CHECK_FOR_GUARDS && isInTheMap(guardPos))
|
||||||
{
|
{
|
||||||
const TerrainTile &guardTile = *gs->getTile(guardPos);
|
objectVisited(guardian, h);
|
||||||
objectVisited(guardTile.visitableObjects.back(), h);
|
|
||||||
|
|
||||||
moveQuery->visitDestAfterVictory = visitDest==VISIT_DEST;
|
moveQuery->visitDestAfterVictory = visitDest==VISIT_DEST;
|
||||||
}
|
}
|
||||||
@ -1238,9 +1259,9 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, ui8 teleporting, boo
|
|||||||
// visit town for town portal \ castle gates
|
// visit town for town portal \ castle gates
|
||||||
// do not use generic visitObjectOnTile to avoid double-teleporting
|
// do not use generic visitObjectOnTile to avoid double-teleporting
|
||||||
// if this moveHero call was triggered by teleporter
|
// if this moveHero call was triggered by teleporter
|
||||||
if (!t.visitableObjects.empty())
|
if (objectToVisit)
|
||||||
{
|
{
|
||||||
if (CGTownInstance * town = dynamic_cast<CGTownInstance *>(t.visitableObjects.back()))
|
if (CGTownInstance * town = dynamic_cast<CGTownInstance *>(objectToVisit))
|
||||||
town->onHeroVisit(h);
|
town->onHeroVisit(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,6 +90,11 @@ bool TurnOrderProcessor::playersInContact(PlayerColor left, PlayerColor right) c
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TurnOrderProcessor::isContactAllowed(PlayerColor active, PlayerColor waiting) const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool TurnOrderProcessor::canActSimultaneously(PlayerColor active, PlayerColor waiting) const
|
bool TurnOrderProcessor::canActSimultaneously(PlayerColor active, PlayerColor waiting) const
|
||||||
{
|
{
|
||||||
const auto * activeInfo = gameHandler->getPlayerState(active, false);
|
const auto * activeInfo = gameHandler->getPlayerState(active, false);
|
||||||
|
@ -53,6 +53,8 @@ class TurnOrderProcessor : boost::noncopyable
|
|||||||
public:
|
public:
|
||||||
TurnOrderProcessor(CGameHandler * owner);
|
TurnOrderProcessor(CGameHandler * owner);
|
||||||
|
|
||||||
|
bool isContactAllowed(PlayerColor left, PlayerColor right) const;
|
||||||
|
|
||||||
/// Add new player to handle (e.g. on game start)
|
/// Add new player to handle (e.g. on game start)
|
||||||
void addPlayer(PlayerColor which);
|
void addPlayer(PlayerColor which);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user