Browse Source

* Fixed #33 -> Creatures tend to stop at every hex during movement

beegee1 14 years ago
parent
commit
f609c4ad9a

+ 2 - 2
AI/GeniusAI/CGeniusAI.cpp

@@ -1319,12 +1319,12 @@ void CGeniusAI::battleNewRound(int round)
 /**
 /**
  *
  *
  */
  */
-void CGeniusAI::battleStackMoved(int ID, THex dest, int distance, bool end)
+void CGeniusAI::battleStackMoved(int ID, std::vector<THex> dest, int distance)
 {
 {
 	std::string message("\t\t\tCGeniusAI::battleStackMoved ID(");
 	std::string message("\t\t\tCGeniusAI::battleStackMoved ID(");
 	message += boost::lexical_cast<std::string>(ID);
 	message += boost::lexical_cast<std::string>(ID);
 	message += "), dest(";
 	message += "), dest(";
-	message += boost::lexical_cast<std::string>(dest);
+	message += boost::lexical_cast<std::string>(dest.size());
 	message += ")";
 	message += ")";
 	DbgBox(message.c_str());
 	DbgBox(message.c_str());
 }
 }

+ 1 - 1
AI/GeniusAI/CGeniusAI.h

@@ -205,7 +205,7 @@ public:
 	virtual void battleStacksAttacked(const std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack())
 	virtual void battleStacksAttacked(const std::set<BattleStackAttacked> & bsa); //called when stack receives damage (after battleAttack())
 	virtual void battleEnd(const BattleResult *br);
 	virtual void battleEnd(const BattleResult *br);
 	virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
 	virtual void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
-	virtual void battleStackMoved(int ID, THex dest, int distance, bool end);
+	virtual void battleStackMoved(int ID, std::vector<THex> dest, int distance);
 	virtual void battleSpellCast(const BattleSpellCast *sc);
 	virtual void battleSpellCast(const BattleSpellCast *sc);
 	virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
 	virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
 	//virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
 	//virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning

+ 1 - 1
AI/StupidAI/StupidAI.cpp

@@ -185,7 +185,7 @@ void CStupidAI::battleNewRound(int round)
 	print("battleNewRound called");
 	print("battleNewRound called");
 }
 }
 
 
-void CStupidAI::battleStackMoved(const CStack * stack, THex dest, int distance, bool end) 
+void CStupidAI::battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) 
 {
 {
 	print("battleStackMoved called");;
 	print("battleStackMoved called");;
 }
 }

+ 1 - 1
AI/StupidAI/StupidAI.h

@@ -21,7 +21,7 @@ public:
 	//void battleResultsApplied() OVERRIDE; //called when all effects of last battle are applied
 	//void battleResultsApplied() OVERRIDE; //called when all effects of last battle are applied
 	void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied;
 	void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied;
 	void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
 	void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
-	void battleStackMoved(const CStack * stack, THex dest, int distance, bool end) OVERRIDE;
+	void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
 	void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
 	void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
 	void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE;//called when a specific effect is set to stacks
 	void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE;//called when a specific effect is set to stacks
 	void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right
 	void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) OVERRIDE; //called by engine when battle starts; side=0 - left, side=1 - right

+ 40 - 22
client/CBattleInterface.cpp

@@ -609,9 +609,9 @@ bool CBattleStackMoved::init()
 	//bool twoTiles = movedStack->doubleWide();
 	//bool twoTiles = movedStack->doubleWide();
 	
 	
 	Point begPosition = CBattleHex::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner);
 	Point begPosition = CBattleHex::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner);
-	Point endPosition = CBattleHex::getXYUnitAnim(destHex, movedStack->attackerOwned, movedStack, owner);
+	Point endPosition = CBattleHex::getXYUnitAnim(nextHex, movedStack->attackerOwned, movedStack, owner);
 
 
-	int mutPos = THex::mutualPosition(curStackPos, destHex);
+	int mutPos = THex::mutualPosition(curStackPos, nextHex);
 	
 	
 	//reverse unit if necessary
 	//reverse unit if necessary
 	if((begPosition.x > endPosition.x) && owner->creDir[stack->ID] == true)
 	if((begPosition.x > endPosition.x) && owner->creDir[stack->ID] == true)
@@ -687,10 +687,41 @@ void CBattleStackMoved::nextFrame()
 	posY += stepY;
 	posY += stepY;
 	owner->creAnims[stack->ID]->pos.y = posY;
 	owner->creAnims[stack->ID]->pos.y = posY;
 
 
