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:
parent
a437373a15
commit
5226081f33
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user