|
|
@@ -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);
|
|
|
- }
|
|
|
+ for(bool obstacleHit = false; (!obstacleHit) && (v >= tilesToMove); --v)
|
|
|
+ {
|
|
|
+ BattleHex hex = path.first[v];
|
|
|
+ tiles.push_back(hex);
|
|
|
|
|
|
- //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 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 stack didn't die in explosion, continue movement
|
|
|
- if(!obstacle->stopsMovement() && curStack->alive())
|
|
|
+ if(tiles.size() > 0)
|
|
|
{
|
|
|
- obstacle.reset();
|
|
|
+ //commit movement
|
|
|
+ BattleStackMoved sm;
|
|
|
+ sm.stack = curStack->ID;
|
|
|
+ sm.distance = path.second;
|
|
|
+ sm.teleporting = false;
|
|
|
+ sm.tilesToMove = tiles;
|
|
|
+ sendAndApply(&sm);
|
|
|
tiles.clear();
|
|
|
- v--;
|
|
|
- goto startWalking; //TODO it's so evil
|
|
|
}
|
|
|
+
|
|
|
+ //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;
|
|
|
}
|
|
|
|