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; } } }); } }
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; } }
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); }); } }
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); }