Quellcode durchsuchen

1. Better way to disable stack / cursor glitches
2. An attempt to handle looting artifacts after battle

DjWarmonger vor 13 Jahren
Ursprung
Commit
2fbc57e140

+ 5 - 3
client/BattleInterface/CBattleInterface.cpp

@@ -1989,6 +1989,8 @@ void CBattleInterface::endCastingSpell()
 	CCS->curh->changeGraphic(1, 6);
 
 	//restore actions for current stack
+	if (!activeStack)
+		activateStack();
 	getPossibleActionsForStack (activeStack);
 }
 
@@ -2476,8 +2478,6 @@ void CBattleInterface::showQueue()
 
 void CBattleInterface::startAction(const BattleAction* action)
 {
-	possibleActions.clear(); //no random interface calls for inactive stack
-
 	if(action->actionType == BattleAction::END_TACTIC_PHASE)
 	{
 		SDL_FreeSurface(menu);
@@ -2528,7 +2528,7 @@ void CBattleInterface::startAction(const BattleAction* action)
 
 	char txt[400];
 
-	if(action->actionType == BattleAction::HERO_SPELL) //when hero casts spell
+	if (action->actionType == BattleAction::HERO_SPELL) //when hero casts spell
 	{
 		if(action->side)
 			defendingHero->setPhase(4);
@@ -3039,6 +3039,8 @@ void CBattleInterface::handleHex(BattleHex myNumber, int eventType)
 							spellToCast->destinationTile = myNumber;
 							break;
 					}
+					activeStack = NULL; //disable interface checks for active stack
+
 					curInt->cb->battleMakeAction(spellToCast);
 					endCastingSpell();
 				}

+ 5 - 0
lib/CCreatureSet.cpp

@@ -975,6 +975,11 @@ CCommanderInstance::~CCommanderInstance()
 
 }
 
