Selaa lähdekoodia

Support for WoG's Defense bonus.

DjWarmonger 14 vuotta sitten
vanhempi
sitoutus
16e7241fbd

+ 6 - 4
client/CBattleInterface.cpp

@@ -3210,12 +3210,12 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
 			displayEffect(CGI->spellh->spells[effID]->mainEffectAnim, curInt->cb->battleGetStackByID(*ci)->position);
 		}
 	}
-	else if (sse.stacks.size() == 1 && sse.effect.size() == 1)
+	else if (sse.stacks.size() == 1 && sse.effect.size() == 2)
 	{
-		const Bonus & bns = sse.effect.back();
+		const Bonus & bns = sse.effect.front();
 		if (bns.source == Bonus::OTHER && bns.type == Bonus::PRIMARY_SKILL)
 		{
-			//defensive stance (I hope)
+			//defensive stance
 			const CStack * stack = LOCPLINT->cb->battleGetStackByID(*sse.stacks.begin());
 			int txtid = 120;
 
@@ -3223,7 +3223,9 @@ void CBattleInterface::battleStacksEffectsSet(const SetStackEffect & sse)
 				txtid++; //move to plural text
 
 			char txt[4000];
-			int val = stack->Defense() - (stack->Defense() * 100 )/ (100 + bns.val);
+			BonusList defenseBonuses = *(stack->getBonuses(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE)));
+			defenseBonuses.remove_if(Selector::durationType(Bonus::STACK_GETS_TURN)); //remove bonuses gained from defensive stance
+			int val = stack->Defense() - defenseBonuses.totalValue();
 			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);
 		}

+ 1 - 0
config/bonusnames.txt

@@ -9,6 +9,7 @@ SPELL_BEFORE_ATTACK	Caster - %s	%d% chance to cast before attack
 CATAPULT	Catapult	Attacks siege walls
 JOUSTING	Champion Charge	+5% damage per hex travelled
 DOUBLE_DAMAGE_CHANCE	Death Blow	%d% chance for double damage
+DEFENSIVE_STANCE	Defense Bonus	+%d Defense when defending
 ADDITIONAL_ATTACK	Double Strike	Attacks twice
 DRAGON_NATURE	Dragon	Creature has a Dragon Nature
 LIFE_DRAIN	Drain life	Drains life equal to damage dealt

+ 2 - 0
lib/CCreatureHandler.cpp

@@ -845,6 +845,8 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, std::string & src
 		b.type = Bonus::ENEMY_DEFENCE_REDUCTION; break;
 	case 'C':
 		b.type = Bonus::CHANGES_SPELL_COST_FOR_ALLY; break;
+	case 'd':
+		b.type = Bonus::DEFENSIVE_STANCE; break;
 	case 'e':
 		b.type = Bonus::DOUBLE_DAMAGE_CHANCE; break;
 	case 'E':

+ 3 - 1
lib/CCreatureSet.cpp

@@ -600,6 +600,7 @@ std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const
 				case Bonus::MANA_DRAIN:
 				case Bonus::HP_REGENERATION:
 				case Bonus::ADDITIONAL_RETALIATION:
+				case Bonus::DEFENSIVE_STANCE:
 				case Bonus::DOUBLE_DAMAGE_CHANCE:
 				case Bonus::DARKNESS: //Darkness Dragons any1?
 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))));
@@ -694,7 +695,8 @@ std::string CStackInstance::bonusToGraphics(Bonus *bonus) const
 			fileName = "E_DBLOW.bmp"; break;
 		case Bonus::DEATH_STARE:
 			fileName = "E_DEATH.bmp"; break;
-			//"E_DEFBON.bmp"
+		case Bonus::DEFENSIVE_STANCE:
+			fileName = "E_DEFBON.bmp"; break;
 		case Bonus::NO_DISTANCE_PENALTY:
 			fileName = "E_DIST.bmp"; break;
 		case Bonus::ADDITIONAL_ATTACK:

