예제 #1
0
파일: SectorMap.cpp 프로젝트: vcmi/vcmi
void SectorMap::makeParentBFS(crint3 source)
{
	parent.clear();

	int mySector = retrieveTile(source);
	std::queue<int3> toVisit;
	toVisit.push(source);
	while (!toVisit.empty())
	{
		int3 curPos = toVisit.front();
		toVisit.pop();
		TSectorID & sec = retrieveTile(curPos);
		assert(sec == mySector); //consider only tiles from the same sector
		UNUSED(sec);

		foreach_neighbour(curPos, [&](crint3 neighPos)
		{
			if (retrieveTile(neighPos) == mySector && !vstd::contains(parent, neighPos))
			{
				if (cb->canMoveBetween(curPos, neighPos))
				{
					toVisit.push(neighPos);
					parent[neighPos] = curPos;
				}
			}
		});
	}
}
예제 #2
0
void CMapGenerator::createObstaclesCommon2()
{
	if (map->twoLevel)
	{
		//finally mark rock tiles as occupied, spawn no obstacles there
		for (int x = 0; x < map->width; x++)
		{
			for (int y = 0; y < map->height; y++)
			{
				int3 tile(x, y, 1);
				if (map->getTile(tile).terType == ETerrainType::ROCK)
				{
					setOccupied(tile, ETileType::USED);
				}
			}
		}
	}

	//tighten obstacles to improve visuals

	for (int i = 0; i < 3; ++i)
	{
		int blockedTiles = 0;
		int freeTiles = 0;

		for (int z = 0; z < (map->twoLevel ? 2 : 1); z++)
		{
			for (int x = 0; x < map->width; x++)
			{
				for (int y = 0; y < map->height; y++)
				{
					int3 tile(x, y, z);
					if (!isPossible(tile)) //only possible tiles can change
						continue;

					int blockedNeighbours = 0;
					int freeNeighbours = 0;
					foreach_neighbour(tile, [this, &blockedNeighbours, &freeNeighbours](int3 &pos)
					{
						if (this->isBlocked(pos))
							blockedNeighbours++;
						if (this->isFree(pos))
							freeNeighbours++;
					});
					if (blockedNeighbours > 4)
					{
						setOccupied(tile, ETileType::BLOCKED);
						blockedTiles++;
					}
					else if (freeNeighbours > 4)
					{
						setOccupied(tile, ETileType::FREE);
						freeTiles++;
					}
				}
			}
		}
		logGlobal->traceStream() << boost::format("Set %d tiles to BLOCKED and %d tiles to FREE") % blockedTiles % freeTiles;
	}
}
예제 #3
0
void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out)
{
	for(const int3 &tile : tiles)
	{
		foreach_neighbour(tile, [&](int3 neighbour)
		{
			if(cb->isVisible(neighbour))
				out.push_back(neighbour);
		});
	}
}
예제 #4
0
파일: SectorMap.cpp 프로젝트: vcmi/vcmi
void SectorMap::exploreNewSector(crint3 pos, int num, CCallback * cbp)
{
	Sector & s = infoOnSectors[num];
	s.id = num;
	s.water = getTile(pos)->isWater();

	std::queue<int3> toVisit;
	toVisit.push(pos);
	while (!toVisit.empty())
	{
		int3 curPos = toVisit.front();
		toVisit.pop();
		TSectorID & sec = retrieveTile(curPos);
		if (sec == NOT_CHECKED)
		{
			const TerrainTile * t = getTile(curPos);
			if (!markIfBlocked(sec, curPos, t))
			{
				if (t->isWater() == s.water) //sector is only-water or only-land
				{
					sec = num;
					s.tiles.push_back(curPos);
					foreach_neighbour(cbp, curPos, [&](CCallback * cbp, crint3 neighPos)
					{
						if (retrieveTile(neighPos) == NOT_CHECKED)
						{
							toVisit.push(neighPos);
							//parent[neighPos] = curPos;
						}
						const TerrainTile * nt = getTile(neighPos);
						if (nt && nt->isWater() != s.water && canBeEmbarkmentPoint(nt, s.water))
						{
							s.embarkmentPoints.push_back(neighPos);
						}
					});

					if (t->visitable)
					{
						auto obj = t->visitableObjects.front();
						if (cb->getObj(obj->id, false)) // FIXME: we have to filter invisible objcts like events, but probably TerrainTile shouldn't be used in SectorMap at all
							s.visitableObjs.push_back(obj);
					}
				}
			}
		}
	}

	vstd::removeDuplicates(s.embarkmentPoints);
}