ソースを参照

Armies swap will now maintain unit ordering

Ivan Savenko 5 ヶ月 前
コミット
ce4e37f2d9
1 ファイル変更34 行追加20 行削除
  1. 34 20
      client/widgets/CExchangeController.cpp

+ 34 - 20
client/widgets/CExchangeController.cpp

@@ -29,34 +29,48 @@ void CExchangeController::swapArmy()
 	const auto & leftSlots = left->Slots();
 	const auto & rightSlots = right->Slots();
 
-	auto i = leftSlots.begin();
-	auto j = rightSlots.begin();
+	auto leftIt = leftSlots.begin();
+	auto rightIt = rightSlots.begin();
 
-	for(; i != leftSlots.end() && j != rightSlots.end(); i++, j++)
+	// Swap slots that are full in both armies
+	// [A] [B] => [B] [A]
+	for (SlotID slotID(0); slotID < GameConstants::ARMY_SIZE; ++slotID)
 	{
-		GAME->interface()->cb->swapCreatures(left, right, i->first, j->first);
+		if (left->hasStackAtSlot(slotID) && right->hasStackAtSlot(slotID))
+			GAME->interface()->cb->swapCreatures(left, right, slotID, slotID);
 	}
 
-	if(i != leftSlots.end())
+	// Swap pairs of stacks in different slots and correct their positions
+	// [A] [ ]    [B] [ ]    [ ] [A]
+	//         =>         =>
+	// [ ] [B]    [ ] [A]    [B] [ ]
+	for (;;)
 	{
-		auto freeSlots = right->getFreeSlots();
-		auto slot = freeSlots.begin();
+		while (leftIt != leftSlots.end() && right->hasStackAtSlot(leftIt->first))
+			leftIt++;
 
-		for(; i != leftSlots.end() && slot != freeSlots.end(); i++, slot++)
-		{
-			GAME->interface()->cb->swapCreatures(left, right, i->first, *slot);
-		}
-	}
-	else if(j != rightSlots.end())
-	{
-		auto freeSlots = left->getFreeSlots();
-		auto slot = freeSlots.begin();
+		while (rightIt != rightSlots.end() && left->hasStackAtSlot(rightIt->first))
+			rightIt++;
 
-		for(; j != rightSlots.end() && slot != freeSlots.end(); j++, slot++)
-		{
-			GAME->interface()->cb->swapCreatures(left, right, *slot, j->first);
-		}
+		if (leftIt == leftSlots.end() || rightIt == rightSlots.end())
+			break;
+
+		GAME->interface()->cb->swapCreatures(left, right, leftIt->first, rightIt->first);
+
+		GAME->interface()->cb->swapCreatures(left, left, leftIt->first, rightIt->first);
+		GAME->interface()->cb->swapCreatures(right, right, rightIt->first, leftIt->first);
+
+		leftIt++;
+		rightIt++;
 	}
+
+	// Move remaining unpaired stacks (if armies size is different)
+	// [A] [ ] => [ ] [A]
+	for(; leftIt != leftSlots.end(); leftIt++)
+		GAME->interface()->cb->swapCreatures(left, right, leftIt->first, leftIt->first);
+
+	for(; rightIt != rightSlots.end(); rightIt++)
+		GAME->interface()->cb->swapCreatures(left, right, rightIt->first, rightIt->first);
 }
 
 void CExchangeController::moveArmy(bool leftToRight, std::optional<SlotID> heldSlot)