1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-26 22:57:00 +02:00

Merge branch 'issue/2033' into develop

This commit is contained in:
AlexVinS 2015-06-20 17:41:05 +03:00
commit 728dac3b47

View File

@ -1020,50 +1020,76 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
}
else //for non-flying creatures
{
// send one package with the creature path information
shared_ptr<const CObstacleInstance> obstacle; //obstacle that interrupted movement
shared_ptr<const CObstacleInstance> obstacle, obstacle2; //obstacle that interrupted movement
std::vector<BattleHex> tiles;
int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
const int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
int v = path.first.size()-1;
startWalking:
for(; v >= tilesToMove; --v)
bool stackIsMoving = true;
while(stackIsMoving)
{
BattleHex hex = path.first[v];
tiles.push_back(hex);
if((obstacle = battleGetObstacleOnPos(hex, false)))
if(v<tilesToMove)
{
//we walked onto something, so we finalize this portion of stack movement check into obstacle
logGlobal->error("Movement terminated abnormally");
break;
}
}
if (tiles.size() > 0)
{
//commit movement
BattleStackMoved sm;
sm.stack = curStack->ID;
sm.distance = path.second;
sm.teleporting = false;
sm.tilesToMove = tiles;
sendAndApply(&sm);
}
//we don't handle obstacle at the destination tile -> it's handled separately in the if at the end
if(obstacle && curStack->position != dest)
{
handleDamageFromObstacle(*obstacle, curStack);
//if stack didn't die in explosion, continue movement
if(!obstacle->stopsMovement() && curStack->alive())
for(bool obstacleHit = false; (!obstacleHit) && (v >= tilesToMove); --v)
{
obstacle.reset();
tiles.clear();
v--;
goto startWalking; //TODO it's so evil
BattleHex hex = path.first[v];
tiles.push_back(hex);
//if we walked onto something, finalize this portion of stack movement check into obstacle
if((obstacle = battleGetObstacleOnPos(hex, false)))
obstacleHit = true;
if(curStack->doubleWide())
{
BattleHex otherHex = curStack->occupiedHex(hex);
//two hex creature hit obstacle by backside
if(otherHex.isValid() && ((obstacle2 = battleGetObstacleOnPos(otherHex, false))))
obstacleHit = true;
}
}
if(tiles.size() > 0)
{
//commit movement
BattleStackMoved sm;
sm.stack = curStack->ID;
sm.distance = path.second;
sm.teleporting = false;
sm.tilesToMove = tiles;
sendAndApply(&sm);
tiles.clear();
}
//we don't handle obstacle at the destination tile -> it's handled separately in the if at the end
if(curStack->position != dest)
{
auto processObstacle = [&](shared_ptr<const CObstacleInstance> & obs)
{
if(obs)
{
handleDamageFromObstacle(*obs, curStack);
//if stack die in explosion or interrupted by obstacle, abort movement
if(obs->stopsMovement() || !curStack->alive())
stackIsMoving = false;
obs.reset();
}
};
processObstacle(obstacle);
if(curStack->alive())
processObstacle(obstacle2);
}
else
//movement finished normally: we reached destination
stackIsMoving = false;
}
}
@ -1075,6 +1101,18 @@ startWalking:
handleDamageFromObstacle(*theLastObstacle, curStack);
}
}
if(curStack->alive() && curStack->doubleWide())
{
BattleHex otherHex = curStack->occupiedHex(curStack->position);
if(otherHex.isValid())
if(auto theLastObstacle = battleGetObstacleOnPos(otherHex, false))
{
//two hex creature hit obstacle by backside
handleDamageFromObstacle(*theLastObstacle, curStack);
}
}
return ret;
}