浏览代码

Further victory conditions supported:
Transport artifact
Find artifact
Gather army
Gather resource
Build city

Michał W. Urbańczyk 15 年之前
父节点
当前提交
6803d08c6c
共有 6 个文件被更改,包括 60 次插入12 次删除
  1. 2 1
      client/Client.cpp
  2. 1 1
      hch/CObjectHandler.cpp
  3. 13 6
      lib/CGameState.cpp
  4. 2 2
      lib/map.h
  5. 34 2
      server/CGameHandler.cpp
  6. 8 0
      server/CGameHandler.h

+ 2 - 1
client/Client.cpp

@@ -190,7 +190,8 @@ void CClient::endGame()
 {
 	tlog0 << "\n\nEnding current game!" << std::endl;
 	GH.curInt = NULL;
-	GH.topInt()->deactivate();
+	if(GH.topInt())
+		GH.topInt()->deactivate();
 	GH.listInt.clear();
 	GH.objsToBlit.clear();
 

+ 1 - 1
hch/CObjectHandler.cpp

@@ -1242,7 +1242,7 @@ bool CGHeroInstance::hasArt( ui32 aid ) const
 		if(i->second == aid)
 			return true;
 
-	return true;
+	return false;
 }
 
 void CGDwelling::initObj()

+ 13 - 6
lib/CGameState.cpp

@@ -2961,7 +2961,7 @@ int CGameState::victoryCheck( ui8 player ) const
 				{
 					const CArmedInstance *ai = NULL;
 					if(map->objects[i] 
-						&& map->objects[i]->tempOwner  //object controlled by player
+						&& map->objects[i]->tempOwner == player //object controlled by player
 						&&  (ai = dynamic_cast<const CArmedInstance*>(map->objects[i]))) //contains army
 					{
 						for(TSlots::const_iterator i=ai->army.slots.begin(); i!=ai->army.slots.end(); ++i) //iterate through army
@@ -2982,11 +2982,11 @@ int CGameState::victoryCheck( ui8 player ) const
 			break;
 
 		case buildCity:
-			for(size_t i = 0; i < map->towns.size(); i++)
-				if(map->towns[i]->pos == map->victoryCondition.pos
-					&& map->towns[i]->tempOwner == player 
-					&& map->towns[i]->hallLevel() >= map->victoryCondition.ID)
+			{
+				const CGTownInstance *t = static_cast<const CGTownInstance *>(map->victoryCondition.obj);
+				if(t->tempOwner == player && t->fortLevel()-1 >= map->victoryCondition.ID && t->hallLevel()-1 >= map->victoryCondition.count)
 					return 1;
+			}
 			break;
 
 		case buildGrail:
@@ -3041,7 +3041,14 @@ int CGameState::victoryCheck( ui8 player ) const
 			return 1;
 			break;
 		case transportItem:
-			//TODO
+			{
+				const CGTownInstance *t = static_cast<const CGTownInstance *>(map->victoryCondition.obj);
+				if(t->visitingHero && t->visitingHero->hasArt(map->victoryCondition.ID)
+					|| t->garrisonHero && t->garrisonHero->hasArt(map->victoryCondition.ID))
+				{
+					return 1;
+				}
+			}
 			break;
  		}
 	}

+ 2 - 2
lib/map.h

@@ -157,8 +157,8 @@ struct DLL_EXPORT CVictoryCondition
 	ui8 allowNormalVictory, appliesToAI;
 
 	int3 pos; //pos of city to upgrade (3); pos of town to build grail, {-1,-1,-1} if not relevant (4); hero pos (5); town pos(6); monster pos (7); destination pos(8)
-	ui32 ID; //artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8)
-	ui32 count; //needed count for creatures (1) / resource (2); upgraded town hall level (3); 
+	si32 ID; //artifact ID (0); monster ID (1); resource ID (2); needed fort level in upgraded town (3); artifact ID (8)
+	si32 count; //needed count for creatures (1) / resource (2); upgraded town hall level (3); 
 
 	const CGObjectInstance *obj; //object of specific monster / city / hero instance (NULL if not used); set during map parsing
 

