浏览代码

jfhs patch integration is now complete:
Lots of fixes for object placement.
Fixed blocked paths on generated maps.

DjWarmonger 11 年之前
父节点
当前提交
35d6215b7b
共有 3 个文件被更改,包括 20 次插入30 次删除
  1. 0 19
      lib/CRandomGenerator.h
  2. 4 1
      lib/rmg/CMapGenerator.cpp
  3. 16 10
      lib/rmg/CRmgTemplateZone.cpp

+ 0 - 19
lib/CRandomGenerator.h

@@ -97,25 +97,6 @@ public:
 
 namespace RandomGeneratorUtil
 {
-	/// Gets an iterator to an element of a nonempty container randomly. Undefined behaviour if container is empty.
-	//template<typename T>
-	//auto nextItem(const std::set<T> & container, CRandomGenerator & rand) -> decltype(std::begin(container))
-	//{
-	//	assert(!container.empty());
-	//	auto ret = container.begin();
-	//	std::advance(ret, rand.nextInt(container.size() - 1));
-	//	return ret;
-	//}
-
-	//template<typename T>
-	//auto nextItem(std::set<T> & container, CRandomGenerator & rand) -> decltype(std::begin(container))
-	//{
-	//	assert(!container.empty());
-	//	auto ret = container.begin();
-	//	std::advance(ret, rand.nextInt(container.size() - 1));
-	//	return ret;
-	//}
-
 	template<typename Container>
 	auto nextItem(const Container & container, CRandomGenerator & rand) -> decltype(std::begin(container))
 	{

+ 4 - 1
lib/rmg/CMapGenerator.cpp

@@ -36,12 +36,15 @@ std::unique_ptr<CMap> CMapGenerator::generate()
 		addHeaderInfo();
 
 		genZones();
+		map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
 		fillZones();
 	}
 	catch (rmgException &e)
 	{
-		logGlobal->infoStream() << "Random map generation received exception: " << e.what();
+		logGlobal->errorStream() << "Random map generation received exception: " << e.what();
 	}
+
+	map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed
 	return std::move(map);
 }
 

+ 16 - 10
lib/rmg/CRmgTemplateZone.cpp

@@ -85,9 +85,7 @@ int CRmgTemplateZone::CTileInfo::getNearestObjectDistance() const
 
 void CRmgTemplateZone::CTileInfo::setNearestObjectDistance(int value)
 {
-	if(value < 0)
-		throw rmgException(boost::to_string(boost::format("Negative value %d for nearest object distance not allowed.") %value));
-	nearestObjectDistance = value;
+	nearestObjectDistance = std::max(0, value); //never negative (or unitialized)
 }
 
 bool CRmgTemplateZone::CTileInfo::isObstacle() const
@@ -406,7 +404,6 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 		logGlobal->infoStream() << "Place found";
 
 		placeObject(gen, obj, pos);
-		logGlobal->infoStream() << "Placed object";
 	}
 	std::vector<CGObjectInstance*> guarded_objects;
 	static auto res_gen = gen->rand.getIntRange(Res::ERes::WOOD, Res::ERes::GOLD);
@@ -424,7 +421,8 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 			delete obj;
 			break;
 		}
-		placeObject(gen, obj, pos);		
+		placeObject(gen, obj, pos);
+
 		if ((restype != Res::ERes::WOOD) && (restype != Res::ERes::ORE))
 		{
 			guarded_objects.push_back(obj);
@@ -451,7 +449,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
 			placeObject(gen, obj, it->first);
 		}
 	}
-	logGlobal->infoStream() << boost::format("Filling %d with ROCK") % sel.getSelectedItems().size();
+	//logGlobal->infoStream() << boost::format("Filling %d with ROCK") % sel.getSelectedItems().size();
 	//gen->editManager->drawTerrain(ETerrainType::ROCK, &gen->gen);
 	logGlobal->infoStream() << boost::format ("Zone %d filled successfully") %id;
 	return true;
@@ -487,9 +485,11 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
 
 void CRmgTemplateZone::checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos)
 {
+	if (!gen->map->isInTheMap(pos))
+		throw rmgException(boost::to_string(boost::format("Position of object %d at %s is outside the map") % object->id % object->pos()));
 	object->pos = pos;
 
-	if (!gen->map->isInTheMap(object->visitablePos()))
+	if (object->isVisitable() && !gen->map->isInTheMap(object->visitablePos()))
 		throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % object->visitablePos() % object->id % object->pos()));
 	for (auto tile : object->getBlockedPos())
 	{
@@ -497,8 +497,14 @@ void CRmgTemplateZone::checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance*
 			throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile() % object->id % object->pos()));
 	}
 
+	auto templates = VLC->dobjinfo->pickCandidates(object->ID, object->subID, gen->map->getTile(pos).terType);
+	if (templates.empty())
+		throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %object->ID %object->subID %pos));
+	
+	object->appearance = templates.front();
+	gen->map->addBlockVisTiles(object);
 	gen->editManager->insertObject(object, pos);
-	logGlobal->infoStream() << boost::format ("Successfully inserted object (%d,%d) at pos %s") %object->ID %object->id %pos();
+	logGlobal->traceStream() << boost::format ("Successfully inserted object (%d,%d) at pos %s") %object->ID %object->subID %pos();
 }
 
 void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos)
@@ -529,7 +535,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
 {
 	
 	logGlobal->infoStream() << boost::format("Guard object at %d %d") % object->pos.x % object->pos.y;
-	int3 visitable = object->pos + object->getVisitableOffset();
+	int3 visitable = object->visitablePos();
 	std::vector<int3> tiles;
 	for(int i = -1; i < 2; ++i)
 	{
@@ -552,7 +558,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
 		logGlobal->infoStream() << "Failed";
 		return false;
 	}
-	auto guard_tile = *std::next(tiles.begin(), gen->rand.nextInt(tiles.size()));
+	auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
 	tileinfo[guard_tile].setObstacle(false);
 	auto guard = new CGCreature();
 	guard->ID = Obj::RANDOM_MONSTER;