Răsfoiți Sursa

* defensive stance implemented (bug #342 fixed)

mateuszb 14 ani în urmă
părinte
comite
98494a5e6f
4 a modificat fișierele cu 46 adăugiri și 11 ștergeri
  1. 24 8
      client/CBattleInterface.cpp
  2. 9 3
      lib/HeroBonus.h
  3. 4 0
      lib/NetPacksLib.cpp
  4. 9 0
      server/CGameHandler.cpp

+ 24 - 8
client/CBattleInterface.cpp

@@ -2788,10 +2788,29 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
 
 void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
 {
-	for(std::vector<ui32>::const_iterator ci = sse.stacks.begin(); ci!=sse.stacks.end(); ++ci)
+	if(sse.effect.id != -1) //can be -1 for defensive stance effect
 	{
-		displayEffect(CGI->spellh->spells[sse.effect.id]->mainEffectAnim, curInt->cb->battleGetStackByID(*ci)->position);
+		for(std::vector<ui32>::const_iterator ci = sse.stacks.begin(); ci!=sse.stacks.end(); ++ci)
+		{
+			displayEffect(CGI->spellh->spells[sse.effect.id]->mainEffectAnim, curInt->cb->battleGetStackByID(*ci)->position);
+		}
+	}
+	else if (sse.effect.source == Bonus::OTHER && sse.effect.type == Bonus::PRIMARY_SKILL && sse.stacks.size() == 1)
+	{
+		//defensive stance (I hope)
+		const CStack * stack = LOCPLINT->cb->battleGetStackByID(*sse.stacks.begin());
+		int txtid = 120;
+
+		if(stack->count != 1)
+			txtid++; //move to plural text
+
+		char txt[4000];
+		int val = stack->Defense() - (stack->Defense() * 100 )/ (100 + sse.effect.val);
+		sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(),  (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str(), val);
+		console->addText(txt);
 	}
+
+
 	if (activeStack != NULL) //it can be -1 when a creature casts effect
 	{
 		redrawBackgroundWithHexes(activeStack);
@@ -3313,14 +3332,11 @@ void CBattleInterface::startAction(const BattleAction* action)
 	int txtid = 0;
 	switch(action->actionType)
 	{
-	case 3: //defend
-		txtid = 120;
-		break;
-	case 8: //wait
+	case BattleAction::WAIT:
 		txtid = 136;
 		break;
-	case 11: //bad morale
-		txtid = -34; //negative -> no separate singular/plural form		
+	case BattleAction::BAD_MORALE:
+		txtid = -34; //negative -> no separate singular/plural form
 		displayEffect(30,stack->position);
 		break;
 	}

+ 9 - 3
lib/HeroBonus.h

@@ -179,7 +179,8 @@ struct DLL_EXPORT Bonus
 		N_TURNS = 16, //used during battles, after battle bonus is always removed
 		N_DAYS = 32,
 		UNITL_BEING_ATTACKED = 64,/*removed after attack and counterattacks are performed*/
-		UNTIL_ATTACK = 128 /*removed after attack and counterattacks are performed*/
+		UNTIL_ATTACK = 128, /*removed after attack and counterattacks are performed*/
+		STACK_GETS_TURN = 256 /*removed when stack gets its turn - used for defensive stance*/
 	};
 	enum BonusSource
 	{
@@ -197,7 +198,8 @@ struct DLL_EXPORT Bonus
 		HERO_SPECIAL,
 		ARMY,
 		CAMPAIGN_BONUS,
-		SPECIAL_WEEK
+		SPECIAL_WEEK,
+		OTHER /*used for defensive stance*/
 	};
 
 	enum LimitEffect
@@ -218,7 +220,7 @@ struct DLL_EXPORT Bonus
 		INDEPENDENT_MAX //used for SPELL bonus
 	};
 
-	ui8 duration; //uses BonusDuration values
+	ui16 duration; //uses BonusDuration values
 	si16 turnsRemain; //used if duration is N_TURNS or N_DAYS
 
 	TBonusType type; //uses BonusType values - says to what is this bonus - 1 byte
@@ -271,6 +273,10 @@ struct DLL_EXPORT Bonus
 	{
 		return hb->duration & Bonus::ONE_BATTLE;
 	}
+	static bool UntilGetsTurn(const Bonus *hb)
+	{
+		return hb->duration & Bonus::STACK_GETS_TURN;
+	}
 	static bool UntilAttack(const Bonus *hb)
 	{
 		return hb->duration & Bonus::UNTIL_ATTACK;

+ 4 - 0
lib/NetPacksLib.cpp

@@ -919,6 +919,10 @@ DLL_EXPORT void BattleSetActiveStack::applyGs( CGameState *gs )
 {
 	gs->curB->activeStack = stack;
 	CStack *st = gs->curB->getStack(stack);
+
+	//remove bonuses that last until when stack gets new turn
+	st->bonuses.remove_if(Bonus::UntilGetsTurn);
+
 	if(vstd::contains(st->state,MOVED)) //if stack is moving second time this turn it must had a high morale bonus
 		st->state.insert(HAD_MORALE);
 }

+ 9 - 0
server/CGameHandler.cpp

@@ -3033,6 +3033,15 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 			break;
 		}
 	case BattleAction::DEFEND: //defend
+		{
+			//defensive stance
+			SetStackEffect sse;
+			sse.effect = Bonus(Bonus::STACK_GETS_TURN, Bonus::PRIMARY_SKILL, Bonus::OTHER, 20, -1, PrimarySkill::DEFENSE, Bonus::PERCENT_TO_ALL);
+			sse.stacks.push_back(ba.stackNumber);
+			sendAndApply(&sse);
+
+			//don't break - we share code with next case
+		}
 	case BattleAction::WAIT: //wait
 		{
 			sendAndApply(&StartAction(ba));