+void CCommanderInstance::setAlive (bool Alive)
+{
+	alive = Alive;
+}
+
 CStackBasicDescriptor::CStackBasicDescriptor()
 {
 	type = NULL;

+ 1 - 0
lib/CCreatureSet.h

@@ -87,6 +87,7 @@ public:
 	CCommanderInstance();
 	CCommanderInstance (TCreature id);
 	~CCommanderInstance();
+	void setAlive (bool alive);
 
 	ui64 getPower() const {return 0;};
 	int getExpRank() const {return 0;};

+ 4 - 1
lib/NetPacks.h

@@ -847,6 +847,7 @@ typedef si32 TArtPos;
 struct ArtifactLocation
 {
 	typedef boost::variant<ConstTransitivePtr<CGHeroInstance>, ConstTransitivePtr<CStackInstance> > TArtHolder;
+	//, ConstTransitivePtr<CCommanderInstance> ?
 
 	TArtHolder artHolder;
 	TArtPos slot;
@@ -1228,11 +1229,13 @@ struct BattleSetActiveStack : public CPackForClient//3002
 };
 struct BattleResult : public CPackForClient//3003
 {
+	enum EResult {NORMAL = 0, ESCAPE = 1, SURRENDER = 2};
+
 	BattleResult(){type = 3003;};
 	void applyFirstCl(CClient *cl);
 	void applyGs(CGameState *gs);
 
-	ui8 result; //0 - normal victory; 1 - escape; 2 - surrender
+	ui8 result; //EResult values
 	ui8 winner; //0 - attacker, 1 - defender, [2 - draw (should be possible?)]
 	std::map<ui32,si32> casualties[2]; //first => casualties of attackers - map crid => number
 	expType exp[2]; //exp for attacker and defender

+ 56 - 4
server/CGameHandler.cpp

@@ -342,6 +342,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 	resultsApplied.player2 = bEndArmy2->tempOwner;
 	const CGHeroInstance *victoriousHero = gs->curB->heroes[battleResult.data->winner];
 
+	int result = battleResult.get()->result;
+
 	if(!duel)
 	{
 		//unblock engaged players
@@ -419,8 +421,8 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		sendAndApply(&cs);
 	}
 	// Necromancy if applicable.
-	const CGHeroInstance *winnerHero = battleResult.data->winner != 0 ? hero2 : hero1;
-	const CGHeroInstance *loserHero = battleResult.data->winner != 0 ? hero1 : hero2;
+	ConstTransitivePtr <CGHeroInstance> winnerHero = battleResult.data->winner != 0 ? hero2 : hero1;
+	ConstTransitivePtr <CGHeroInstance> loserHero = battleResult.data->winner != 0 ? hero1 : hero2;
 
 	const CStackBasicDescriptor raisedStack = winnerHero ? winnerHero->calculateNecromancy(*battleResult.data) : CStackBasicDescriptor();
 	// Give raised units to winner and show dialog, if any were raised,
@@ -451,6 +453,57 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 		else
 			afterBattleCallback();
 	}
+	//TODO: check if hero surrended / fled
+	//TODO: display loot in window
+	//if (result < BattleResult::SURRENDER && winnerHero)
+	//{
+	//	if (loserHero)
+	//	{
+	//		BOOST_FOREACH (auto art, loserHero->artifactsWorn)
+	//		{
+	//			if (art.second.artifact)
+	//			{
+	//				MoveArtifact ma; //TODO: put into a function?
+	//				ma.src = ArtifactLocation (loserHero, art.first);
+	//				ma.dst = ArtifactLocation (winnerHero, art.second.artifact->firstAvailableSlot(winnerHero));
+	//				sendAndApply(&ma);
+	//			}
+	//		}
+	//		BOOST_FOREACH (auto art, loserHero->artifactsInBackpack)
+	//		{
+	//			if (art.artifact)
+	//			{
+	//				MoveArtifact ma;
+	//				ma.src = ArtifactLocation (loserHero, loserHero->getArtPos (art.artifact->artType->id, false)); //I smell trouble?
+	//				ma.dst = ArtifactLocation (winnerHero, art.artifact->firstAvailableSlot(winnerHero));
+	//				sendAndApply(&ma);
+	//			}
+	//		}
+	//		if (loserHero->commander) //TODO: what if commanders belong to no hero?
+	//		{
+	//			BOOST_FOREACH (auto art, loserHero->commander->artifactsWorn)
+	//			{
+	//				if (art.second.artifact)
+	//				{
+	//					MoveArtifact ma; //FIXME: boost::variant vs pointer casting is bad solution
+	//					ma.src = ArtifactLocation (ConstTransitivePtr <CStackInstance> (loserHero->commander), art.first);
+	//					ma.dst = ArtifactLocation (winnerHero, art.second.artifact->firstAvailableSlot(winnerHero));
+	//					sendAndApply(&ma);
+	//				}
+	//			}
+	//		}
+	//	}
+	//	BOOST_FOREACH (auto armySlot, gs->curB->belligerents[loser]->stacks)
+	//	{
+	//		MoveArtifact ma;
+	//		ma.src = ArtifactLocation (armySlot.second, (ArtifactPosition::CREATURE_SLOT));
+	//		{
+	//			if (CArtifactInstance * art = ma.src.getArt())
+	//				ma.dst = ArtifactLocation (winnerHero, art->firstAvailableSlot(winnerHero));
+	//			sendAndApply(&ma);
+	//		}
+	//	}
+	//}
 
 	if (necroSlot != -1) 
 	{
@@ -474,8 +527,7 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
 
 	winLoseHandle(1<<sides[0] | 1<<sides[1]); //handle victory/loss of engaged players
 
-	int result = battleResult.get()->result;
-	if(result == 1 || result == 2) //loser has escaped or surrendered
+	if(result < BattleResult::SURRENDER) //loser has escaped or surrendered
 	{
 		SetAvailableHeroes sah;
 		sah.player = loser;