Jelajahi Sumber

- Zone guards will now match template settings.
- Added guards for monoliths.

DjWarmonger 11 tahun lalu
induk
melakukan
7f31b7dddb

+ 56 - 4
lib/rmg/CMapGenerator.cpp

@@ -218,10 +218,7 @@ void CMapGenerator::fillZones()
 {	
 	logGlobal->infoStream() << "Started filling zones";
 
-	for (auto it : zones)
-	{
-		it.second->createConnections(this);
-	}
+	createConnections();
 	for (auto it : zones)
 	{
 		//make sure all connections are passable before creating borders
@@ -231,6 +228,61 @@ void CMapGenerator::fillZones()
 	logGlobal->infoStream() << "Zones filled successfully";
 }
 
+void CMapGenerator::createConnections()
+{
+	for (auto connection : mapGenOptions->getMapTemplate()->getConnections())
+	{
+		auto zoneA = connection.getZoneA();
+		auto zoneB = connection.getZoneB();
+
+		//rearrange tiles in random order
+		auto tilesCopy = zoneA->getTileInfo();
+		std::vector<int3> tiles(tilesCopy.begin(), tilesCopy.end());
+		//TODO: hwo to use std::shuffle with our generator?
+		//std::random_shuffle (tiles.begin(), tiles.end(), &gen->rand.nextInt);
+
+		int i, n;
+		n = (tiles.end() - tiles.begin());
+		for (i=n-1; i>0; --i)
+		{
+			std::swap (tiles.begin()[i],tiles.begin()[rand.nextInt(i+1)]);
+		}
+
+		int3 guardPos(-1,-1,-1);
+
+		auto otherZoneTiles = zoneB->getTileInfo();
+		auto otherZoneCenter = zoneB->getPos();
+
+		for (auto tile : tiles)
+		{
+			foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos)
+			{
+				if (vstd::contains(otherZoneTiles, pos))
+					guardPos = tile;
+			});
+			if (guardPos.valid())
+			{
+				zoneA->addMonster (this, guardPos, connection.getGuardStrength()); //TODO: set value according to template
+				//zones can make paths only in their own area
+				zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId()); //make connection towards our zone center
+				zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId()); //make connection towards other zone center
+				break; //we're done with this connection
+			}
+		}
+		if (!guardPos.valid())
+		{
+			auto teleport1 = new CGTeleport;
+			teleport1->ID = Obj::MONOLITH_TWO_WAY;
+			teleport1->subID = getNextMonlithIndex();
+
+			auto teleport2 = new CGTeleport(*teleport1);
+
+			zoneA->addRequiredObject (teleport1, connection.getGuardStrength());
+			zoneB->addRequiredObject (teleport2, connection.getGuardStrength());
+		}		
+	}
+}
+
 void CMapGenerator::addHeaderInfo()
 {
 	map->version = EMapFormat::SOD;

+ 1 - 0
lib/rmg/CMapGenerator.h

@@ -64,6 +64,7 @@ public:
 	CMapEditManager * editManager;
 
 	std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
+	void createConnections();
 	void foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo);
 
 	bool isBlocked(const int3 &tile) const;

+ 9 - 59
lib/rmg/CRmgTemplateZone.cpp

@@ -317,60 +317,6 @@ std::set<int3> CRmgTemplateZone::getTileInfo () const
 	return tileinfo;
 }
 
