Ejemplo n.º 1
0
 std::string AttenuationShaderTemplate::AttenuationFragmentShaderSource(
     Object *selected_object, const std::set<Object *> &objects, const std::set<Object *> &areas) {
   std::ostringstream result;
   result.precision(std::numeric_limits<double>::max_digits10);
   result << kAttenuationFragmentShaderSourcePrefix << MinimumAttenuationTemplate() << std::endl;
   for (auto object : objects) {
     if (selected_object != object) {
       result << ObjectTemplate(object, true) << std::endl;
     }
   }
   for (auto area : areas) {
     if (selected_object != area) {
       result << ObjectTemplate(area, false) << std::endl;
     }
   }
   result << SuffixTemplate() << kAttenuationFragmentShaderSourceSuffix;
   return result.str();
 }
Ejemplo n.º 2
0
void CMapGenerator::createConnections2()
{
	for (auto & connection : connectionsLeft)
	{
		auto zoneA = connection.getZoneA();
		auto zoneB = connection.getZoneB();

		int3 guardPos(-1, -1, -1);

		int3 posA = zoneA->getPos();
		int3 posB = zoneB->getPos();

		auto strength = connection.getGuardStrength();

		if (posA.z != posB.z) //try to place subterranean gates
		{
			auto sgt = VLC->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0)->getTemplates().front();
			auto tilesBlockedByObject = sgt.getBlockedOffsets();

			auto factory = VLC->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0);
			auto gate1 = factory->create(ObjectTemplate());
			auto gate2 = factory->create(ObjectTemplate());

			while (!guardPos.valid())
			{
				bool continueOuterLoop = false;
				//find common tiles for both zones
				auto tileSetA = zoneA->getPossibleTiles(),
					tileSetB = zoneB->getPossibleTiles();

				std::vector<int3> tilesA(tileSetA.begin(), tileSetA.end()),
					tilesB(tileSetB.begin(), tileSetB.end());

				std::vector<int3> commonTiles;

				//required for set_intersection
				boost::sort(tilesA);
				boost::sort(tilesB);

				boost::set_intersection(tilesA, tilesB, std::back_inserter(commonTiles), [](const int3 &lhs, const int3 &rhs) -> bool
				{
					//ignore z coordinate
					if (lhs.x < rhs.x)
						return true;
					else
						return lhs.y < rhs.y;
				});

				vstd::erase_if(commonTiles, [](const int3 &tile) -> bool
				{
					return (!tile.x) || (!tile.y); //gates shouldn't go outside map (x = 0) and look bad at the very top (y = 0)
				});

				if (commonTiles.empty())
					break; //nothing more to do

				boost::sort(commonTiles, [posA, posB](const int3 &lhs, const int3 &rhs) -> bool
				{
					//choose tiles which are equidistant to zone centers
					return (std::abs<double>(posA.dist2dSQ(lhs) - posB.dist2dSQ(lhs)) < std::abs<double>((posA.dist2dSQ(rhs) - posB.dist2dSQ(rhs))));
				});

				for (auto tile : commonTiles)
				{
					tile.z = posA.z;
					int3 otherTile = tile;
					otherTile.z = posB.z;

					float distanceFromA = posA.dist2d(tile);
					float distanceFromB = posB.dist2d(otherTile);

					if (distanceFromA > 5 && distanceFromB > 5)
					{
						if (zoneA->areAllTilesAvailable(this, gate1, tile, tilesBlockedByObject) &&
							zoneB->areAllTilesAvailable(this, gate2, otherTile, tilesBlockedByObject))
						{
							if (zoneA->getAccessibleOffset(this, sgt, tile).valid() && zoneB->getAccessibleOffset(this, sgt, otherTile).valid())
							{
								EObjectPlacingResult::EObjectPlacingResult result1 = zoneA->tryToPlaceObjectAndConnectToPath(this, gate1, tile);
								EObjectPlacingResult::EObjectPlacingResult result2 = zoneB->tryToPlaceObjectAndConnectToPath(this, gate2, otherTile);

								if ((result1 == EObjectPlacingResult::SUCCESS) && (result2 == EObjectPlacingResult::SUCCESS))
								{
									zoneA->placeObject(this, gate1, tile);
									zoneA->guardObject(this, gate1, strength, true, true);
									zoneB->placeObject(this, gate2, otherTile);
									zoneB->guardObject(this, gate2, strength, true, true);
									guardPos = tile; //set to break the loop
									break;
								}
								else if ((result1 == EObjectPlacingResult::SEALED_OFF) || (result2 == EObjectPlacingResult::SEALED_OFF))
								{
									//sealed-off tiles were blocked, exit inner loop and get another tile set
									continueOuterLoop = true;
									break;
								}
								else
									continue; //try with another position
							}
						}
					}
				}
				if (!continueOuterLoop) //we didn't find ANY tile - break outer loop			
					break;
			}
			if (!guardPos.valid()) //cleanup? is this safe / enough?
			{
				delete gate1;
				delete gate2;
			}
		}
		if (!guardPos.valid())
		{
			auto factory = VLC->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, getNextMonlithIndex());
			auto teleport1 = factory->create(ObjectTemplate());
			auto teleport2 = factory->create(ObjectTemplate());

			zoneA->addRequiredObject(teleport1, strength);
			zoneB->addRequiredObject(teleport2, strength);
		}
	}
}