+	// Increments step count and check if we are finished with current animation
 	++whichStep;
 	++whichStep;
 	if(whichStep == steps)
 	if(whichStep == steps)
 	{
 	{
-		endAnim();
+		// Sets the position of the creature animation sprites
+		Point coords = CBattleHex::getXYUnitAnim(nextHex, owner->creDir[stack->ID], stack, owner);
+		owner->creAnims[stack->ID]->pos = coords;
+		
+		// true if creature haven't reached the final destination hex
+		if ((nextPos + 1) < destTiles.size())
+		{
+			// update the next hex field which has to be reached by the stack
+			nextPos++;
+			curStackPos = nextHex;
+			nextHex = destTiles[nextPos];
+			
+			// update position of double wide creatures
+			bool twoTiles = stack->doubleWide();
+			if(twoTiles && bool(stack->attackerOwned) && (owner->creDir[stack->ID] != bool(stack->attackerOwned) )) //big attacker creature is reversed
+				owner->creAnims[stack->ID]->pos.x -= 44;
+			else if(twoTiles && (! bool(stack->attackerOwned) ) && (owner->creDir[stack->ID] != bool(stack->attackerOwned) )) //big defender creature is reversed
+				owner->creAnims[stack->ID]->pos.x += 44;
+			
+			// re-init animation
+			for(std::list<std::pair<CBattleAnimation *, bool> >::iterator it = owner->pendingAnims.begin(); it != owner->pendingAnims.end(); ++it)
+			{
+				if (it->first == this)
+				{
+					it->second = false;
+					break;
+				}
+			}
+		}
+		else
+			endAnim();
 	}
 	}
 }
 }
 
 
@@ -701,22 +732,8 @@ void CBattleStackMoved::endAnim()
 	CBattleAnimation::endAnim();
 	CBattleAnimation::endAnim();
 
 
 	if(movedStack)
 	if(movedStack)
-	{
-		bool twoTiles = movedStack->doubleWide();
-
-		if(endMoving)
-		{
-			owner->addNewAnim(new CBattleMoveEnd(owner, stack, destHex));
-		}
+		owner->addNewAnim(new CBattleMoveEnd(owner, stack, nextHex));
 
 
-		Point coords = CBattleHex::getXYUnitAnim(destHex, owner->creDir[stack->ID], movedStack, owner);
-		owner->creAnims[stack->ID]->pos = coords;
-
-		if(!endMoving && twoTiles && bool(movedStack->attackerOwned) && (owner->creDir[stack->ID] != bool(movedStack->attackerOwned) )) //big attacker creature is reversed
-			owner->creAnims[stack->ID]->pos.x -= 44;
-		else if(!endMoving && twoTiles && (! bool(movedStack->attackerOwned) ) && (owner->creDir[stack->ID] != bool(movedStack->attackerOwned) )) //big defender creature is reversed
-			owner->creAnims[stack->ID]->pos.x += 44;
-	}
 
 
 	if(owner->moveSh >= 0)
 	if(owner->moveSh >= 0)
 	{
 	{
@@ -727,10 +744,11 @@ void CBattleStackMoved::endAnim()
 	delete this;
 	delete this;
 }
 }
 
 
-CBattleStackMoved::CBattleStackMoved(CBattleInterface * _owner, const CStack * _stack, THex _destHex, bool _endMoving, int _distance)
-: CBattleStackAnimation(_owner, _stack), destHex(_destHex), endMoving(_endMoving), distance(_distance), stepX(0.0f), stepY(0.0f)
+CBattleStackMoved::CBattleStackMoved(CBattleInterface * _owner, const CStack * _stack, std::vector<THex> _destTiles, int _distance)
+: CBattleStackAnimation(_owner, _stack), destTiles(_destTiles), nextPos(0), distance(_distance), stepX(0.0f), stepY(0.0f)
 {
 {
 	curStackPos = stack->position;
 	curStackPos = stack->position;
+	nextHex = destTiles.front();
 }
 }
 
 
 //move started
 //move started
@@ -2525,9 +2543,9 @@ void CBattleInterface::stackActivated(const CStack * stack) //TODO: check it all
 		activateStack();
 		activateStack();
 }
 }
 
 
