예제 #1
0
void CThreatMap::AddEnemyUnit(const EnemyUnit& e, const float scale) {
	const int posx = e.pos.x / (SQUARE_SIZE * THREATRES);
	const int posy = e.pos.z / (SQUARE_SIZE * THREATRES);

	assert(!threatCellsRaw.empty());

	if (!MAPPOS_IN_BOUNDS(e.pos)) {
		std::stringstream msg;
			msg << "[CThreatMap::AddEnemyUnit][frame=" << ai->cb->GetCurrentFrame() << "][scale=" << scale << "]\n";
			msg << "\tposition <" << e.pos.x << ", " << e.pos.z << "> of unit " << e.id;
			msg << " (health " << ai->ccb->GetUnitHealth(e.id) << ") is out-of-bounds\n";
		ai->GetLogger()->Log(msg.str());
	}

	const float threat = e.threat * scale;
	const float rangeSq = e.range * e.range;

	for (int myx = int(posx - e.range); myx < (posx + e.range); myx++) {
		if (myx < 0 || myx >= width) {
			continue;
		}

		for (int myy = int(posy - e.range); myy < (posy + e.range); myy++) {
			if (myy < 0 || myy >= height) {
				continue;
			}

			const int dxSq = (posx - myx) * (posx - myx);
			const int dySq = (posy - myy) * (posy - myy);

			if ((dxSq + dySq - 0.5) <= rangeSq) {
				assert((myy * width + myx) < threatCellsRaw.size());
				assert((myy * width + myx) < threatCellsVis.size());

				// MicroPather cannot deal with negative costs
				// (which may arise due to floating-point drift)
				// nor with zero-cost nodes (see MP::SetMapData,
				// threat is not used as an additive overlay)
				threatCellsRaw[myy * width + myx] = std::max(threatCellsRaw[myy * width + myx] + threat, THREATVAL_BASE);
				threatCellsVis[myy * width + myx] = std::max(threatCellsVis[myy * width + myx] + threat, THREATVAL_BASE);

				currSumThreat += threat;
			}
		}
	}

	currAvgThreat = currSumThreat / area;
}
예제 #2
0
파일: PathFinder.cpp 프로젝트: rlcevg/KAIK
bool CPathFinder::IsPositionReachable(const MoveData* md, const float3& pos) const {
	if (md == 0) {
		// aircraft or building
		return true;
	}
	if (!MAPPOS_IN_BOUNDS(pos)) {
		return false;
	}

	const float* hgtMap = ai->cb->GetHeightMap();
	const float* slpMap  = ai->cb->GetSlopeMap();

	const int WH = ai->cb->GetMapWidth();
	const int WS = WH >> 1;
	const int xh = (pos.x / SQUARE_SIZE);
	const int zh = (pos.z / SQUARE_SIZE);
	const int xs = xh >> 1;
	const int zs = zh >> 1;

	bool heightOK = false;
	bool slopeOK  = false;

	switch (md->moveFamily) {
		case MoveData::Ship: {
			heightOK = (hgtMap[zh * WH + xh] < -md->depth);
			slopeOK  = true;
		} break;
		case MoveData::Tank:
		case MoveData::KBot: {
			heightOK = (hgtMap[zh * WH + xh] > -md->depth);
			slopeOK  = (slpMap[zs * WS + xs] <  md->maxSlope);
		} break;
		case MoveData::Hover: {
			heightOK = true;
			slopeOK  = (slpMap[zs * WS + xs] < md->maxSlope);
		} break;
	}

	return (heightOK && slopeOK);
}