Exemplo n.º 1
0
void CEnergyGrid::AddPylon(CCircuitUnit::Id unitId, CCircuitDef::Id defId, const AIFloat3& pos)
{
	CMetalManager* metalManager = circuit->GetMetalManager();
	const CMetalData::Clusters& clusters = metalManager->GetClusters();
	const CMetalData::Graph& clusterGraph = metalManager->GetGraph();

	// Find edges to which building belongs to
	float range = pylonRanges[defId];
	float sqRange = range * range;
	CMetalData::Graph::edge_iterator edgeIt, edgeEnd;
	std::tie(edgeIt, edgeEnd) = boost::edges(clusterGraph);  // or boost::tie
	for (; edgeIt != edgeEnd; ++edgeIt) {
		const CMetalData::EdgeDesc& edgeId = *edgeIt;
		int idxSource = boost::source(edgeId, clusterGraph);
		const AIFloat3& P0 = clusters[idxSource].geoCentr;
		int idxTarget = boost::target(edgeId, clusterGraph);
		const AIFloat3& P1 = clusters[idxTarget].geoCentr;

		if ((P0.SqDistance2D(pos) < sqRange) || (P1.SqDistance2D(pos) < sqRange) ||
			(((P0 + P1) * 0.5f).SqDistance2D(pos) < P0.SqDistance2D(P1) * 0.25f))
		{
			CEnergyLink& link = boost::get(linkIt, edgeId);
			link.AddPylon(unitId, pos, range);
			linkPylons.insert(edgeId);
		}
	}
}
Exemplo n.º 2
0
void CEnergyGrid::RebuildTree()
{
	if (linkClusters.empty() && unlinkClusters.empty() && !isForceRebuild) {
		return;
	}
	isForceRebuild = false;
	CMetalManager* metalManager = circuit->GetMetalManager();
	const CMetalData::Graph& clusterGraph = metalManager->GetGraph();

	// Remove destroyed edges
	auto pred = [this](const CMetalData::EdgeDesc& desc) {
		spanningTree.erase(desc);
		return true;
	};
	for (int index : unlinkClusters) {
		boost::remove_out_edge_if(index, pred, ownedClusters);
	}
	unlinkClusters.clear();

	// Add new edges to Kruskal graph
	for (int index : linkClusters) {
		CMetalData::Graph::out_edge_iterator outEdgeIt, outEdgeEnd;
		std::tie(outEdgeIt, outEdgeEnd) = boost::out_edges(index, clusterGraph);  // or boost::tie
		for (; outEdgeIt != outEdgeEnd; ++outEdgeIt) {
			const CMetalData::EdgeDesc& edgeId = *outEdgeIt;
			int idx0 = boost::target(edgeId, clusterGraph);
			if (linkedClusters[idx0]) {
				boost::add_edge(idx0, index, clusterGraph[edgeId], ownedClusters);

				CEnergyLink& link = boost::get(linkIt, edgeId);
				link.SetStartVertex(idx0);
			}
		}
	}
	linkClusters.clear();

	float width = circuit->GetTerrainManager()->GetTerrainWidth();
	float height = circuit->GetTerrainManager()->GetTerrainHeight();
	float baseWeight = width * width + height * height;
	float invBaseWeight = 1.0f / baseWeight;  // FIXME: only valid for 1 of the ally team
	const AIFloat3& basePos = circuit->GetSetupManager()->GetBasePos();
	for (const CMetalData::EdgeDesc& edgeId : spanningTree) {
		CEnergyLink& link = boost::get(linkIt, edgeId);
		if (link.IsFinished() || link.IsBeingBuilt()) {
			// Mark used edges as const
			ownedClusters[edgeId].weight = clusterGraph[edgeId].weight * invBaseWeight;
		} else if (!link.IsValid()) {
			ownedClusters[edgeId].weight = clusterGraph[edgeId].weight * baseWeight;
		} else {
			// Adjust weight by distance to base
			const CMetalData::SEdge& edge = clusterGraph[edgeId];
			ownedClusters[edgeId].weight = edge.weight * basePos.SqDistance2D(edge.center) * invBaseWeight;
		}
	}

	// Build Kruskal's minimum spanning tree
	spanningTree.clear();
	boost::property_map<CMetalData::Graph, float CMetalData::SEdge::*>::type w_map = boost::get(&CMetalData::SEdge::weight, ownedClusters);
	boost::kruskal_minimum_spanning_tree(ownedClusters, std::inserter(spanningTree, spanningTree.end()), boost::weight_map(w_map));
}
Exemplo n.º 3
0
void CEnergyGrid::Init()
{
	for (auto& kv : circuit->GetCircuitDefs()) {
		const std::map<std::string, std::string>& customParams = kv.second->GetUnitDef()->GetCustomParams();
		auto it = customParams.find("pylonrange");
		if (it != customParams.end()) {
			pylonRanges[kv.first] = utils::string_to_float(it->second);
		}
	}
	// FIXME: const names
	const char* names[] = {"armestor", "armsolar", "armwin"};
	for (const char* name : names) {
		CCircuitDef* cdef = circuit->GetCircuitDef(name);
		rangePylons[pylonRanges[cdef->GetId()]] = cdef->GetId();
	}

	CMetalManager* metalManager = circuit->GetMetalManager();
	const CMetalData::Clusters& clusters = metalManager->GetClusters();
	const CMetalData::Graph& clusterGraph = metalManager->GetGraph();

	linkedClusters.resize(clusters.size(), false);

	links.reserve(boost::num_edges(clusterGraph));
	CMetalData::Graph::edge_iterator edgeIt, edgeEnd;
	std::tie(edgeIt, edgeEnd) = boost::edges(clusterGraph);
	for (; edgeIt != edgeEnd; ++edgeIt) {
		const CMetalData::EdgeDesc& edgeId = *edgeIt;
		int idx0 = boost::source(edgeId, clusterGraph);
		int idx1 = boost::target(edgeId, clusterGraph);
		links.emplace_back(idx0, clusters[idx0].geoCentr, idx1, clusters[idx1].geoCentr);
	}
	linkIt = boost::make_iterator_property_map(&links[0], boost::get(&CMetalData::SEdge::index, clusterGraph));

	ownedClusters = CMetalData::Graph(boost::num_vertices(clusterGraph));
}
Exemplo n.º 4
0
void CEnergyGrid::RemovePylon(CCircuitUnit::Id unitId)
{
	CMetalManager* metalManager = circuit->GetMetalManager();
	const CMetalData::Graph& clusterGraph = metalManager->GetGraph();

	// Find edges to which building belongs to
	CMetalData::Graph::edge_iterator edgeIt, edgeEnd;
	std::tie(edgeIt, edgeEnd) = boost::edges(clusterGraph);  // or boost::tie
	for (; edgeIt != edgeEnd; ++edgeIt) {
		const CMetalData::EdgeDesc& edgeId = *edgeIt;
		CEnergyLink& link = boost::get(linkIt, edgeId);
		if (link.RemovePylon(unitId)) {
			unlinkPylons.insert(edgeId);
		}
	}
}
Exemplo n.º 5
0
void CEnergyGrid::Init()
{
	CMetalManager* metalManager = circuit->GetMetalManager();
	const CMetalData::Clusters& clusters = metalManager->GetClusters();
	const CMetalData::Graph& clusterGraph = metalManager->GetGraph();

	linkedClusters.resize(clusters.size(), false);

	links.reserve(boost::num_edges(clusterGraph));
	CMetalData::Graph::edge_iterator edgeIt, edgeEnd;
	std::tie(edgeIt, edgeEnd) = boost::edges(clusterGraph);
	for (; edgeIt != edgeEnd; ++edgeIt) {
		const CMetalData::EdgeDesc& edgeId = *edgeIt;
		int idx0 = boost::source(edgeId, clusterGraph);
		int idx1 = boost::target(edgeId, clusterGraph);
		links.emplace_back(idx0, clusters[idx0].geoCentr, idx1, clusters[idx1].geoCentr);
	}
	linkIt = boost::make_iterator_property_map(&links[0], boost::get(&CMetalData::SEdge::index, clusterGraph));

	ownedClusters = CMetalData::Graph(boost::num_vertices(clusterGraph));
}