+ 34 - 2
server/CGameHandler.cpp

@@ -1666,8 +1666,12 @@ void CGameHandler::heroVisitCastle(int obj, int heroID)
 	vc.tid = obj;
 	vc.flags |= 1;
 	sendAndApply(&vc);
-	vistiCastleObjects (getTown(obj), getHero(heroID));
+	const CGHeroInstance *h = getHero(heroID);
+	vistiCastleObjects (getTown(obj), h);
 	giveSpells (getTown(obj), getHero(heroID));
+
+	if(gs->map->victoryCondition.condition == transportItem)
+		checkLossVictory(h->tempOwner); //transported artifact?
 }
 
 void CGameHandler::vistiCastleObjects (const CGTownInstance *t, const CGHeroInstance *h)
@@ -1879,6 +1883,34 @@ void CGameHandler::sendAndApply( CPackForClient * info )
 	sendToAllClients(info);
 }
 
+void CGameHandler::sendAndApply( SetGarrisons * info )
+{
+	sendAndApply((CPackForClient*)info);
+	if(gs->map->victoryCondition.condition == gatherTroop)
+		for(std::map<ui32,CCreatureSet>::const_iterator i = info->garrs.begin(); i != info->garrs.end(); i++)
+			checkLossVictory(getObj(i->first)->tempOwner);
+}
+
+void CGameHandler::sendAndApply( SetResource * info )
+{
+	sendAndApply((CPackForClient*)info);
+	if(gs->map->victoryCondition.condition == gatherResource)
+		checkLossVictory(info->player);
+}
+
+void CGameHandler::sendAndApply( SetResources * info )
+{
+	sendAndApply((CPackForClient*)info);
+	if(gs->map->victoryCondition.condition == gatherResource)
+		checkLossVictory(info->player);
+}
+
+void CGameHandler::sendAndApply( NewStructures * info )
+{
+	sendAndApply((CPackForClient*)info);
+	if(gs->map->victoryCondition.condition == buildCity)
+		checkLossVictory(getTown(info->tid)->tempOwner);
+}
 void CGameHandler::save( const std::string &fname )
 {
 	{
@@ -3506,7 +3538,7 @@ void CGameHandler::getLossVicMessage( ui8 player, bool standard, bool victory, I
 			{
 			case artifact:
 				out.text.addTxt(MetaString::GENERAL_TXT, 280); //Congratulations! You have found the %s, and can claim victory!
-				out.text.addReplacement(MetaString::ART_NAMES,gs->map->victoryCondition.obj->subID); //artifact name
+				out.text.addReplacement(MetaString::ART_NAMES,gs->map->victoryCondition.ID); //artifact name
 				break;
 			case gatherTroop:
 				out.text.addTxt(MetaString::GENERAL_TXT, 276); //Congratulations! You have over %d %s in your armies. Your enemies have no choice but to bow down before your power!

+ 8 - 0
server/CGameHandler.h

@@ -31,6 +31,10 @@ struct BattleAttack;
 struct BattleStackAttacked;
 struct CPack;
 struct Query;
+struct SetGarrisons;
+struct SetResource;
+struct SetResources;
+struct NewStructures;
 class CGHeroInstance;
 extern std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback functions - for selection dialogs
 extern boost::mutex gsm;
@@ -185,6 +189,10 @@ public:
 	void ask(Query * sel, ui8 player, const CFunctionList<void(ui32)> &callback);
 	void sendToAllClients(CPackForClient * info);
 	void sendAndApply(CPackForClient * info);
+	void sendAndApply(SetGarrisons * info);
+	void sendAndApply(SetResource * info);
+	void sendAndApply(SetResources * info);
+	void sendAndApply(NewStructures * info);
 
 	void run(bool resume);
 	void newTurn();