浏览代码

* battle should now end automatically when last stack of one of sides is killed by a spell
* minor changes

mateuszb 16 年之前
父节点
当前提交
7382314dfd
共有 8 个文件被更改,包括 39 次插入16 次删除
  1. 1 1
      hch/CLodHandler.cpp
  2. 1 1
      hch/CLodHandler.h
  3. 1 1
      hch/CObjectHandler.cpp
  4. 1 1
      hch/CObjectHandler.h
  5. 1 1
      lib/CGameState.cpp
  6. 1 1
      lib/CGameState.h
  7. 28 10
      server/CGameHandler.cpp
  8. 5 0
      server/CGameHandler.h

+ 1 - 1
hch/CLodHandler.cpp

@@ -275,7 +275,7 @@ void CLodHandler::extractFile(std::string FName, std::string name)
 	}
 }
 
-int CLodHandler::readNormalNr (unsigned char* bufor, int bytCon, bool cyclic)
+int CLodHandler::readNormalNr (const unsigned char* bufor, int bytCon, bool cyclic)
 {
 	int ret=0;
 	int amp=1;

+ 1 - 1
hch/CLodHandler.h

@@ -60,7 +60,7 @@ public:
 
 	CLodHandler();
 	~CLodHandler();
-	int readNormalNr (unsigned char* bufor, int bytCon, bool cyclic=false); //lod header reading helper
+	int readNormalNr (const unsigned char* bufor, int bytCon, bool cyclic=false); //lod header reading helper
 	int infs(unsigned char * in, int size, int realSize, std::ofstream & out, int wBits=15); //zlib fast handler
 	int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler
 	unsigned char * giveFile(std::string defName, int * length=NULL); //returns pointer to the decompressed data - it must be deleted when no longer needed!

+ 1 - 1
hch/CObjectHandler.cpp

@@ -1050,7 +1050,7 @@ bool CGHeroInstance::canCastThisSpell(const CSpell * spell) const
  * type and second value the amount. Both values are returned as -1 if necromancy
  * could not be applied.
  */
-std::pair<ui32, si32> CGHeroInstance::calculateNecromancy (BattleResult &battleResult) const
+std::pair<ui32, si32> CGHeroInstance::calculateNecromancy (const BattleResult &battleResult) const
 {
 	const ui8 necromancyLevel = getSecSkillLevel(12);
 

+ 1 - 1
hch/CObjectHandler.h

@@ -297,7 +297,7 @@ public:
 	int getTotalStrength() const;
 	ui8 getSpellSchoolLevel(const CSpell * spell) const; //returns level on which given spell would be cast by this hero
 	bool canCastThisSpell(const CSpell * spell) const; //determines if this hero can cast given spell; takes into account existing spell in spellbook, existing spellbook and artifact bonuses
-	std::pair<ui32, si32> calculateNecromancy (BattleResult &battleResult) const;
+	std::pair<ui32, si32> calculateNecromancy (const BattleResult &battleResult) const;
 	void showNecromancyDialog (std::pair<ui32, si32> raisedStack) const;
 
 	//////////////////////////////////////////////////////////////////////////

+ 1 - 1
lib/CGameState.cpp

@@ -972,7 +972,7 @@ std::pair<int,int> CGameState::pickObject(CGObjectInstance *obj)
 	switch(obj->ID)
 	{
 	case 65: //random artifact
-		return std::pair<int,int>(5,(ran()%136)+7); //tylko sensowny zakres - na poczatku sa katapulty itp, na koncu specjalne i blanki
+		return std::pair<int,int>(5,(ran()%136)+7); //the only reasonable range - there are siege weapons and blanks we must ommit
 	case 66: //random treasure artifact
 		return std::pair<int,int>(5,VLC->arth->treasures[ran()%VLC->arth->treasures.size()]->id);
 	case 67: //random minor artifact

+ 1 - 1
lib/CGameState.h

@@ -335,7 +335,7 @@ public:
 	void init(StartInfo * si, Mapa * map, int Seed);
 	void loadTownDInfos();
 	void randomizeObject(CGObjectInstance *cur);
-	std::pair<int,int> pickObject(CGObjectInstance *obj);
+	std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
 	int pickHero(int owner);
 	void apply(CPack *pack);
 	CGHeroInstance *getHero(int objid);

+ 28 - 10
server/CGameHandler.cpp

@@ -318,6 +318,9 @@ static CCreatureSet takeCasualties(int color, const CCreatureSet &set, BattleInf
 
 void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town)
 {
+	battleEndCallback = new boost::function<void(BattleResult*)>(cb);
+	bEndArmy1 = army1;
+	bEndArmy2 = army2;
 	{
 		BattleInfo *curB = new BattleInfo;
 		curB->side1 = army1->tempOwner;
@@ -465,20 +468,26 @@ askInterfaceForMove:
 		}
 	}
 
+	endBattle(tile, hero1, hero2);
+
+}
+
+void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2)
+{
 	BattleResultsApplied resultsApplied;
-	resultsApplied.player1 = army1->tempOwner;
-	resultsApplied.player2 = army2->tempOwner;
+	resultsApplied.player1 = bEndArmy1->tempOwner;
+	resultsApplied.player2 = bEndArmy2->tempOwner;
 
 	//unblock engaged players
-	if(army1->tempOwner<PLAYER_LIMIT)
-		states.setFlag(army1->tempOwner,&PlayerStatus::engagedIntoBattle,false);
-	if(army2 && army2->tempOwner<PLAYER_LIMIT)
-		states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,false);	
+	if(bEndArmy1->tempOwner<PLAYER_LIMIT)
+		states.setFlag(bEndArmy1->tempOwner, &PlayerStatus::engagedIntoBattle, false);
+	if(bEndArmy2 && bEndArmy2->tempOwner<PLAYER_LIMIT)
+		states.setFlag(bEndArmy2->tempOwner, &PlayerStatus::engagedIntoBattle, false);	
 
 	//casualties among heroes armies
 	SetGarrisons sg;
-	sg.garrs[army1->id] = takeCasualties(army1->tempOwner,army1->army,gs->curB);
-	sg.garrs[army2->id] = takeCasualties(army2->tempOwner,army2->army,gs->curB);
+	sg.garrs[bEndArmy1->id] = takeCasualties(bEndArmy1->tempOwner, bEndArmy1->army, gs->curB);
+	sg.garrs[bEndArmy2->id] = takeCasualties(bEndArmy2->tempOwner, bEndArmy2->army, gs->curB);
 	sendAndApply(&sg);
 
 	//end battle, remove all info, free memory
@@ -503,8 +512,12 @@ askInterfaceForMove:
 	if(battleResult.data->exp[1] && hero2)
 		changePrimSkill(hero2->id,4,battleResult.data->exp[1]);
 
-	if(cb)
-		cb(battleResult.data);
+	if(battleEndCallback && *battleEndCallback)
+	{
+		(*battleEndCallback)(battleResult.data);
+		delete battleEndCallback;
+		battleEndCallback = 0;
+	}
 
 	sendAndApply(&resultsApplied);
 
@@ -3150,6 +3163,11 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 				}
 			}
 			sendAndApply(&EndAction());
+			checkForBattleEnd(gs->curB->stacks);
+			if(battleResult.get())
+			{
+				endBattle(gs->curB->tile, getHero(gs->curB->hero1), getHero(gs->curB->hero2));
+			}
 			return true;
 		}
 	}

+ 5 - 0
server/CGameHandler.h

@@ -85,6 +85,11 @@ public:
 	void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
 	int moveStack(int stack, int dest); //returned value - travelled distance
 	void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
+	////used only in endBattle - don't touch elsewhere
+	boost::function<void(BattleResult*)> * battleEndCallback;
+	const CArmedInstance * bEndArmy1, * bEndArmy2;
+	//
+	void endBattle(int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2); //ends battle
 	void prepareAttack(BattleAttack &bat, const CStack *att, const CStack *def, int distance); //distance - number of hexes travelled before attacking
 	void prepareAttacked(BattleStackAttacked &bsa, const CStack *def);
 	void checkForBattleEnd( std::vector<CStack*> &stacks );