Browse Source

* support for multiple retaliations per turn, unlimited retaliations, counterstrike spell
* stack is not resurrected when it is under a living stack

mateuszb 16 years ago
parent
commit
072c1f8d12
3 changed files with 31 additions and 4 deletions
  1. 9 0
      lib/CGameState.cpp
  2. 19 2
      lib/NetPacksLib.cpp
  3. 3 2
      server/CGameHandler.cpp

+ 9 - 0
lib/CGameState.cpp

@@ -528,6 +528,15 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
 	:ID(I), creature(C), amount(A), baseAmount(A), firstHPleft(C->hitPoints), owner(O), slot(S), attackerOwned(AO), position(-1),   
 	counterAttacks(1), shots(C->shots), features(C->abilities)
 {
+	//additional retaliations
+	for(int h=0; h<C->abilities.size(); ++h)
+	{
+		if(C->abilities[h].type == StackFeature::ADDITIONAL_RETALIATION)
+		{
+			counterAttacks += C->abilities[h].value;
+		}
+	}
+	//alive state indication
 	state.insert(ALIVE);
 }
 

+ 19 - 2
lib/NetPacksLib.cpp

@@ -583,7 +583,7 @@ DLL_EXPORT void BattleNextRound::applyGs( CGameState *gs )
 		s->state -= WAITING;
 		s->state -= MOVED;
 		s->state -= HAD_MORALE;
-		s->counterAttacks = 1;
+		s->counterAttacks = 1 + s->valOfFeatures(StackFeature::ADDITIONAL_RETALIATION);
 
 		//remove effects and restore only those with remaining turns in duration
 		std::vector<CStack::StackEffect> tmpEffects = s->effects;
@@ -867,9 +867,12 @@ static std::vector<StackFeature> stackEffectToFeature(const CStack::StackEffect
 	case 56: //frenzy
 		sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
 		break;
-	case 60: //hypnotize
+	case 58: //counterstrike
+		sf.push_back(featureGenerator(StackFeature::ADDITIONAL_RETALIATION, 0, VLC->spellh->spells[sse.id].powers[sse.level], sse.turnsRemain));
 		break;
+	case 60: //hypnotize
 		sf.push_back(featureGenerator(StackFeature::HYPNOTIZED, 0, sse.level, sse.turnsRemain));
+		break;
 	case 61: //forgetfulness
 		sf.push_back(featureGenerator(StackFeature::SLAYER, 0, sse.level, sse.turnsRemain));
 		break;
@@ -960,6 +963,20 @@ DLL_EXPORT void StacksHealedOrResurrected::applyGs( CGameState *gs )
 	for(int g=0; g<healedStacks.size(); ++g)
 	{
 		CStack * changedStack = gs->curB->stacks[healedStacks[g].stackID];
+
+		//checking if we resurrect a stack that is under a living stack
+		std::vector<int> access = gs->curB->getAccessibility(changedStack->ID, true);
+		bool acc[BFIELD_SIZE];
+		for(int h=0; h<BFIELD_SIZE; ++h)
+			acc[h] = false;
+		for(int h=0; h<access.size(); ++h)
+			acc[access[h]] = true;
+		if(!changedStack->alive() && !gs->curB->isAccessible(changedStack->position, acc,
+			changedStack->hasFeatureOfType(StackFeature::DOUBLE_WIDE), changedStack->attackerOwned,
+			changedStack->hasFeatureOfType(StackFeature::FLYING), true))
+			return; //position is already occupied
+
+		//applying changes
 		if(!changedStack->alive())
 		{
 			changedStack->state.insert(ALIVE);

+ 3 - 2
server/CGameHandler.cpp

@@ -2371,9 +2371,9 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 			//counterattack
 			if(!curStack->hasFeatureOfType(StackFeature::BLOCKS_RETALIATION)
 				&& stackAtEnd->alive()
-				&& stackAtEnd->counterAttacks
+				&& ( stackAtEnd->counterAttacks > 0 || stackAtEnd->hasFeatureOfType(StackFeature::UNLIMITED_RETALIATIONS) )
 				&& !stackAtEnd->hasFeatureOfType(StackFeature::SIEGE_WEAPON)
-				&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED)) //TODO: support for multiple retaliatons per turn
+				&& !stackAtEnd->hasFeatureOfType(StackFeature::HYPNOTIZED))
 			{
 				prepareAttack(bat,stackAtEnd,curStack);
 				bat.flags |= 2;
@@ -2826,6 +2826,7 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 			case 54: //slow
 			case 55: //slayer
 			case 56: //frenzy
+			case 58: //counterstrike
 			case 60: //hypnotize
 			case 61: //forgetfulness
 			case 62: //blind