float3 CAICallback::ClosestBuildSite(const UnitDef* unitdef,float3 pos,float searchRadius,int minDist)
{
	//todo fix so you cant detect enemy buildings with it
	CFeature* feature;
	int allyteam=gs->AllyTeam(team);

	int endr = (int)(searchRadius / (SQUARE_SIZE*2));
	const vector<SearchOffset>& ofs = GetSearchOffsetTable (endr);

	for(int so=0;so<endr*endr*4;so++) {
		float x = pos.x+ofs[so].dx*SQUARE_SIZE*2;
		float z = pos.z+ofs[so].dy*SQUARE_SIZE*2;
		float3 p(x,0,z);
		p = helper->Pos2BuildPos (p, unitdef);
		if(uh->TestUnitBuildSquare(p,unitdef,feature) && (!feature || feature->allyteam!=allyteam))
		{
			int xs=(int)(x/SQUARE_SIZE);
			int zs=(int)(z/SQUARE_SIZE);
			bool good=true;
			for(int z2=max(0,zs-unitdef->ysize/2-minDist);z2<min(gs->mapy,zs+unitdef->ysize+minDist);++z2){
				for(int x2=max(0,xs-unitdef->xsize/2-minDist);x2<min(gs->mapx,xs+unitdef->xsize+minDist);++x2){
					CSolidObject* so=readmap->groundBlockingObjectMap[z2*gs->mapx+x2];
					if(so && so->immobile && !dynamic_cast<CFeature*>(so)){
						good=false;
						break;
					}
				}
			}
			if(good) 
				return p;
		}
	}

	return float3(-1.0f,0.0f,0.0f);	
}
float3 CAICallback::ClosestBuildSite(const UnitDef* unitdef,float3 pos,float searchRadius,int minDist, int facing)
{
	if (!unitdef) return float3(-1.0f,0.0f,0.0f);
	CFeature* feature;
	int allyteam=gs->AllyTeam(team);

	int endr = (int)(searchRadius / (SQUARE_SIZE*2));
	const vector<SearchOffset>& ofs = GetSearchOffsetTable (endr);

	for(int so=0;so<endr*endr*4;so++) {
		float x = pos.x+ofs[so].dx*SQUARE_SIZE*2;
		float z = pos.z+ofs[so].dy*SQUARE_SIZE*2;
		BuildInfo bi(unitdef, float3(x,0,z), facing);
		bi.pos = helper->Pos2BuildPos (bi);
		if(uh->TestUnitBuildSquare(bi,feature,allyteam) && (!feature || feature->allyteam!=allyteam))
		{
			int xs=(int)(x/SQUARE_SIZE);
			int zs=(int)(z/SQUARE_SIZE);
			bool good=true;
			int xsize=bi.GetXSize();
			int ysize=bi.GetYSize();
			for(int z2=std::max(0,zs-ysize/2-minDist);z2<std::min(gs->mapy,zs+(ysize+1)/2+minDist);++z2){
				for(int x2=std::max(0,xs-xsize/2-minDist);x2<std::min(gs->mapx,xs+(xsize+1)/2+minDist);++x2){
					CSolidObject* so = groundBlockingObjectMap->GroundBlockedUnsafe(z2 * gs->mapx + x2);
					if(so && so->immobile && !dynamic_cast<CFeature*>(so)){
						good=false;
						break;
					}
				}
			}
			//Checking factories near - factory can open yard for building
			if (good) for(int z2=std::max(0,zs-ysize/2-minDist-2);z2<std::min(gs->mapy,zs+(ysize+1)/2+minDist+2);++z2){
				for(int x2=std::max(0,xs-xsize/2-minDist-2);x2<std::min(gs->mapx,xs+(xsize+1)/2+minDist+2);++x2){
					CSolidObject* so = groundBlockingObjectMap->GroundBlockedUnsafe(z2 * gs->mapx + x2);
					if(so && so->immobile && dynamic_cast<CFactory*>(so) && ((CFactory*)so)->opening){
						good=false;
						break;
					}
				}
			}
			if(good)
				return bi.pos;
		}
	}

	return float3(-1.0f,0.0f,0.0f);
}
Example #3
0
float3 CGameHelper::ClosestBuildSite(int team, const UnitDef* unitDef, float3 pos, float searchRadius, int minDist, int facing)
{
    if (!unitDef) {
        return float3(-1.0f, 0.0f, 0.0f);
    }

    CFeature* feature = NULL;

    const int allyteam = teamHandler->AllyTeam(team);
    const int endr = int(searchRadius / (SQUARE_SIZE * 2));
    const vector<SearchOffset>& ofs = GetSearchOffsetTable(endr);

    for (int so = 0; so < endr * endr * 4; so++) {
        float x = pos.x + ofs[so].dx * SQUARE_SIZE * 2;
        float z = pos.z + ofs[so].dy * SQUARE_SIZE * 2;

        BuildInfo bi(unitDef, float3(x, 0.0f, z), facing);
        bi.pos = Pos2BuildPos(bi);

        if (uh->TestUnitBuildSquare(bi, feature, allyteam) && (!feature || feature->allyteam != allyteam)) {
            const int xs = int(x / SQUARE_SIZE);
            const int zs = int(z / SQUARE_SIZE);
            const int xsize = bi.GetXSize();
            const int zsize = bi.GetZSize();

            bool good = true;

            int z2Min = std::max(       0, zs - (zsize    ) / 2 - minDist);
            int z2Max = std::min(gs->mapy, zs + (zsize + 1) / 2 + minDist);
            int x2Min = std::max(       0, xs - (xsize    ) / 2 - minDist);
            int x2Max = std::min(gs->mapx, xs + (xsize + 1) / 2 + minDist);

            // check for nearby blocking features
            for (int z2 = z2Min; z2 < z2Max; ++z2) {
                for (int x2 = x2Min; x2 < x2Max; ++x2) {
                    CSolidObject* so = groundBlockingObjectMap->GroundBlockedUnsafe(z2 * gs->mapx + x2);

                    if (so && so->immobile && !dynamic_cast<CFeature*>(so)) {
                        good = false;
                        break;
                    }
                }
            }

            if (good) {
                z2Min = std::max(       0, zs - (zsize    ) / 2 - minDist - 2);
                z2Max = std::min(gs->mapy, zs + (zsize + 1) / 2 + minDist + 2);
                x2Min = std::max(       0, xs - (xsize    ) / 2 - minDist - 2);
                x2Max = std::min(gs->mapx, xs + (xsize + 1) / 2 + minDist + 2);

                // check for nearby factories with open yards
                for (int z2 = z2Min; z2 < z2Max; ++z2) {
                    for (int x2 = x2Min; x2 < x2Max; ++x2) {
                        CSolidObject* so = groundBlockingObjectMap->GroundBlockedUnsafe(z2 * gs->mapx + x2);

                        if (so && so->immobile && dynamic_cast<CFactory*>(so) && ((CFactory*)so)->opening) {
                            good = false;
                            break;
                        }
                    }
                }
            }

            if (good) {
                return bi.pos;
            }
        }
    }

    return float3(-1.0f, 0.0f, 0.0f);
}