Browse Source

Support for Death Blow ability.

DjWarmonger 14 years ago
parent
commit
8102fd4cf0
6 changed files with 46 additions and 16 deletions
  1. 18 4
      client/CPlayerInterface.cpp
  2. 13 5
      lib/BattleState.cpp
  3. 3 3
      lib/BattleState.h
  4. 2 2
      lib/IGameCallback.cpp
  5. 5 1
      lib/NetPacks.h
  6. 5 1
      server/CGameHandler.cpp

+ 18 - 4
client/CPlayerInterface.cpp

@@ -717,6 +717,7 @@ BattleAction CPlayerInterface::activeStack(const CStack * stack) //called when i
 		}
 
 		b->stackActivated(stack);
+		//Regeneration & mana drain go there
 	}
 	//wait till BattleInterface sets its command
 	boost::unique_lock<boost::mutex> lock(b->givenCommand->mx);
@@ -822,11 +823,24 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
 	{
 		const CStack *stack = cb->battleGetStackByID(ba->stackAttacking);
 		std::string hlp = CGI->generaltexth->allTexts[45];
-		boost::algorithm::replace_first(hlp,"%s",(stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str());
+		boost::algorithm::replace_first(hlp,"%s", (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str());
 		battleInt->console->addText(hlp);
-		battleInt->displayEffect(18,stack->position);
+		battleInt->displayEffect(18, stack->position);
 	}
 	//TODO: bad luck?
+	if (ba->deathBlow())
+	{
+		const CStack *stack = cb->battleGetStackByID(ba->stackAttacking);
+		std::string hlp = CGI->generaltexth->allTexts[(stack->count != 1) ? 336 : 335];
+		boost::algorithm::replace_first(hlp,"%s", (stack->count != 1) ? stack->getCreature()->namePl.c_str() : stack->getCreature()->nameSing.c_str());
+		battleInt->console->addText(hlp);
+		for (std::vector<BattleStackAttacked>::const_iterator i = ba->bsa.begin(); i != ba->bsa.end(); i++)
+		{
+			const CStack * attacked = cb->battleGetStackByID(i->stackAttacked);
+			battleInt->displayEffect(73, attacked->position);
+		}
+		
+	}
 
 	const CStack * attacker = cb->battleGetStackByID(ba->stackAttacking);
 
@@ -834,15 +848,15 @@ void CPlayerInterface::battleAttack(const BattleAttack *ba)
 	{
 		for(std::vector<BattleStackAttacked>::const_iterator i = ba->bsa.begin(); i != ba->bsa.end(); i++)
 		{
-			const CStack * attacked = cb->battleGetStackByID(i->stackAttacked);
 			if (!i->isSecondary()) //display projectile only for primary target
 			{
+				const CStack * attacked = cb->battleGetStackByID(i->stackAttacked);
 				battleInt->stackAttacking(attacker, cb->battleGetPos(i->stackAttacked), attacked, true);
 			}
 		}
 	}
 	else
-	{//TODO: support multiple attacked creatures
+	{
 		int shift = 0;
 		if(ba->counter() && THex::mutualPosition(curAction->destinationTile, attacker->position) < 0)
 		{

+ 13 - 5
lib/BattleState.cpp

@@ -425,7 +425,8 @@ std::pair< std::vector<THex>, int > BattleInfo::getPath(THex start, THex dest, b
 	return std::make_pair(path, dist[dest]);
 }
 
-TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg ) const
+TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero,
+	bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg ) const
 {
 	float additiveBonus=1.0f, multBonus=1.0f,
 		minDmg = attacker->getMinDamage() * attackerCount, 
@@ -575,6 +576,11 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
 		additiveBonus += 1.0f;
 	}
 
+	if (deathBlow) //Dread Knight and many WoGified creatures
+	{
+		additiveBonus += 1.0f;
+	}
+
 	//handling spell effects
 	if(!shooting && defender->hasBonusOfType(Bonus::GENERAL_DAMAGE_REDUCTION, 0)) //eg. shield
 	{
@@ -647,14 +653,16 @@ TDmgRange BattleInfo::calculateDmgRange( const CStack* attacker, const CStack* d
 	return returnedVal;
 }
 
-TDmgRange BattleInfo::calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const
+TDmgRange BattleInfo::calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero,
+	bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const
 {
-	return calculateDmgRange(attacker, defender, attacker->count, defender->count, attackerHero, defendingHero, shooting, charge, lucky, ballistaDoubleDmg);
+	return calculateDmgRange(attacker, defender, attacker->count, defender->count, attackerHero, defendingHero, shooting, charge, lucky, deathBlow, ballistaDoubleDmg);
 }
 
-ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg )
+ui32 BattleInfo::calculateDmg( const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero,
+	bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg )
 {
-	TDmgRange range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky, ballistaDoubleDmg);
+	TDmgRange range = calculateDmgRange(attacker, defender, attackerHero, defendingHero, shooting, charge, lucky, deathBlow, ballistaDoubleDmg);
 
 	if(range.first != range.second)
 	{

+ 3 - 3
lib/BattleState.h

@@ -83,9 +83,9 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
 
 	bool isStackBlocked(const CStack * stack) const; //returns true if there is neighboring enemy stack
 
-	ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg); //charge - number of hexes travelled before attack (for champion's jousting)
-	TDmgRange calculateDmgRange( const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
-	TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
+	ui32 calculateDmg(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg); //charge - number of hexes travelled before attack (for champion's jousting)
+	TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, TQuantity attackerCount, TQuantity defenderCount, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
+	TDmgRange calculateDmgRange(const CStack* attacker, const CStack* defender, const CGHeroInstance * attackerHero, const CGHeroInstance * defendingHero, bool shooting, ui8 charge, bool lucky, bool deathBlow, bool ballistaDoubleDmg) const; //charge - number of hexes travelled before attack (for champion's jousting); returns pair <min dmg, max dmg>
 	void calculateCasualties(std::map<ui32,si32> *casualties) const; //casualties are array of maps size 2 (attacker, defeneder), maps are (crid => amount)
 	std::set<CStack*> getAttackedCreatures(const CSpell * s, int skillLevel, ui8 attackerOwner, THex destinationTile); //calculates stack affected by given spell
 	std::set<CStack*> getAttackedCreatures(const CStack* attacker, THex destinationTile); //calculates range of multi-hex attacks

+ 2 - 2
lib/IGameCallback.cpp

@@ -299,7 +299,7 @@ TDmgRange CBattleInfoCallback::battleEstimateDamage(const CStack * attacker, con
 		defenderHero = gs->curB->heroes[0];
 	}
 
-	TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false, false);
+	TDmgRange ret = gs->curB->calculateDmgRange(attacker, defender, attackerHero, defenderHero, shooting, 0, false, false, false);
 
 	if(retaliationDmg)
 	{
@@ -314,7 +314,7 @@ TDmgRange CBattleInfoCallback::battleEstimateDamage(const CStack * attacker, con
 			{
 				BattleStackAttacked bsa;
 				bsa.damageAmount = ret.*pairElems[i];
-				retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, false, false, false).*pairElems[!i];
+				retaliationDmg->*pairElems[!i] = gs->curB->calculateDmgRange(defender, attacker, bsa.newAmount, attacker->count, attackerHero, defenderHero, false, 0, false, false, false).*pairElems[!i];
 			}
 		}
 	}

+ 5 - 1
lib/NetPacks.h

@@ -1306,7 +1306,7 @@ struct BattleAttack : public CPackForClient//3006
 	std::vector<BattleStackAttacked> bsa;
 	ui32 stackAttacking;
 	ui8 flags; //uses Eflags (below)
-	enum EFlags{SHOT = 1, COUNTER = 2, LUCKY = 4, UNLUCKY = 8, BALLISTA_DOUBLE_DMG = 16};
+	enum EFlags{SHOT = 1, COUNTER = 2, LUCKY = 4, UNLUCKY = 8, BALLISTA_DOUBLE_DMG = 16, DEATH_BLOW = 32};
 
 	bool shot() const//distance attack - decrease number of shots
 	{
@@ -1329,6 +1329,10 @@ struct BattleAttack : public CPackForClient//3006
 	{
 		return flags & BALLISTA_DOUBLE_DMG;
 	}
+	bool deathBlow() const
+	{
+		return flags & DEATH_BLOW;
+	}
 	//bool killed() //if target stack was killed
 	//{
 	//	return bsa.killed();

+ 5 - 1
server/CGameHandler.cpp

@@ -522,6 +522,10 @@ void CGameHandler::prepareAttack(BattleAttack &bat, const CStack *att, const CSt
 	{
 		bat.flags |= BattleAttack::LUCKY;
 	}
+	if (rand()%100 < att->valOfBonuses(Bonus::DOUBLE_DAMAGE_CHANCE))
+	{
+		bat.flags |= BattleAttack::DEATH_BLOW;
+	}
 
 	if(att->getCreature()->idNumber == 146)
 	{
@@ -575,7 +579,7 @@ void CGameHandler::applyBattleEffects(BattleAttack &bat, const CStack *att, cons
 		bsa.flags |= BattleStackAttacked::SECONDARY; //all other targets do not suffer from spells & spell-like abilities
 	bsa.attackerID = att->ID;
 	bsa.stackAttacked = def->ID;
-	bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky(), bat.ballistaDoubleDmg());
+	bsa.damageAmount = gs->curB->calculateDmg(att, def, gs->curB->battleGetOwner(att), gs->curB->battleGetOwner(def), bat.shot(), distance, bat.lucky(), bat.deathBlow(), bat.ballistaDoubleDmg());
 	def->prepareAttacked(bsa); //calculate casualties
 	bat.bsa.push_back(bsa); //add this stack to the list of victims