Пример #1
0
	float3 CMap::Pos2BuildPos(float3 pos, const UnitDef* ud){
		NLOG("CMap::Pos2BuildPos");
		if(ud->xsize&2)
			pos.x=floor((pos.x)/(SQUARE_SIZE*2))*SQUARE_SIZE*2+8;
		else
			pos.x=floor((pos.x+8)/(SQUARE_SIZE*2))*SQUARE_SIZE*2;

		if(ud->ysize&2)
			pos.z=floor((pos.z)/(SQUARE_SIZE*2))*SQUARE_SIZE*2+8;
		else
			pos.z=floor((pos.z+8)/(SQUARE_SIZE*2))*SQUARE_SIZE*2;

		pos.y=GetBuildHeight(pos,ud);
		if(ud->floater && pos.y<0)
			pos.y = -ud->waterline;

		return pos;
	}
Пример #2
0
CGameHelper::BuildSquareStatus CGameHelper::TestUnitBuildSquare(
	const BuildInfo& buildInfo,
	CFeature*& feature,
	int allyteam,
	bool synced,
	std::vector<float3>* canbuildpos,
	std::vector<float3>* featurepos,
	std::vector<float3>* nobuildpos,
	const std::vector<Command>* commands)
{
	feature = NULL;

	const int xsize = buildInfo.GetXSize();
	const int zsize = buildInfo.GetZSize();
	const float3 pos = buildInfo.pos;

	const int x1 = (pos.x - (xsize * 0.5f * SQUARE_SIZE));
	const int z1 = (pos.z - (zsize * 0.5f * SQUARE_SIZE));
	const int z2 = z1 + zsize * SQUARE_SIZE;
	const int x2 = x1 + xsize * SQUARE_SIZE;
	const float bh = GetBuildHeight(pos, buildInfo.def, synced);

	const MoveDef* moveDef = (buildInfo.def->pathType != -1U) ? moveDefHandler->GetMoveDefByPathType(buildInfo.def->pathType) : NULL;
	const S3DModel* model = buildInfo.def->LoadModel();
	const float buildHeight = (model != NULL) ? math::fabs(model->height) : 10.0f;

	BuildSquareStatus canBuild = BUILDSQUARE_OPEN;

	if (buildInfo.def->needGeo) {
		canBuild = BUILDSQUARE_BLOCKED;
		const std::vector<CFeature*>& features = quadField->GetFeaturesExact(pos, std::max(xsize, zsize) * 6);

		// look for a nearby geothermal feature if we need one
		for (std::vector<CFeature*>::const_iterator fi = features.begin(); fi != features.end(); ++fi) {
			if ((*fi)->def->geoThermal
				&& math::fabs((*fi)->pos.x - pos.x) < (xsize * 4 - 4)
				&& math::fabs((*fi)->pos.z - pos.z) < (zsize * 4 - 4)) {
				canBuild = BUILDSQUARE_OPEN;
				break;
			}
		}
	}

	if (commands != NULL) {
		// this is only called in unsynced context (ShowUnitBuildSquare)
		assert(!synced);

		for (int x = x1; x < x2; x += SQUARE_SIZE) {
			for (int z = z1; z < z2; z += SQUARE_SIZE) {
				BuildSquareStatus tbs = TestBuildSquare(float3(x, bh, z), buildHeight, buildInfo.def, moveDef, feature, gu->myAllyTeam, synced);

				if (tbs != BUILDSQUARE_BLOCKED) {
					//??? what does this do?
					for (std::vector<Command>::const_iterator ci = commands->begin(); ci != commands->end(); ++ci) {
						BuildInfo bc(*ci);
						if (std::max(bc.pos.x - x - SQUARE_SIZE, x - bc.pos.x) * 2 < bc.GetXSize() * SQUARE_SIZE &&
							std::max(bc.pos.z - z - SQUARE_SIZE, z - bc.pos.z) * 2 < bc.GetZSize() * SQUARE_SIZE) {
							tbs = BUILDSQUARE_BLOCKED;
							break;
						}
					}
				}

				switch (tbs) {
					case BUILDSQUARE_OPEN:
						canbuildpos->push_back(float3(x, bh, z));
						break;
					case BUILDSQUARE_RECLAIMABLE:
					case BUILDSQUARE_OCCUPIED:
						featurepos->push_back(float3(x, bh, z));
						break;
					case BUILDSQUARE_BLOCKED:
						nobuildpos->push_back(float3(x, bh, z));
						break;
				}

				canBuild = std::min(canBuild, tbs);
			}
		}
	} else {
		// this can be called in either context
		for (int x = x1; x < x2; x += SQUARE_SIZE) {
			for (int z = z1; z < z2; z += SQUARE_SIZE) {
				canBuild = std::min(canBuild, TestBuildSquare(float3(x, bh, z), buildHeight, buildInfo.def, moveDef, feature, allyteam, synced));
				if (canBuild == BUILDSQUARE_BLOCKED) {
					return BUILDSQUARE_BLOCKED;
				}
			}
		}
	}

	return canBuild;
}