Browse Source

Some work towards Eagle Eye skill support.

Michał W. Urbańczyk 14 years ago
parent
commit
9f90ef58ca
3 changed files with 61 additions and 1 deletions
  1. 3 1
      lib/BattleState.h
  2. 6 0
      lib/NetPacksLib.cpp
  3. 52 0
      server/CGameHandler.cpp

+ 3 - 1
lib/BattleState.h

@@ -58,7 +58,8 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
 	CArmedInstance *belligerents[2]; //may be same as heroes
 	std::vector<CStack*> stacks;
 	std::vector<CObstacleInstance> obstacles;
-	ui8 castSpells[2]; //[0] - attacker, [1] - defender
+	ui8 castSpells[2]; //how many spells each side has cast this turn [0] - attacker, [1] - defender
+	std::vector<const CSpell *> usedSpellsHistory[2]; //each time hero casts spell, it's inserted here -> eagle eye skill 
 	SiegeInfo si;
 	si32 battlefieldType;
 
@@ -67,6 +68,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
 		h & sides & round & activeStack & siege & town & tile & stacks & belligerents & obstacles
 			& castSpells & si & battlefieldType;
 		h & heroes;
+		h & usedSpellsHistory;
 		h & static_cast<CBonusSystemNode&>(*this);
 	}
 

+ 6 - 0
lib/NetPacksLib.cpp

@@ -973,7 +973,13 @@ DLL_EXPORT void StartAction::applyGs( CGameState *gs )
 	CStack *st = gs->curB->getStack(ba.stackNumber);
 
 	if(ba.actionType != BattleAction::HERO_SPELL) //don't check for stack if it's custom action by hero
+	{
 		assert(st);
+	}
+	else
+	{
+		gs->curB->usedSpellsHistory[ba.side].push_back(VLC->spellh->spells[ba.additionalInfo]);
+	}
 
 	switch(ba.actionType)
 	{

+ 52 - 0
server/CGameHandler.cpp

@@ -21,6 +21,7 @@
 #include "../client/CSoundBase.h"
 #include "CGameHandler.h"
 #include <boost/format.hpp>
+#include <sstream>
 
 /*
  * CGameHandler.cpp, part of VCMI engine
@@ -353,6 +354,57 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
 	sendAndApply(battleResult.data);
 
+	//Eagle Eye secondary skill handling
+	const CGHeroInstance *vistoriousHero = gs->curB->heroes[battleResult.data->winner];
+	if(0 && vistoriousHero)
+	{
+		if(int eagleEyeLevel = vistoriousHero->getSecSkillLevel(CGHeroInstance::EAGLE_EYE))
+		{
+			int maxLevel = eagleEyeLevel + 1;
+			double eagleEyeChance = vistoriousHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::EAGLE_EYE);
+			
+			ChangeSpells cs;
+			cs.learn = 1;
+			cs.hid = vistoriousHero->id;
+
+			BOOST_FOREACH(const CSpell *sp, gs->curB->usedSpellsHistory[!battleResult.data->winner])
+				if(rand() % 100 < eagleEyeChance)
+					cs.spells.insert(sp->id);
+
+			if(cs.spells.size())
+			{
+				InfoWindow iw;
+				iw.text.addTxt(MetaString::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s
+				iw.text.addReplacement(vistoriousHero->name);
+
+				std::ostringstream names;
+				for(int i = 0; i < cs.spells.size(); i++)
+				{
+					names << "%s";
+					if(i < cs.spells.size() - 2)
+						names << ", ";
+					else if(i < cs.spells.size() - 1)
+						names << "%s";
+				}
+
+				iw.text.addReplacement(names.str());
+
+				std::set<ui32>::iterator it = cs.spells.begin();
+				for(int i = 0; i < cs.spells.size(); i++, it++)
+				{
+					iw.text.addReplacement(MetaString::SPELL_NAME, *it);
+					if(i == cs.spells.size() - 2) //we just added pre-last name
+						iw.text.addReplacement(MetaString::GENERAL_TXT, 141); // " and "
+					iw.components.push_back(Component(Component::SPELL, *it, 0, 0));
+				}
+
+				sendAndApply(&iw);
+				sendAndApply(&cs);
+			}
+		}
+	}
+
+
 	if(!duel)
 	{
 		cab1.takeFromArmy(this); cab2.takeFromArmy(this); //take casualties after battle is deleted