Pārlūkot izejas kodu

* support for Wait command (to be tested)

Michał W. Urbańczyk 17 gadi atpakaļ
vecāks
revīzija
bb5819f4df
5 mainītis faili ar 64 papildinājumiem un 6 dzēšanām
  1. 3 1
      CBattleInterface.cpp
  2. 51 0
      CGameState.cpp
  3. 1 0
      CGameState.h
  4. 1 0
      client/Client.cpp
  5. 8 5
      server/CGameHandler.cpp

+ 3 - 1
CBattleInterface.cpp

@@ -170,7 +170,7 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
 	}
 
 
-	//prepairing graphic with cell borders
+	//preparing graphic with cell borders
 	cellBorders = CSDL_Ext::newSurface(background->w, background->h, cellBorder);
 	//copying palette
 	for(int g=0; g<cellBorder->format->palette->ncolors; ++g) //we assume that cellBorders->format->palette->ncolors == 256
@@ -708,6 +708,7 @@ void CBattleInterface::bSpellf()
 
 void CBattleInterface::bWaitf()
 {
+	giveCommand(8,0,activeStack);
 }
 
 void CBattleInterface::bDefencef()
@@ -793,6 +794,7 @@ void CBattleInterface::stackActivated(int number)
 	activeStack = number;
 	myTurn = true;
 	redrawBackgroundWithHexes(number);
+	bWait->block(vstd::contains(LOCPLINT->cb->battleGetStackByID(number)->state,WAITING)); //block waiting button if stack has been already waiting
 }
 
 void CBattleInterface::stackMoved(int number, int destHex, bool endMoving)

+ 51 - 0
CGameState.cpp

@@ -686,7 +686,13 @@ void CGameState::applyNL(IPack * pack)
 			BattleNextRound *ns = static_cast<BattleNextRound*>(pack);
 			curB->round = ns->round;
 			for(int i=0; i<curB->stacks.size();i++)
+			{
+				curB->stacks[i]->state -= DEFENDING;
+				curB->stacks[i]->state -= WAITING;
+				curB->stacks[i]->state -= MOVED;
+				curB->stacks[i]->state -= HAD_MORALE;
 				curB->stacks[i]->counterAttacks = 1;
+			}
 			break;
 		}
 	case 3002:
@@ -734,6 +740,24 @@ void CGameState::applyNL(IPack * pack)
 			applyNL(&br->bsa);
 			break;
 		}
+	case 3007:
+		{
+			StartAction *br = static_cast<StartAction*>(pack);
+				CStack *st = curB->getStack(br->ba.stackNumber);
+			switch(br->ba.actionType)
+			{
+			case 3:
+				st->state.insert(DEFENDING);
+				break;
+			case 8:
+				st->state.insert(WAITING);
+				break;
+			case 2: case 6: case 7: case 9: case 10:
+				st->state.insert(MOVED);
+				break;
+			}
+			break;
+		}
 	case 3009:
 		{
 			SpellCasted *sc = static_cast<SpellCasted*>(pack);
@@ -1581,4 +1605,31 @@ void BattleInfo::calculateCasualties( std::set<std::pair<ui32,si32> > *casualtie
 			casualties[!stacks[i]->attackerOwned].insert(std::pair<ui32,si32>(stacks[i]->creature->idNumber,stacks[i]->baseAmount - stacks[i]->amount));
 		}
 	}
+}
+
+CStack * BattleInfo::getNextStack()
+{
+	CStack *current = getStack(activeStack);
+	for (int i = 0; i <  stacks.size(); i++)  //find fastest not moved/waited stack (stacks vector is sorted by speed)
+	{
+		if(vstd::contains(stacks[i]->state,DEFENDING)
+			||vstd::contains(stacks[i]->state,WAITING)
+			||vstd::contains(stacks[i]->state,MOVED)
+			||!stacks[i]->alive()
+			||stacks[i] == current
+		  )
+			continue;
+		return stacks[i];
+	}
+	for (int i = stacks.size() - 1; i >= 0 ; i--) //find slowest waiting stack
+	{
+		if(vstd::contains(stacks[i]->state,DEFENDING)
+			||vstd::contains(stacks[i]->state,MOVED)
+			||!stacks[i]->alive()
+			||stacks[i] == current
+		  )
+			continue;
+		return stacks[i];
+	}
+	return NULL; //all stacks moved or defending!
 }

+ 1 - 0
CGameState.h

@@ -66,6 +66,7 @@ struct DLL_EXPORT BattleInfo
 	{
 		h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
 	}
+	CStack * getNextStack(); //which stack will have turn after current one
 	CStack * getStack(int stackID);
 	CStack * getStackT(int tileID);
 	void getAccessibilityMap(bool *accessibility, int stackToOmmit=-1); //send pointer to at least 187 allocated bytes

+ 1 - 0
client/Client.cpp

@@ -613,6 +613,7 @@ void CClient::process(int what)
 				playerint[gs->curB->side1]->actionStarted(&curbaction);
 			if(playerint.find(gs->curB->side2) != playerint.end())
 				playerint[gs->curB->side2]->actionStarted(&curbaction);
+			gs->apply(&StartAction(curbaction));
 			break;
 		}
 	case 3008:

+ 8 - 5
server/CGameHandler.cpp

@@ -307,11 +307,11 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
 		const BattleInfo & curB = *gs->curB;
 
 		//stack loop
-		for(unsigned i=0;i<stacks.size() && !battleResult.get();i++)
+		CStack *next;
+		while(!battleResult.get() && (next=gs->curB->getNextStack()))
 		{
-			if(!stacks[i]->alive()) continue;//indicates imposiibility of making action for this dead unit
 			BattleSetActiveStack sas;
-			sas.stack = stacks[i]->ID;
+			sas.stack = next->ID;
 			sendAndApply(&sas);
 			boost::unique_lock<boost::mutex> lock(battleMadeAction.mx);
 			while(!battleMadeAction.data  &&  !battleResult.get()) //active stack hasn't made its action and battle is still going
@@ -1080,18 +1080,21 @@ upgend:
 						{
 							sendAndApply(&StartAction(ba)); //start movement
 							moveStack(ba.stackNumber,ba.destinationTile); //move
-							sendDataToClients(ui16(3008)); //endmovement
+							sendDataToClients(ui16(3008)); //end movement
 							break;
 						}
 					case 3: //defend
+					case 8: //wait
 						{
+							sendAndApply(&StartAction(ba));
+							sendDataToClients(ui16(3008));
 							break;
 						}
 					case 4: //retreat/flee
 						{
 							//TODO: check if fleeing is possible (e.g. enemy may have Shackles of War)
 							//TODO: calculate casualties
-							//TODO: remove retreating hero from map and place it in recrutation list
+							//TODO: remove retreating hero from map and place it in recruitment list
 							BattleResult *br = new BattleResult;
 							br->result = 1;
 							br->winner = !ba.side; //fleeing side loses