Explorar el Código

Fixes for random creature spawns. VCMI will display info about different weeks (though they are not supported yet).

DjWarmonger hace 15 años
padre
commit
70a158ba55
Se han modificado 3 ficheros con 82 adiciones y 25 borrados
  1. 3 0
      lib/NetPacks.h
  2. 2 0
      lib/NetPacksLib.cpp
  3. 77 25
      server/CGameHandler.cpp

+ 3 - 0
lib/NetPacks.h

@@ -690,6 +690,8 @@ struct SetAvailableArtifacts  : public CPackForClient //519
 
 struct NewTurn : public CPackForClient //101
 {
+	enum weekType {NORMAL, DOUBLE_GROWTH, BONUS_GROWTH, PLAGUE, CUSTOM};
+
 	DLL_EXPORT void applyGs(CGameState *gs);
 
 	struct Hero
@@ -708,6 +710,7 @@ struct NewTurn : public CPackForClient //101
 	std::vector<SetAvailableCreatures> cres;//creatures to be placed in towns
 	ui32 day;
 	bool resetBuilded;
+	weekType specialWeek;
 
 	NewTurn(){type = 101;};
 

+ 2 - 0
lib/NetPacksLib.cpp

@@ -633,8 +633,10 @@ DLL_EXPORT void NewTurn::applyGs( CGameState *gs )
 		h->bonuses.remove_if(Bonus::OneDay);
 
 	if(gs->getDate(1) == 1) //new week, Monday that is
+	{
 		BOOST_FOREACH(CGHeroInstance *h, gs->map->heroes)
 			h->bonuses.remove_if(Bonus::OneWeek);
+	}
 
 	//count days without town
 	for( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)

+ 77 - 25
server/CGameHandler.cpp

@@ -57,8 +57,7 @@ extern bool end2;
 
 CondSh<bool> battleMadeAction;
 CondSh<BattleResult *> battleResult(NULL);
-boost::rand48 ran; //TODO: Use common (external?) function for it
-std::ptrdiff_t randomizer (ptrdiff_t i) {return ran();}
+std::ptrdiff_t randomizer (ptrdiff_t i) {return rand();}
 std::ptrdiff_t (*p_myrandom)(std::ptrdiff_t) = randomizer;
 
 class CBaseForGHApply
@@ -1149,6 +1148,82 @@ void CGameHandler::newTurn()
 		pickAllowedArtsSet(saa.arts);
 		sendAndApply(&saa);
 	}
+	if (getDate(1) == 7 && getDate(0)>1) //new week (day numbers are confusing, as day was not yet switched)
+	{
+		int monsterid;
+		bool newmonth;
+		int monthType = rand()%100;
+		if(getDate(4) == 28) //new month
+		{
+			newmonth = true;
+			if (monthType < 60) //double growth
+			{
+				//spawn wandering monsters
+				n.specialWeek = NewTurn::DOUBLE_GROWTH;
+				std::vector<int3>::iterator tile;
+				std::vector<int3> tiles;
+				getFreeTiles(tiles);
+				ui32 amount = (tiles.size()) >> 6;
+				std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom);
+
+				std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(rand)));
+				monsterid = newMonster.second;
+				for (int i = 0; i < amount; ++i)
+				{
+					tile = tiles.begin();
+					TerrainTile *tinfo = &gs->map->terrain[tile->x][tile->y][tile->z];
+					NewObject no;
+					no.ID = newMonster.first;
+					no.subID= newMonster.second;
+					no.pos = *tile;
+					sendAndApply(&no);
+					tiles.erase(tile); //not use it again
+				}
+			}
+			else if (monthType < 98)
+				n.specialWeek = NewTurn::NORMAL;
+			else
+				n.specialWeek = NewTurn::PLAGUE;
+		}
+		else //it's a week, but not full month
+		{
+			newmonth = false;
+			if (monthType < 20)
+			{
+				n.specialWeek = NewTurn::BONUS_GROWTH; //+5
+				std::pair<int,int> newMonster (54, VLC->creh->pickRandomMonster(boost::ref(rand)));
+				monsterid = newMonster.second;
+			}
+		}
+
+		InfoWindow iw;
+		int msgid;
+		switch (n.specialWeek)
+		{
+			case NewTurn::DOUBLE_GROWTH:
+				iw.text.addTxt(MetaString::ARRAY_TXT, 131);
+				iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
+				iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
+				break;
+			case NewTurn::PLAGUE:
+				iw.text.addTxt(MetaString::ARRAY_TXT, 132);
+				break;
+			case NewTurn::BONUS_GROWTH:
+				iw.text.addTxt(MetaString::ARRAY_TXT, 134);
+				iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
+				iw.text.addReplacement(MetaString::CRE_SING_NAMES, monsterid);
+				break;
+			default:
+				iw.text.addTxt(MetaString::ARRAY_TXT, (newmonth ? 130 : 133));
+				iw.text.addReplacement(MetaString::ARRAY_TXT, 43 + rand()%15);
+		}
+
+		for (std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end(); i++)
+		{
+			iw.player = i->first;
+			sendAndApply(&iw);
+		}
+	}
 
 	sendAndApply(&n);
 	tlog5 << "Info about turn " << n.day << "has been sent!" << std::endl;
@@ -1160,29 +1235,6 @@ void CGameHandler::newTurn()
 			gs->map->objects[i]->newTurn();
 	}
 
-	if(getDate(4) == 1 && getDate(0)>1) //new month
-	{
-		//spawn wandering monsters
-		std::vector<int3>::iterator tile;
-		std::vector<int3> tiles;
-		getFreeTiles(tiles);
-		ui32 amount = (tiles.size()) >> 6;
-		std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom);
-
-		std::pair<int,int> newMonster(54, VLC->creh->pickRandomMonster(boost::ref(ran)));
-		for (int i = 0; i < amount; ++i)
-		{
-			tile = tiles.begin();
-			TerrainTile *tinfo = &gs->map->terrain[tile->x][tile->y][tile->z];
-			NewObject no;
-			no.ID = newMonster.first;
-			no.subID = newMonster.second;
-			no.pos = *tile;
-			sendAndApply(&no);
-			tiles.erase(tile); //not use it again
-		}
-	}
-
 	winLoseHandle(0xff);
 
 	//warn players without town