1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

rewrite stack movement processing

This commit is contained in:
AlexVinS 2015-04-12 08:12:07 +03:00
parent a437373a15
commit 5226081f33

View File

@ -1022,48 +1022,83 @@ int CGameHandler::moveStack(int stack, BattleHex dest)
{
// 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);
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 stop = false; (!stop) && (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((obstacle = battleGetObstacleOnPos(hex, false)))
{
//we walked onto something, so we finalize this portion of stack movement check into obstacle
stop = true;
}
if(curStack->doubleWide())
{
BattleHex otherHex = curStack->occupiedHex(hex);
if(otherHex.isValid() && ((obstacle2 = battleGetObstacleOnPos(otherHex, false))))
{
//two hex creature hit obstacle by backside
stop = 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 didn't die in explosion, continue movement
if(obs->stopsMovement() || !curStack->alive())
{
obs.reset();
//movement has been interrupted by obstacle
stackIsMoving = false;
}
}
};
processObstacle(obstacle);
if(curStack->alive())
processObstacle(obstacle2);
}
else
//movement finished normally
stackIsMoving = false;
}
}
@ -1075,6 +1110,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;
}