-void CBattleInterface::stackMoved(const CStack * stack, THex destHex, bool endMoving, int distance)
+void CBattleInterface::stackMoved(const CStack * stack, std::vector<THex> destHex, int distance)
 {
 {
-	addNewAnim(new CBattleStackMoved(this, stack, destHex, endMoving, distance));
+	addNewAnim(new CBattleStackMoved(this, stack, destHex, distance));
 	waitForAnims();
 	waitForAnims();
 }
 }
 
 

+ 5 - 4
client/CBattleInterface.h

@@ -161,8 +161,9 @@ public:
 class CBattleStackMoved : public CBattleStackAnimation
 class CBattleStackMoved : public CBattleStackAnimation
 {
 {
 private:
 private:
-	THex destHex; //destination
-	bool endMoving; //if this is end of move
+	std::vector<THex> destTiles; //destination
+	THex nextHex;
+	int nextPos;
 	int distance;
 	int distance;
 	float stepX, stepY; //how far stack is moved in one frame
 	float stepX, stepY; //how far stack is moved in one frame
 	float posX, posY;
 	float posX, posY;
@@ -173,7 +174,7 @@ public:
 	void nextFrame();
 	void nextFrame();
 	void endAnim();
 	void endAnim();
 
 
-	CBattleStackMoved(CBattleInterface * _owner, const CStack * _stack, THex _destHex, bool _endMoving, int _distance);
+	CBattleStackMoved(CBattleInterface * _owner, const CStack * _stack, std::vector<THex> _destTiles, int _distance);
 };
 };
 
 
 /// Move start animation of a creature
 /// Move start animation of a creature
@@ -541,7 +542,7 @@ public:
 	void newStack(const CStack * stack); //new stack appeared on battlefield
 	void newStack(const CStack * stack); //new stack appeared on battlefield
 	void stackRemoved(int stackID); //stack disappeared from batlefiled
 	void stackRemoved(int stackID); //stack disappeared from batlefiled
 	void stackActivated(const CStack * stack); //active stack has been changed
 	void stackActivated(const CStack * stack); //active stack has been changed
-	void stackMoved(const CStack * stack, THex destHex, bool endMoving, int distance); //stack with id number moved to destHex
+	void stackMoved(const CStack * stack, std::vector<THex> destHex, int distance); //stack with id number moved to destHex
 	void waitForAnims();
 	void waitForAnims();
 	void stacksAreAttacked(std::vector<SStackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
 	void stacksAreAttacked(std::vector<SStackAttackedInfo> attackedInfos); //called when a certain amount of stacks has been attacked
 	void stackAttacking(const CStack * attacker, THex dest, const CStack * attacked, bool shooting); //called when stack with id ID is attacking something on hex dest
 	void stackAttacking(const CStack * attacker, THex dest, const CStack * attacked, bool shooting); //called when stack with id ID is attacking something on hex dest

+ 2 - 2
client/CPlayerInterface.cpp

@@ -761,7 +761,7 @@ void CPlayerInterface::battleEnd(const BattleResult *br)
 	battleInt->battleFinished(*br);
 	battleInt->battleFinished(*br);
 }
 }
 
 
-void CPlayerInterface::battleStackMoved(const CStack * stack, THex dest, int distance, bool end)
+void CPlayerInterface::battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance)
 {
 {
 	if(LOCPLINT != this)
 	if(LOCPLINT != this)
 	{ //another local interface should do this
 	{ //another local interface should do this
@@ -769,7 +769,7 @@ void CPlayerInterface::battleStackMoved(const CStack * stack, THex dest, int dis
 	}
 	}
 
 
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
-	battleInt->stackMoved(stack, dest, end, distance);
+	battleInt->stackMoved(stack, dest, distance);
 }
 }
 void CPlayerInterface::battleSpellCast( const BattleSpellCast *sc )
 void CPlayerInterface::battleSpellCast( const BattleSpellCast *sc )
 {
 {

+ 1 - 1
client/CPlayerInterface.h

@@ -220,7 +220,7 @@ public:
 	void battleEnd(const BattleResult *br) OVERRIDE; //end of battle
 	void battleEnd(const BattleResult *br) OVERRIDE; //end of battle
 	void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied; used for HP regen handling
 	void battleNewRoundFirst(int round) OVERRIDE; //called at the beginning of each turn before changes are applied; used for HP regen handling
 	void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
 	void battleNewRound(int round) OVERRIDE; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
-	void battleStackMoved(const CStack * stack, THex dest, int distance, bool end) OVERRIDE;
+	void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE;
 	void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
 	void battleSpellCast(const BattleSpellCast *sc) OVERRIDE;
 	void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
 	void battleStacksEffectsSet(const SetStackEffect & sse) OVERRIDE; //called when a specific effect is set to stacks
 	void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE;
 	void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE;

+ 1 - 1
client/NetPacksClient.cpp

@@ -596,7 +596,7 @@ void BattleResult::applyFirstCl( CClient *cl )
 void BattleStackMoved::applyFirstCl( CClient *cl )
 void BattleStackMoved::applyFirstCl( CClient *cl )
 {
 {
 	const CStack * movedStack = GS(cl)->curB->getStack(stack);
 	const CStack * movedStack = GS(cl)->curB->getStack(stack);
-	BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStackMoved,movedStack,tile,distance,ending);
+	BATTLE_INTERFACE_CALL_IF_PRESENT_FOR_BOTH_SIDES(battleStackMoved,movedStack,tilesToMove,distance);
 }
 }
 
 
 void BattleStackAttacked::applyCl( CClient *cl )
 void BattleStackAttacked::applyCl( CClient *cl )

+ 2 - 2
lib/CGameInterface.cpp

@@ -168,9 +168,9 @@ void CAdventureAI::battleNewStackAppeared(const CStack * stack)
 	battleAI->battleNewStackAppeared(stack);
 	battleAI->battleNewStackAppeared(stack);
 }
 }
 
 
