1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-23 12:08:45 +02:00

VCAI: add channel probing support for teleporters with multiple exits

This commit is contained in:
ArseniyShestakov 2015-12-03 17:20:03 +03:00
parent eb9f29e368
commit 2f9ca778b2
2 changed files with 24 additions and 16 deletions

@ -625,22 +625,29 @@ void VCAI::showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exit
int choosenExit = -1; int choosenExit = -1;
if(impassable) if(impassable)
knownTeleportChannels[channel]->passability = TeleportChannel::IMPASSABLE; knownTeleportChannels[channel]->passability = TeleportChannel::IMPASSABLE;
else else if(destinationTeleport != ObjectInstanceID() && destinationTeleportPos.valid())
{ {
auto neededExit = std::make_pair(destinationTeleport, destinationTeleportPos); auto neededExit = std::make_pair(destinationTeleport, destinationTeleportPos);
if(destinationTeleport != ObjectInstanceID() && vstd::contains(exits, neededExit)) if(destinationTeleport != ObjectInstanceID() && vstd::contains(exits, neededExit))
choosenExit = vstd::find_pos(exits, neededExit); choosenExit = vstd::find_pos(exits, neededExit);
}
if(!status.channelProbing()) for(auto exit : exits)
{
if(status.channelProbing() && exit.first == destinationTeleport)
{ {
for(auto exit : exits) choosenExit = vstd::find_pos(exits, exit);
break;
}
else
{
// FIXME: This code generate "Object is not visible." errors
// What is better way to check that certain teleport exit wasn't visited yet or not visible?
if(!vstd::contains(visitableObjs, cb->getObj(exit.first)) &&
!vstd::contains(teleportChannelProbingList, exit.first) &&
exit.first != destinationTeleport)
{ {
if(!vstd::contains(visitableObjs, cb->getObj(exit.first)) && teleportChannelProbingList.push_back(exit.first);
!vstd::contains(teleportChannelProbingList, exit.first) &&
exit.first != destinationTeleport)
{
teleportChannelProbingList.push_back(exit.first);
}
} }
} }
} }
@ -1867,11 +1874,11 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true), transit); cb->moveHero(*h, CGHeroInstance::convertPosition(dst, true), transit);
}; };
auto doTeleportMovement = [&](int3 dst, ObjectInstanceID exitId) auto doTeleportMovement = [&](ObjectInstanceID exitId, int3 exitPos)
{ {
destinationTeleport = exitId; destinationTeleport = exitId;
destinationTeleportPos = CGHeroInstance::convertPosition(dst, true); destinationTeleportPos = CGHeroInstance::convertPosition(exitPos, true);
cb->moveHero(*h, destinationTeleportPos); cb->moveHero(*h, h->pos);
destinationTeleport = ObjectInstanceID(); destinationTeleport = ObjectInstanceID();
destinationTeleportPos = int3(); destinationTeleportPos = int3();
afterMovementCheck(); afterMovementCheck();
@ -1880,13 +1887,14 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
auto doChannelProbing = [&]() -> void auto doChannelProbing = [&]() -> void
{ {
auto currentExit = getObj(CGHeroInstance::convertPosition(h->pos,false), false); auto currentExit = getObj(CGHeroInstance::convertPosition(h->pos,false), false);
auto currentExitPos = CGHeroInstance::convertPosition(h->pos,false);
assert(currentExit); assert(currentExit);
status.setChannelProbing(true); status.setChannelProbing(true);
for(auto exit : teleportChannelProbingList) for(auto exit : teleportChannelProbingList)
doTeleportMovement(CGHeroInstance::convertPosition(h->pos,false), exit); doTeleportMovement(exit, int3());
teleportChannelProbingList.clear(); teleportChannelProbingList.clear();
doTeleportMovement(CGHeroInstance::convertPosition(h->pos,false), currentExit->id); doTeleportMovement(currentExit->id, currentExitPos);
status.setChannelProbing(false); status.setChannelProbing(false);
}; };
@ -1900,7 +1908,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
auto nextObject = getObj(nextCoord, false); auto nextObject = getObj(nextCoord, false);
if(CGTeleport::isConnected(currentObject, nextObject)) if(CGTeleport::isConnected(currentObject, nextObject))
{ //we use special login if hero standing on teleporter it's mean we need { //we use special login if hero standing on teleporter it's mean we need
doTeleportMovement(currentCoord, nextObject->id); doTeleportMovement(nextObject->id, nextCoord);
if(teleportChannelProbingList.size()) if(teleportChannelProbingList.size())
doChannelProbing(); doChannelProbing();

@ -1755,7 +1755,7 @@ bool CGameHandler::moveHero( ObjectInstanceID hid, int3 dst, ui8 teleporting, bo
} }
logGlobal->traceStream() << "Player " << asker << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst; logGlobal->traceStream() << "Player " << asker << " wants to move hero "<< hid.getNum() << " from "<< h->pos << " to " << dst;
const int3 hmpos = dst + int3(-1,0,0); const int3 hmpos = CGHeroInstance::convertPosition(dst, false);
if(!gs->map->isInTheMap(hmpos)) if(!gs->map->isInTheMap(hmpos))
{ {