-void CRmgTemplateZone::createConnections(CMapGenerator* gen)
-{
-	//rearrange tiles in random order
-	std::vector<int3> tiles(tileinfo.begin(), tileinfo.end());
-	//TODO: hwo to use std::shuffle with our generator?
-	//std::random_shuffle (tiles.begin(), tiles.end(), &gen->rand.nextInt);
-
-	int i, n;
-	n = (tiles.end() - tiles.begin());
-	for (i=n-1; i>0; --i)
-	{
-		std::swap (tiles.begin()[i],tiles.begin()[gen->rand.nextInt(i+1)]);
-	}
-
-	for (auto connection : connections)
-	{
-		if (getId() > connection) //only one connection between each pair
-			continue;
-
-		int3 guardPos(-1,-1,-1);
-
-		auto otherZoneTiles = gen->getZones()[connection]->getTileInfo();
-		auto otherZoneCenter = gen->getZones()[connection]->getPos();
-
-		for (auto tile : tiles)
-		{
-			gen->foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos)
-			{
-				if (vstd::contains(otherZoneTiles, pos))
-					guardPos = tile;
-			});
-			if (guardPos.valid())
-			{
-				addMonster (gen, guardPos, 10000); //TODO: set value according to template
-				//zones can make paths only in their own area
-				this->crunchPath (gen, guardPos, this->getPos(), this->getId()); //make connection towards our zone center
-				gen->getZones()[connection]->crunchPath (gen, guardPos, otherZoneCenter, connection); //make connection towards other zone center
-				break; //we're done with this connection
-			}
-		}
-		if (!guardPos.valid())
-		{
-			auto teleport1 = new CGTeleport;
-			teleport1->ID = Obj::MONOLITH_TWO_WAY;
-			teleport1->subID = gen->getNextMonlithIndex();
-
-			auto teleport2 = new CGTeleport(*teleport1);
-
-			addRequiredObject (teleport1);
-			gen->getZones()[connection]->addRequiredObject(teleport2);
-		}		
-	}
-}
-
 void CRmgTemplateZone::createBorder(CMapGenerator* gen)
 {
 	for (auto tile : tileinfo)
@@ -450,9 +396,9 @@ do not leave zone border
 	return result;
 }
 
-void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj)
+void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj, si32 strength)
 {
-	requiredObjects.push_back(obj);
+	requiredObjects.push_back(std::make_pair(obj, strength));
 }
 
 void CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength)
@@ -527,7 +473,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 				mine->subID = static_cast<si32>(res);
 				mine->producedResource = res;
 				mine->producedQuantity = mine->defaultResProduction();
-				requiredObjects.push_back(mine);
+				addRequiredObject(mine);
 			}
 		}
 		else
@@ -555,7 +501,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 	{
 		int3 pos;
 		logGlobal->traceStream() << "Looking for place";
-		if ( ! findPlaceForObject(gen, obj, 3, pos))		
+		if ( ! findPlaceForObject(gen, obj.first, 3, pos))		
 		{
 			logGlobal->errorStream() << boost::format("Failed to fill zone %d due to lack of space") %id;
 			//TODO CLEANUP!
@@ -563,7 +509,11 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 		}
 		logGlobal->traceStream() << "Place found";
 
-		placeObject(gen, obj, pos);
+		placeObject(gen, obj.first, pos);
+		if (obj.second)
+		{
+			guardObject (gen, obj.first, obj.second); //FIXME: set apriopriate guard strength
+		}
 	}
 	std::vector<CGObjectInstance*> guarded_objects;
 	static auto res_gen = gen->rand.getIntRange(Res::ERes::WOOD, Res::ERes::GOLD);

+ 2 - 3
lib/rmg/CRmgTemplateZone.h

@@ -112,10 +112,9 @@ public:
 	void addTile (const int3 &pos);
 	std::set<int3> getTileInfo () const;
 
-	void addRequiredObject(CGObjectInstance * obj);
+	void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
 	void addMonster(CMapGenerator* gen, int3 &pos, si32 strength);
 	bool fill(CMapGenerator* gen);
-	void createConnections(CMapGenerator* gen);
 	void createBorder(CMapGenerator* gen);
 	bool crunchPath (CMapGenerator* gen, int3 &src, int3 &dst, TRmgTemplateZoneId zone);
 
@@ -137,7 +136,7 @@ private:
 
 	//content info
 	std::vector<int3> shape; //TODO: remove
-	std::vector<CGObjectInstance*> requiredObjects;
+	std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
 	std::vector<CGObjectInstance*> objects;
 
 	//placement info