Просмотр исходного кода

A little progress with Eagle Eye and Tactics.

Michał W. Urbańczyk 14 лет назад
Родитель
Сommit
0c700f97cd

+ 15 - 4
client/CBattleInterface.cpp

@@ -1106,6 +1106,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	pos = myRect;
 	strongInterest = true;
 	givenCommand = new CondSh<BattleAction *>(NULL);
+	tacticsMode = curInt->cb->battleGetTacticDist();
 	
 	//create stack queue
 	bool embedQueue = screen->h < 700;
@@ -1214,7 +1215,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 	console->pos.y = 560 + pos.y;
 	console->pos.w = 406;
 	console->pos.h = 38;
-	if(curInt->cb->battleGetTacticDist())
+	if(tacticsMode)
 	{
 		btactNext = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bTacticNextStack,this), 213 + pos.x, 560 + pos.y, "icm011.def", SDLK_SPACE);
 		btactEnd = new AdventureMapButton(std::string(), std::string(), boost::bind(&CBattleInterface::bEndTacticPhase,this), 419 + pos.x, 560 + pos.y, "icm012.def", SDLK_RETURN);
@@ -2347,9 +2348,19 @@ void CBattleInterface::giveCommand(ui8 action, THex tile, ui32 stack, si32 addit
 		break;
 	}
 
-	myTurn = false;
-	activeStack = NULL;
-	givenCommand->setn(ba);
+	if(!tacticsMode)
+	{
+		myTurn = false;
+		activeStack = NULL;
+		givenCommand->setn(ba);
+	}
+	else
+	{
+		curInt->cb->battleMakeTacticAction(ba);
+		delNull(ba);
+		// TODO:
+		// activate next stack
+	}
 }
 
 bool CBattleInterface::isTileAttackable(const THex & number) const

+ 1 - 0
client/CBattleInterface.h

@@ -400,6 +400,7 @@ private:
 	float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
 	std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
 
+	bool tacticsMode;
 	bool spellDestSelectMode; //if true, player is choosing destination for his spell
 	int spellSelMode; //0 - any location, 1 - any friendly creature, 2 - any hostile creature, 3 - any creature,
 		//4 - obstacle, 5 - teleport -1 - no location

+ 2 - 0
client/CPlayerInterface.cpp

@@ -647,6 +647,7 @@ void CPlayerInterface::battleCatapultAttacked(const CatapultAttack & ca)
 		return;
 	}
 
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	battleInt->stackIsCatapulting(ca);
 }
 
@@ -657,6 +658,7 @@ void CPlayerInterface::battleStacksRemoved(const BattleStacksRemoved & bsr)
 		return;
 	}
 
+	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	for(std::set<ui32>::const_iterator it = bsr.stackIDs.begin(); it != bsr.stackIDs.end(); ++it) //for each removed stack
 	{
 		battleInt->stackRemoved(LOCPLINT->cb->battleGetStackByID(*it));

+ 4 - 2
lib/BattleState.cpp

@@ -1604,6 +1604,8 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int terType, const
 		curB->tacticsSide = diff < 0;
 		curB->tacticDistance = std::abs(diff)*2 + 1;
 	}
+	else
+		curB->tacticDistance = 0;
 
 	return curB;
 }
@@ -1611,8 +1613,8 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int terType, const
 bool BattleInfo::isInTacticRange( THex dest ) const
 {
 
-	return ((tacticsSide && dest.getX() > 0 && dest.getX() <= tacticDistance)
-		|| (!tacticsSide && dest.getX() < BFIELD_WIDTH - 1 && dest.getX() >= BFIELD_WIDTH - tacticDistance - 1));
+	return ((!tacticsSide && dest.getX() > 0 && dest.getX() <= tacticDistance)
+		|| (tacticsSide && dest.getX() < BFIELD_WIDTH - 1 && dest.getX() >= BFIELD_WIDTH - tacticDistance - 1));
 }
 
 CStack::CStack(const CStackInstance *Base, int O, int I, bool AO, int S)

+ 39 - 42
server/CGameHandler.cpp

@@ -331,6 +331,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	const CArmedInstance *bEndArmy2 = gs->curB->belligerents[1];
 	resultsApplied.player1 = bEndArmy1->tempOwner;
 	resultsApplied.player2 = bEndArmy2->tempOwner;
+	const CGHeroInstance *victoriousHero = gs->curB->heroes[battleResult.data->winner];
 
 	if(!duel)
 	{
@@ -356,60 +357,56 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	ui8 loser = sides[!battleResult.data->winner];
 
 	CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
+	ChangeSpells cs; //for Eagle Eye
 
-
-	sendAndApply(battleResult.data);
-
-	//Eagle Eye secondary skill handling
-	/*const CGHeroInstance *vistoriousHero = gs->curB->heroes[battleResult.data->winner];
-	if(0 && vistoriousHero)
+	if(victoriousHero)
 	{
-		if(int eagleEyeLevel = vistoriousHero->getSecSkillLevel(CGHeroInstance::EAGLE_EYE))
+		if(int eagleEyeLevel = victoriousHero->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;
-
+			double eagleEyeChance = victoriousHero->valOfBonuses(Bonus::SECONDARY_SKILL_PREMY, CGHeroInstance::EAGLE_EYE);
 			BOOST_FOREACH(const CSpell *sp, gs->curB->usedSpellsHistory[!battleResult.data->winner])
-				if(rand() % 100 < eagleEyeChance)
+				if(sp->level <= maxLevel && !vstd::contains(victoriousHero->spells, sp->id) && 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);
+	sendAndApply(battleResult.data);
 
-				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";
-				}
+	//Eagle Eye secondary skill handling
+	/*if(cs.spells.size())
+	{
+		cs.learn = 1;
+		cs.hid = victoriousHero->id;
 
-				iw.text.addReplacement(names.str());
+		InfoWindow iw;
+		iw.text.addTxt(MetaString::GENERAL_TXT, 221); //Through eagle-eyed observation, %s is able to learn %s
+		iw.text.addReplacement(victoriousHero->name);
 
-				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));
-				}
+		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";
+		}
 
-				sendAndApply(&iw);
-				sendAndApply(&cs);
-			}
+		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)
 	{

+ 7 - 5
server/NetPacksServer.cpp

@@ -208,16 +208,18 @@ bool QueryReply::applyGh( CGameHandler *gh )
 
 bool MakeAction::applyGh( CGameHandler *gh )
 {
-	if(!GS(gh)->curB) ERROR_AND_RETURN;
-	if(gh->connections[GS(gh)->curB->getStack(GS(gh)->curB->activeStack)->owner] != c) ERROR_AND_RETURN;
-
-	if(GS(gh)->curB->tacticDistance)
+	const BattleInfo *b = GS(gh)->curB;
+	if(!b) ERROR_AND_RETURN;
+	
+	if(b->tacticDistance)
 	{
 		if(ba.actionType != BattleAction::WALK  &&  ba.actionType != BattleAction::END_TACTIC_PHASE)
 			ERROR_AND_RETURN;
-		if(gh->connections[GS(gh)->curB->sides[GS(gh)->curB->tacticsSide]] != c) 
+		if(gh->connections[b->sides[b->tacticsSide]] != c) 
 			ERROR_AND_RETURN;
 	}
+	else if(gh->connections[b->getStack(b->activeStack)->owner] != c) 
+		ERROR_AND_RETURN;
 
 	return gh->makeBattleAction(ba);
 }