Browse Source

Added prisons. hero experience is set to zero due to problem with leveling http://bugs.vcmi.eu/view.php?id=1804

DjWarmonger 11 years ago
parent
commit
e65b85873c
3 changed files with 65 additions and 0 deletions
  1. 22 0
      lib/rmg/CMapGenerator.cpp
  2. 6 0
      lib/rmg/CMapGenerator.h
  3. 37 0
      lib/rmg/CRmgTemplateZone.cpp

+ 22 - 0
lib/rmg/CMapGenerator.cpp

@@ -67,18 +67,31 @@ CMapGenerator::~CMapGenerator()
 	}
 }
 
+void CMapGenerator::initPrisonsRemaining()
+{
+	prisonsRemaining = 0;
+	for (auto isAllowed : map->allowedHeroes)
+	{
+		if (isAllowed)
+			prisonsRemaining++;
+	}
+	prisonsRemaining = std::max<int> (0, prisonsRemaining - 16 * map->players.size()); //so at least 16 heroes will be available for every player
+}
+
 std::unique_ptr<CMap> CMapGenerator::generate()
 {
 	mapGenOptions->finalize(rand);
 
 	map = make_unique<CMap>();
 	editManager = map->getEditManager();
+
 	try
 	{
 		editManager->getUndoManager().setUndoRedoLimit(0);
 		addHeaderInfo();
 		initTiles();
 
+		initPrisonsRemaining();
 		genZones();
 		map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
 		fillZones();
@@ -451,6 +464,15 @@ int CMapGenerator::getNextMonlithIndex()
 		return monolithIndex++;
 }
 
+int CMapGenerator::getPrisonsRemaning() const
+{
+	return prisonsRemaining;
+}
+void CMapGenerator::decreasePrisonsRemaining()
+{
+	prisonsRemaining = std::max (0, prisonsRemaining--);
+}
+
 void CMapGenerator::registerZone (TFaction faction)
 {
 	zonesPerFaction[faction]++;

+ 6 - 0
lib/rmg/CMapGenerator.h

@@ -78,6 +78,9 @@ public:
 	void setNearestObjectDistance(int3 &tile, int value);
 
 	int getNextMonlithIndex();
+	int getPrisonsRemaning() const;
+	void decreasePrisonsRemaining();
+
 	void registerZone (TFaction faction);
 	ui32 getZoneCount(TFaction faction);
 	ui32 getTotalZoneCount() const;
@@ -89,10 +92,13 @@ private:
 
 	CTileInfo*** tiles;
 
+	int prisonsRemaining;
 	int monolithIndex;
 
 	/// Generation methods
 	std::string getMapDescription() const;
+
+	void initPrisonsRemaining();
 	void addPlayerInfo();
 	void addHeaderInfo();
 	void initTiles();

+ 37 - 0
lib/rmg/CRmgTemplateZone.cpp

@@ -1653,6 +1653,43 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
 		} 
 	}
 
+	//prisons
+	//levels 1, 5, 10, 20, 30
+	static int prisonExp[] = {0, 5000, 15000, 90000, 500000};
+	static int prisonValues[] = {2500, 5000, 10000, 20000, 30000};
+
+	for (int i = 0; i < 5; i++)
+	{
+		oi.generateObject = [i, gen]() -> CGObjectInstance *
+		{
+			auto obj = new CGHeroInstance;
+			obj->ID = Obj::PRISON;
+
+			std::vector<ui32> possibleHeroes;
+			for (int j = 0; j < gen->map->allowedHeroes.size(); j++)
+			{
+				if (gen->map->allowedHeroes[j])
+					possibleHeroes.push_back(j);
+			}
+
+			auto hid = *RandomGeneratorUtil::nextItem(possibleHeroes, gen->rand);
+			obj->initHero (HeroTypeID(hid));
+			obj->subID = 0; //initHero overrides it :?
+			//obj->exp = prisonExp[i]; //game crashes at hero level up
+			obj->exp = 0;
+			obj->setOwner(PlayerColor::NEUTRAL);
+			gen->map->allowedHeroes[hid] = false; //ban this hero
+			gen->decreasePrisonsRemaining();
+
+			return obj;
+		};
+		oi.setTemplate (Obj::PRISON, 0, terrainType);
+		oi.value = prisonValues[i];
+		oi.probability = 30;
+		oi.maxPerZone = gen->getPrisonsRemaning() / 5; //probably not perfect, but we can't generate more prisons than hereos.
+		possibleObjects.push_back (oi);
+	}
+
 	//all following objects are unlimited
 	oi.maxPerZone = std::numeric_limits<ui32>().max();