소스 검색

- Fixed crash caused by randomShuffle
- Banned Magic Spring as it has 2 visitable positions

DjWarmonger 11 년 전
부모
커밋
492b866806
4개의 변경된 파일59개의 추가작업 그리고 37개의 파일을 삭제
  1. 8 7
      config/objects/rewardable.json
  2. 1 1
      lib/CRandomGenerator.h
  3. 26 29
      lib/mapObjects/ObjectTemplate.cpp
  4. 24 0
      lib/rmg/CRmgTemplateZone.cpp

+ 8 - 7
config/objects/rewardable.json

@@ -6,13 +6,14 @@
 		"handler": "magicSpring",
 		"types" : {
 			"object" : {
-				"index" : 0,
-				"rmg" : {
-					"zoneLimit"	: 1,
-					"mapLimit"	: 32,
-					"value"		: 500,
-					"rarity"	: 50
-				}
+				"index" : 0//,
+				//"rmg" : {
+				//	"zoneLimit"	: 1,
+				//	"mapLimit"	: 32,
+				//	"value"		: 500,
+				//	"rarity"	: 50
+				//}
+				//banned due to problems with 2 viistable offsets
 			}
 		}
 	},

+ 1 - 1
lib/CRandomGenerator.h

@@ -117,7 +117,7 @@ namespace RandomGeneratorUtil
 		int n = (container.end() - container.begin());
 		for (int i = n-1; i>0; --i)
 		{
-			std::swap (container.begin()[i],container.begin()[rand.nextInt(i+1)]);
+			std::swap (container.begin()[i],container.begin()[rand.nextInt(i)]);
 		}
 	}
 }

+ 26 - 29
lib/mapObjects/ObjectTemplate.cpp

@@ -23,34 +23,31 @@
  *
  */
 
-namespace vstd
+static bool isOnVisitableFromTopList(int identifier, int type)
 {
-	static bool isVisitableFromTop(int identifier, int type)
-	{
-		if(type == 2 || type == 3 || type == 4 || type == 5) //creature, hero, artifact, resource
-			return true;
-
-		static const Obj visitableFromTop[] =
-			{Obj::FLOTSAM,
-			Obj::SEA_CHEST,
-			Obj::SHIPWRECK_SURVIVOR,
-			Obj::BUOY,
-			Obj::OCEAN_BOTTLE,
-			Obj::BOAT,
-			Obj::WHIRLPOOL,
-			Obj::GARRISON,
-			Obj::GARRISON2,
-			Obj::SCHOLAR,
-			Obj::CAMPFIRE,
-			Obj::BORDERGUARD,
-			Obj::BORDER_GATE,
-			Obj::QUEST_GUARD,
-			Obj::CORPSE
-		};
-		if (vstd::find_pos(visitableFromTop, identifier) != -1)
-			return true;
-		return false;
-	}
+	if(type == 2 || type == 3 || type == 4 || type == 5) //creature, hero, artifact, resource
+		return true;
+
+	static const Obj visitableFromTop[] =
+		{Obj::FLOTSAM,
+		Obj::SEA_CHEST,
+		Obj::SHIPWRECK_SURVIVOR,
+		Obj::BUOY,
+		Obj::OCEAN_BOTTLE,
+		Obj::BOAT,
+		Obj::WHIRLPOOL,
+		Obj::GARRISON,
+		Obj::GARRISON2,
+		Obj::SCHOLAR,
+		Obj::CAMPFIRE,
+		Obj::BORDERGUARD,
+		Obj::BORDER_GATE,
+		Obj::QUEST_GUARD,
+		Obj::CORPSE
+	};
+	if (vstd::find_pos(visitableFromTop, identifier) != -1)
+		return true;
+	return false;
 }
 
 ObjectTemplate::ObjectTemplate():
@@ -109,7 +106,7 @@ void ObjectTemplate::readTxt(CLegacyConfigParser & parser)
 	int type  = boost::lexical_cast<int>(strings[7]);
 	printPriority = boost::lexical_cast<int>(strings[8]) * 100; // to have some space in future
 
-	if (vstd::isVisitableFromTop(id, type))
+	if (isOnVisitableFromTopList(id, type))
 		visitDir = 0xff;
 	else
 		visitDir = (8|16|32|64|128);
@@ -171,7 +168,7 @@ void ObjectTemplate::readMap(CBinaryReader & reader)
 	int type = reader.readUInt8();
 	printPriority = reader.readUInt8() * 100; // to have some space in future
 
-	if (vstd::isVisitableFromTop(id, type))
+	if (isOnVisitableFromTopList(id, type))
 		visitDir = 0xff;
 	else
 		visitDir = (8|16|32|64|128);

+ 24 - 0
lib/rmg/CRmgTemplateZone.cpp

@@ -784,6 +784,25 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
 			return true;
 		}
 
+		//update boundary around our objects, including knowledge about objects visitable from bottom
+
+		boundary.clear();
+		for (auto tile : info.visitableFromBottomPositions)
+		{
+			gen->foreach_neighbour (tile, [tile, &boundary](int3 pos)
+			{
+				if (tile.y >= pos.y) //don't block these objects from above
+					boundary.insert(pos);
+			});
+		}
+		for (auto tile : info.visitableFromTopPositions)
+		{
+			gen->foreach_neighbour (tile, [&boundary](int3 pos)
+			{
+				boundary.insert(pos);
+			});
+		}
+
 		for (auto tile : boundary) //guard must be standing there
 		{
 			if (gen->isFree(tile)) //this tile could be already blocked, don't place a monster here
@@ -1403,6 +1422,8 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
 
 ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value)
 {
+	//int objectsVisitableFromBottom = 0; //for debug
+
 	std::vector<std::pair<ui32, ObjectInfo>> tresholds;
 	ui32 total = 0;
 
@@ -1418,6 +1439,7 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
 
 			if (!oi.templ.isVisitableFromTop())
 			{
+				//objectsVisitableFromBottom++;
 				//there must be free tiles under object
 				if (!isAccessibleFromAnywhere(gen, oi.templ, newVisitablePos, oi.templ.getBlockedOffsets()))
 					continue;
@@ -1502,6 +1524,8 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
 		}
 	}
 
+	//logGlobal->infoStream() << boost::format ("Number of objects visitable  from bottom: %d") % objectsVisitableFromBottom;
+
 	//Generate pandora Box with gold if the value is extremely high
 	ObjectInfo oi;
 	if (tresholds.empty())