/* sets the range of extraction for this extractor, also finds overlapping neighbours. */ void CExtractorBuilding::SetExtractionRangeAndDepth(float range, float depth) { extractionRange = range; extractionDepth = depth; // find any neighbouring extractors std::vector<CUnit*> cu = qf->GetUnits(pos, extractionRange + maxExtractionRange); maxExtractionRange = std::max(extractionRange, maxExtractionRange); for (std::vector<CUnit*>::iterator ui = cu.begin(); ui != cu.end(); ++ui) { if (typeid(**ui) == typeid(CExtractorBuilding) && *ui != this) { CExtractorBuilding* eb = (CExtractorBuilding*) *ui; if (IsNeighbour(eb)) { neighbours.push_back(eb); eb->AddNeighbour(this); } } } // calculate this extractor's area of control and metalExtract amount metalExtract = 0; int xBegin = std::max(0, (int) ((pos.x - extractionRange) / METAL_MAP_SQUARE_SIZE)); int xEnd = std::min(gs->mapx / 2 - 1, (int) ((pos.x + extractionRange) / METAL_MAP_SQUARE_SIZE)); int zBegin = std::max(0, (int) ((pos.z - extractionRange) / METAL_MAP_SQUARE_SIZE)); int zEnd = std::min(gs->mapy / 2 - 1, (int) ((pos.z + extractionRange) / METAL_MAP_SQUARE_SIZE)); metalAreaOfControl.reserve((xEnd - xBegin + 1) * (zEnd - zBegin + 1)); // go through the whole (x, z)-square for (int x = xBegin; x <= xEnd; x++) { for (int z = zBegin; z <= zEnd; z++) { // center of metalsquare at (x, z) const float3 msqrPos((x + 0.5f) * METAL_MAP_SQUARE_SIZE, pos.y, (z + 0.5f) * METAL_MAP_SQUARE_SIZE); const float sqrCenterDistance = msqrPos.SqDistance2D(this->pos); if (unitDef->extractSquare || sqrCenterDistance < Square(extractionRange)) { MetalSquareOfControl msqr; msqr.x = x; msqr.z = z; // extraction is done in a cylinder of height <depth> msqr.extractionDepth = readmap->metalMap->RequestExtraction(x, z, depth); metalAreaOfControl.push_back(msqr); metalExtract += msqr.extractionDepth * readmap->metalMap->GetMetalAmount(msqr.x, msqr.z); } } } // set the COB animation speed cob->Call(COBFN_SetSpeed, (int)(metalExtract * 5 * 100.0f)); if (activated) { cob->Call("Go"); } }
/** * @brief * Adds a neighbour connection */ bool GraphNode::AddNeighbour(GraphNode &cNode, float fDistance) { // Is this node already a neighbour of this node? if (!IsNeighbour(cNode)) { // Add node Neighbour *pNeighbour = new Neighbour(); m_lstNeighbours.Add(pNeighbour); pNeighbour->pNode = &cNode; pNeighbour->fDistance = (fDistance < 0.0f) ? GetDistance(cNode) : fDistance; cNode.m_lstIsNeighbourFrom.Add(this); // Done return true; } // Error! return false; }
VoronoiCell* GetVoronoiCell(Vertex* point, Simplex* simplex, DelaunayTriangulation* dt) { Simplex* newSimplex; ArrayList* neighbours = FindNeighbours(point, simplex); int n = ArrayListSize(neighbours); if (n==0) { if (!SimplexContainsPoint(dt->m_AlphaSimplex, point)) fprintf(stderr,"Error: point outside of delaunay triangulation. - " "try extending the super-Simplex and re-starting.\n"); else fprintf(stderr, "Error: No neighbours found for point! - DelaunayTriangulation appears " "to be degenerate.\n"); return nullptr; } VoronoiCell* voronoiCell = NewVoronoiCell(dt,n); Simplex** simps = new Simplex* [n]; Vertex** edges = new Vertex* [3*n]; int* done = new int [3*n]; int i, j = 0; for (i = 0; i < ArrayListSize(neighbours); i++) { newSimplex = (Simplex*)GetFromArrayList(neighbours, i); Vertex* v1,* v2,* v3; GetRemainingFace(newSimplex, point, &v1, &v2, &v3); simps[i] = newSimplex; edges[3*i] = v1; edges[3*i+1] = v2; edges[3*i+2] = v3; done[3*i] = 0; done[3*i+1] = 0; done[3*i+2] = 0; CircumCenter(newSimplex, voronoiCell->m_Points[i]); } for (i = 0; i < 3*n; i++) { if (done[i]) continue; int first = i; int current = i; int lastConsidered = -1; int match; do { match=0; for (j = 0; j < 3*n; j++) { if (done[j]) continue; if ((edges[i] == edges[j]) && j != lastConsidered && IsNeighbour(simps[current/3], simps[j/3])) { done[j] = 1; match = 1; AddVertexToVoronoiCell(voronoiCell, voronoiCell->m_Points[j/3]); lastConsidered = current; current = j; break; } } } while (match && (current != first)); StartNewVoronoiFace(voronoiCell); } FreeArrayList(neighbours, nullptr); return voronoiCell; }