-void CAdventureAI::battleStackMoved(const CStack * stack, THex dest, int distance, bool end)
+void CAdventureAI::battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance)
 {
 {
-	battleAI->battleStackMoved(stack, dest, distance, end);
+	battleAI->battleStackMoved(stack, dest, distance);
 }
 }
 
 
 void CAdventureAI::battleAttack(const BattleAttack *ba)
 void CAdventureAI::battleAttack(const BattleAttack *ba)

+ 2 - 2
lib/CGameInterface.h

@@ -97,7 +97,7 @@ public:
 	virtual void yourTurn() OVERRIDE{};
 	virtual void yourTurn() OVERRIDE{};
 	virtual void heroKilled(const CGHeroInstance*){};
 	virtual void heroKilled(const CGHeroInstance*){};
 	virtual void heroCreated(const CGHeroInstance*) OVERRIDE{};
 	virtual void heroCreated(const CGHeroInstance*) OVERRIDE{};
-	virtual void battleStackMoved(const CStack * stack, THex dest, int distance, bool end) OVERRIDE{};
+	virtual void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance) OVERRIDE{};
 	virtual void battleStackAttacking(int ID, int dest) {};
 	virtual void battleStackAttacking(int ID, int dest) {};
 	virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE{};
 	virtual void battleStacksAttacked(const std::vector<BattleStackAttacked> & bsa) OVERRIDE{};
 	virtual BattleAction activeStack(const CStack * stack) OVERRIDE;
 	virtual BattleAction activeStack(const CStack * stack) OVERRIDE;
@@ -127,7 +127,7 @@ public:
 	virtual void battleStacksRemoved(const BattleStacksRemoved & bsr);
 	virtual void battleStacksRemoved(const BattleStacksRemoved & bsr);
 	virtual void battleObstaclesRemoved(const std::set<si32> & removedObstacles);
 	virtual void battleObstaclesRemoved(const std::set<si32> & removedObstacles);
 	virtual void battleNewStackAppeared(const CStack * stack);
 	virtual void battleNewStackAppeared(const CStack * stack);
-	virtual void battleStackMoved(const CStack * stack, THex dest, int distance, bool end);
+	virtual void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance);
 	virtual void battleAttack(const BattleAttack *ba);
 	virtual void battleAttack(const BattleAttack *ba);
 	virtual void battleSpellCast(const BattleSpellCast *sc);
 	virtual void battleSpellCast(const BattleSpellCast *sc);
 	virtual void battleEnd(const BattleResult *br);
 	virtual void battleEnd(const BattleResult *br);

+ 1 - 1
lib/IGameEventsReceiver.h