+ 1 - 0
lib/HeroBonus.h

@@ -125,6 +125,7 @@ namespace PrimarySkill
 	BONUS_NAME(ENEMY_DEFENCE_REDUCTION) /*in % (value) eg. behemots*/ \
 	BONUS_NAME(GENERAL_DAMAGE_REDUCTION) /* shield / air shield effect */ \
 	BONUS_NAME(GENERAL_ATTACK_REDUCTION) /*eg. while stoned or blinded - in %, subtype: -1 - any damage, 0 - melee damage, 1 - ranged damage*/ \
+	BONUS_NAME(DEFENSIVE_STANCE) /* val - bonus to defense while defending */ \
 	BONUS_NAME(ATTACKS_ALL_ADJACENT) /*eg. hydra*/		\
 	BONUS_NAME(MORE_DAMAGE_FROM_SPELL) /*value - damage increase in %, subtype - spell id*/ \
 	BONUS_NAME(FEAR)									\

+ 16 - 11
server/CGameHandler.cpp

@@ -2960,9 +2960,11 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
 		}
 	case BattleAction::DEFEND: //defend
 		{
-			//defensive stance
+			//defensive stance //TODO: remove this bonus when stack becomes active
 			SetStackEffect sse;
 			sse.effect.push_back( Bonus(Bonus::STACK_GETS_TURN, Bonus::PRIMARY_SKILL, Bonus::OTHER, 20, -1, PrimarySkill::DEFENSE, Bonus::PERCENT_TO_ALL) );
+			sse.effect.push_back( Bonus(Bonus::STACK_GETS_TURN, Bonus::PRIMARY_SKILL, Bonus::OTHER, gs->curB->stacks[ba.stackNumber]->valOfBonuses(Bonus::DEFENSIVE_STANCE), 
+				 -1, PrimarySkill::DEFENSE, Bonus::ADDITIVE_VALUE));
 			sse.stacks.push_back(ba.stackNumber);
 			sendAndApply(&sse);
 
@@ -3731,19 +3733,22 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, THex destinati
 			int mirrorChance = (*it)->valOfBonuses(Bonus::MAGIC_MIRROR);
 			if(mirrorChance > rand()%100)
 			{
-			std::vector<CStack *> mirrorTargets;
-			std::vector<CStack *> & battleStacks = gs->curB->stacks;
-			for (int it=0; it < gs->curB->stacks.size(); ++it)
-			{
-				if(battleStacks[it]->owner == casterSide) //get enemy stacks which cna be affected by this spell
+				std::vector<CStack *> mirrorTargets;
+				std::vector<CStack *> & battleStacks = gs->curB->stacks;
+				for (int it=0; it < gs->curB->stacks.size(); ++it)
+				{
+					if(battleStacks[it]->owner == casterSide) //get enemy stacks which cna be affected by this spell
+					{
+						if (!gs->curB->battleIsImmune(NULL, spell, SpellCasting::MAGIC_MIRROR, battleStacks[it]->position))
+							mirrorTargets.push_back(battleStacks[it]);
+					}
+				}
+				if (mirrorTargets.size())
 				{
-					if (!gs->curB->battleIsImmune(NULL, spell, SpellCasting::MAGIC_MIRROR, battleStacks[it]->position))
-						mirrorTargets.push_back(battleStacks[it]);
+					int targetHex = mirrorTargets[rand() % mirrorTargets.size()]->position;
+					handleSpellCasting(spellID, 0, targetHex, 1 - casterSide, (*it)->owner, NULL, (caster ? caster : NULL), usedSpellPower, SpellCasting::MAGIC_MIRROR, (*it));
 				}
 			}
-				int targetHex = mirrorTargets[rand() % mirrorTargets.size()]->position;
-				handleSpellCasting(spellID, 0, targetHex, 1 - casterSide, (*it)->owner, NULL, (caster ? caster : NULL), usedSpellPower, SpellCasting::MAGIC_MIRROR, (*it));
-			}
 		}
 	}
 }