@@ -42,7 +42,7 @@ public:
 	virtual void battleEnd(const BattleResult *br){};
 	virtual void battleEnd(const BattleResult *br){};
 	virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied;
 	virtual void battleNewRoundFirst(int round){}; //called at the beginning of each turn before changes are applied;
 	virtual void battleNewRound(int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
 	virtual void battleNewRound(int round){}; //called at the beginning of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
-	virtual void battleStackMoved(const CStack * stack, THex dest, int distance, bool end){};
+	virtual void battleStackMoved(const CStack * stack, std::vector<THex> dest, int distance){};
 	virtual void battleSpellCast(const BattleSpellCast *sc){};
 	virtual void battleSpellCast(const BattleSpellCast *sc){};
 	virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks
 	virtual void battleStacksEffectsSet(const SetStackEffect & sse){};//called when a specific effect is set to stacks
 	virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
 	virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right

+ 3 - 3
lib/NetPacks.h

@@ -1215,14 +1215,14 @@ struct BattleResult : public CPackForClient//3003
 struct BattleStackMoved : public CPackForClient//3004
 struct BattleStackMoved : public CPackForClient//3004
 {
 {
 	ui32 stack;
 	ui32 stack;
-	THex tile;
-	ui8 ending, distance, teleporting;
+	std::vector<THex> tilesToMove;
+	ui8 distance, teleporting;
 	BattleStackMoved(){type = 3004;};
 	BattleStackMoved(){type = 3004;};
 	void applyFirstCl(CClient *cl);
 	void applyFirstCl(CClient *cl);
 	void applyGs(CGameState *gs);
 	void applyGs(CGameState *gs);
 	template <typename Handler> void serialize(Handler &h, const int version)
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 	{
-		h & stack & tile & ending & distance;
+		h & stack & tilesToMove & distance;
 	}
 	}
 };
 };
 
 

+ 1 - 1
lib/NetPacksLib.cpp

@@ -973,7 +973,7 @@ void BattleResult::applyGs( CGameState *gs )
 
 
 void BattleStackMoved::applyGs( CGameState *gs )
 void BattleStackMoved::applyGs( CGameState *gs )
 {
 {
-	gs->curB->getStack(stack)->position = tile;
+	gs->curB->getStack(stack)->position = tilesToMove.back();
 }
 }
 
 
 DLL_EXPORT void BattleStackAttacked::applyGs( CGameState *gs )
 DLL_EXPORT void BattleStackAttacked::applyGs( CGameState *gs )

+ 14 - 7
server/CGameHandler.cpp

@@ -747,25 +747,31 @@ int CGameHandler::moveStack(int stack, THex dest)
 			//inform clients about move
 			//inform clients about move
 			BattleStackMoved sm;
 			BattleStackMoved sm;
 			sm.stack = curStack->ID;
 			sm.stack = curStack->ID;
-			sm.tile = path.first[0];
+			std::vector<THex> tiles;
+			tiles.push_back(path.first[0]);
+			sm.tilesToMove = tiles;
 			sm.distance = path.second;
 			sm.distance = path.second;
-			sm.ending = true;
 			sm.teleporting = false;
 			sm.teleporting = false;
 			sendAndApply(&sm);
 			sendAndApply(&sm);
 		}
 		}
 	}
 	}
 	else //for non-flying creatures
 	else //for non-flying creatures
 	{
 	{
+		// send one package with the creature path information
+		std::vector<THex> tiles;
 		int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
 		int tilesToMove = std::max((int)(path.first.size() - creSpeed), 0);
 		for(int v=path.first.size()-1; v>=tilesToMove; --v)
 		for(int v=path.first.size()-1; v>=tilesToMove; --v)
 		{
 		{
-			//inform clients about move
+			tiles.push_back(path.first[v]);	
+		}
+	
+		if (tiles.size() > 0)
+		{
 			BattleStackMoved sm;
 			BattleStackMoved sm;
 			sm.stack = curStack->ID;
 			sm.stack = curStack->ID;
-			sm.tile = path.first[v];
 			sm.distance = path.second;
 			sm.distance = path.second;
-			sm.ending = v==tilesToMove;
 			sm.teleporting = false;
 			sm.teleporting = false;
+			sm.tilesToMove = tiles;
 			sendAndApply(&sm);
 			sendAndApply(&sm);
 		}
 		}
 	}
 	}
@@ -3617,8 +3623,9 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, THex destinati
 			BattleStackMoved bsm;
 			BattleStackMoved bsm;
 			bsm.distance = -1;
 			bsm.distance = -1;
 			bsm.stack = gs->curB->activeStack;
 			bsm.stack = gs->curB->activeStack;
-			bsm.ending = true;
-			bsm.tile = destination;
+			std::vector<THex> tiles;
+			tiles.push_back(destination);
+			bsm.tilesToMove = tiles;
 			bsm.teleporting = true;
 			bsm.teleporting = true;
 			sendAndApply(&bsm);
 			sendAndApply(&bsm);