public void VoiceCommandMoveCommander(string chatstring, string[] splitchatstring, int player) { int targetteam = Convert.ToInt32(splitchatstring[2]); if (targetteam == csai.Team) { double x = Convert.ToDouble(splitchatstring[3]); double z = Convert.ToDouble(splitchatstring[4]); double y = aicallback.GetElevation(x, z); aicallback.SendTextMsg("moving commander to " + x + "," + y + "," + z, 0); logfile.WriteLine("moving commander to " + x + "," + y + "," + z); aicallback.GiveOrder(commanderid, new Command(Command.CMD_MOVE, new double[] { x, y, z })); } }
public void VoiceCommandMoveTo(string voicestring, string[] splitchatstring, int player) { // int targetteam = Convert.ToInt32( splitchatstring[2] ); //if( targetteam == csai.Team ) // { Float3 targetpos = new Float3(); targetpos.x = Convert.ToDouble(splitchatstring[2]); targetpos.z = Convert.ToDouble(splitchatstring[3]); targetpos.y = aicallback.GetElevation(targetpos.x, targetpos.z); // GotoPos( targetpos ); movetopackcoordinator.SetTarget(targetpos); packcoordinatorselector.ActivatePackCoordinator(movetopackcoordinator); //} }
// returns figure group public static int DrawMap(bool[,] map) { int thismapwidth = map.GetUpperBound(0) + 1; int thismapheight = map.GetUpperBound(1) + 1; IAICallback aicallback = CSAI.GetInstance().aicallback; int multiplier = (aicallback.GetMapWidth() / thismapwidth) * 8; int figuregroup = 0; for (int y = 0; y < thismapheight; y++) { for (int x = 0; x < thismapwidth; x++) { double elevation = aicallback.GetElevation(x * multiplier, y * multiplier) + 10; if (x < (thismapwidth - 1) && map[x, y] != map[x + 1, y]) { figuregroup = aicallback.CreateLineFigure(new Float3((x + 1) * multiplier, elevation, y * multiplier), new Float3((x + 1) * multiplier, elevation, (y + 1) * multiplier), 10, false, 200, figuregroup); } if (y < (thismapheight - 1) && map[x, y] != map[x, y + 1]) { figuregroup = aicallback.CreateLineFigure(new Float3(x * multiplier, elevation, (y + 1) * multiplier), new Float3((x + 1) * multiplier, elevation, (y + 1) * multiplier), 10, false, 200, figuregroup); } } } return(figuregroup); }
void BuildAt( int constructorid, IUnitDef unitdef, Float3 buildsite ) { IUnitDef placeholder; /* if( unitdef.name.ToLower() == "armmex" ) // use smaller placeholder for mexes so fit closer to intended metalspot { placeholder = buildtable.UnitDefByName[ "ARMMOHO".ToLower() ] as IUnitDef; } else { placeholder = buildtable.UnitDefByName[ "CORGANT".ToLower() ] as IUnitDef; } buildsite = aicallback.ClosestBuildSite( placeholder, buildsite, 1400.0, 2 ); buildsite = aicallback.ClosestBuildSite( unitdef, buildsite, 1400.0, 2 ); */ if( unitdef.name == BuildTable.ArmMex ) { placeholder = buildtable.UnitDefByName[ BuildTable.ArmMoho ] as IUnitDef; buildsite = aicallback.ClosestBuildSite( placeholder, buildsite, 1400.0, 2 ); buildsite = aicallback.ClosestBuildSite( unitdef, buildsite, 1400.0, 2 ); } else { buildsite = BuildPlanner.GetInstance().ClosestBuildSite( unitdef, buildsite, 3000 ); buildsite.y = aicallback.GetElevation( buildsite.x, buildsite.z ); buildsite = aicallback.ClosestBuildSite( unitdef, buildsite, 1400, 2 ); } logfile.WriteLine( "building " + unitdef.name + " at " + buildsite.ToString() ); if( ShowNextBuildSite ) { aicallback.DrawUnit(unitdef.name, buildsite, 0.0f, 500, aicallback.GetMyAllyTeam(), true, true); } aicallback.GiveOrder( constructorid, new Command( - unitdef.id, buildsite.ToDoubleArray() ) ); }
Float3 GetRandomDestination() { Float3 destination = new Float3(); destination.x = random.Next(0, aicallback.GetMapWidth() * MovementMaps.SQUARE_SIZE); destination.z = random.Next(0, aicallback.GetMapHeight() * MovementMaps.SQUARE_SIZE); destination.y = aicallback.GetElevation(destination.x, destination.y); return(destination); }
// ported from Spring's ReadMap.cpp by Hugh Perkins public double[,] GetSlopeMap() { int mapwidth = aicallback.GetMapWidth(); int mapheight = aicallback.GetMapHeight(); int slopemapwidth = mapwidth / 2; int slopemapheight = mapheight / 2; int squaresize = MovementMaps.SQUARE_SIZE; // jsut to save typing... logfile.WriteLine("Getting heightmap, this could take a while... "); double[,] HeightMap = new double[mapwidth + 1, mapheight + 1]; //double[]heightmap = aicallback.GetHeightMap(); // cant use heightmap, it is centre heightmap, we need cornermap for (int x = 0; x < mapwidth + 1; x++) { for (int y = 0; y < mapheight + 1; y++) { HeightMap[x, y] = aicallback.GetElevation(x * squaresize, y * squaresize); } } // ArrayIndexer heightmapindexer = new ArrayIndexer( mapwidth + 1, mapheight + 1 ); logfile.WriteLine("calculating slopes..."); logfile.WriteLine("mapwidth: " + slopemapwidth + " " + slopemapheight); double[,] SlopeMap = new double[slopemapwidth, slopemapheight]; for (int y = 2; y < mapheight - 2; y += 2) { for (int x = 2; x < mapwidth - 2; x += 2) { AdvancedFloat3 e1 = new AdvancedFloat3(-squaresize * 4, HeightMap[x - 1, y - 1] - HeightMap[x + 3, y - 1], 0); AdvancedFloat3 e2 = new AdvancedFloat3(0, HeightMap[x - 1, y - 1] - HeightMap[x - 1, y + 3], -squaresize * 4); AdvancedFloat3 n = e2.Cross(e1); n.Normalize(); e1 = new AdvancedFloat3(squaresize * 4, HeightMap[x + 3, y + 3] - HeightMap[x - 1, y + 3], 0); e2 = new AdvancedFloat3(0, HeightMap[x + 3, y + 3] - HeightMap[x + 3, y - 1], squaresize * 4); AdvancedFloat3 n2 = e2.Cross(e1); n2.Normalize(); SlopeMap[x / 2, y / 2] = 1 - (n.y + n2.y) * 0.5; } } logfile.WriteLine("... slopes calculated"); return(SlopeMap); }
public static int DrawRectangle(Float3 pos, int width, int height, int groupnumber) { IAICallback aicallback = CSAI.GetInstance().aicallback; double elevation = aicallback.GetElevation(pos.x, pos.z) + 10; groupnumber = aicallback.CreateLineFigure(pos + new Float3(0, elevation, 0), pos + new Float3(width, elevation, 0), 10, false, 200, groupnumber); groupnumber = aicallback.CreateLineFigure(pos + new Float3(width, elevation, 0), pos + new Float3(width, elevation, height), 10, false, 200, groupnumber); groupnumber = aicallback.CreateLineFigure(pos + new Float3(width, elevation, height), pos + new Float3(0, elevation, height), 10, false, 200, groupnumber); groupnumber = aicallback.CreateLineFigure(pos + new Float3(0, elevation, height), pos + new Float3(0, elevation, 0), 10, false, 200, groupnumber); return(groupnumber); }
public double[,] GetHeightMap() { LogFile.GetInstance().WriteLine("Getting heightmap, this could take a while... "); IAICallback aicallback = CSAI.GetInstance().aicallback; int mapwidth = aicallback.GetMapWidth(); int mapheight = aicallback.GetMapHeight(); double[,] HeightMap = new double[mapwidth + 1, mapheight + 1]; for (int x = 0; x < mapwidth + 1; x++) { for (int y = 0; y < mapheight + 1; y++) { HeightMap[x, y] = aicallback.GetElevation(x * MovementMaps.SQUARE_SIZE, y * MovementMaps.SQUARE_SIZE); } } return(HeightMap); }
void ExploreWith(int unitid) { Float3 destination = new Float3(); if (PriorityTargets.Count > 0) { destination = PriorityTargets.Dequeue() as Float3; logfile.WriteLine("dequeued next destination: " + destination.ToString()); } else { destination.x = random.Next(0, aicallback.GetMapWidth() * MovementMaps.SQUARE_SIZE); destination.z = random.Next(0, aicallback.GetMapHeight() * MovementMaps.SQUARE_SIZE); destination.y = aicallback.GetElevation(destination.x, destination.y); logfile.WriteLine("mapwidth: " + aicallback.GetMapWidth() + " squaresize: " + MovementMaps.SQUARE_SIZE); logfile.WriteLine("ScoutController sending scout " + unitid + " to " + destination.ToString()); } aicallback.GiveOrder(unitid, new Command(Command.CMD_MOVE, destination.ToDoubleArray())); }
// algorithm more or less by krogothe // ported from Submarine's original C++ version public void SearchMetalSpots() { logfile.WriteLine("SearchMetalSpots() >>>"); isMetalMap = false; ArrayList metalspotsal = new ArrayList(); int mapheight = aicallback.GetMapHeight() / 2; //metal map has 1/2 resolution of normal map int mapwidth = aicallback.GetMapWidth() / 2; double mapmaxmetal = aicallback.GetMaxMetal(); int totalcells = mapheight * mapwidth; logfile.WriteLine("mapwidth: " + mapwidth + " mapheight " + mapheight + " maxmetal:" + mapmaxmetal); byte[] metalmap = aicallback.GetMetalMap(); // original metal map int[,] metalremaining = new int[mapwidth, mapheight]; // actual metal available at that point. we remove metal from this as we add spots to MetalSpots int[,] SpotAvailableMetal = new int [mapwidth, mapheight]; // amount of metal an extractor on this spot could make int[,] NormalizedSpotAvailableMetal = new int [mapwidth, mapheight]; // SpotAvailableMetal, normalized to 0-255 range int totalmetal = 0; ArrayIndexer arrayindexer = new ArrayIndexer(mapwidth, mapheight); //Load up the metal Values in each pixel logfile.WriteLine("width: " + mapwidth + " height: " + mapheight); for (int y = 0; y < mapheight; y++) { //string logline = ""; for (int x = 0; x < mapwidth; x++) { metalremaining[x, y] = (int)metalmap[arrayindexer.GetIndex(x, y)]; totalmetal += metalremaining[x, y]; // Count the total metal so you can work out an average of the whole map //logline += metalremaining[ x, y ].ToString() + " "; // logline += metalremaining[ x, y ] + " "; } // logfile.WriteLine( logline ); } logfile.WriteLine("*******************************************"); double averagemetal = ((double)totalmetal) / ((double)totalcells); //do the average // int maxmetal = 0; int ExtractorRadius = (int)(aicallback.GetExtractorRadius() / 16.0); int DoubleExtractorRadius = ExtractorRadius * 2; int SquareExtractorRadius = ExtractorRadius * ExtractorRadius; //used to speed up loops so no recalculation needed int FourSquareExtractorRadius = 4 * SquareExtractorRadius; // same as above double CellsInRadius = Math.PI * ExtractorRadius * ExtractorRadius; int maxmetalspotamount = 0; logfile.WriteLine("Calculating available metal for each spot..."); SpotAvailableMetal = CalculateAvailableMetalForEachSpot(metalremaining, ExtractorRadius, out maxmetalspotamount); logfile.WriteLine("Normalizing..."); // normalize the metal so any map will have values 0-255, no matter how much metal it has int[,] NormalizedMetalRemaining = new int[mapwidth, mapheight]; for (int y = 0; y < mapheight; y++) { for (int x = 0; x < mapwidth; x++) { NormalizedSpotAvailableMetal[x, y] = (SpotAvailableMetal[x, y] * 255) / maxmetalspotamount; } } logfile.WriteLine("maxmetalspotamount: " + maxmetalspotamount); bool Stopme = false; int SpotsFound = 0; //logfile.WriteLine( BuildTable.GetInstance().GetBiggestMexUnit().ToString() ); // IUnitDef biggestmex = BuildTable.GetInstance().GetBiggestMexUnit(); // logfile.WriteLine( "biggestmex is " + biggestmex.name + " " + biggestmex.humanName ); for (int spotindex = 0; spotindex < MaxSpots && !Stopme; spotindex++) { logfile.WriteLine("spotindex: " + spotindex); int bestspotx = 0, bestspoty = 0; int actualmetalatbestspot = 0; // use to try to put extractors over spot itself //finds the best spot on the map and gets its coords int BestNormalizedAvailableSpotAmount = 0; for (int y = 0; y < mapheight; y++) { for (int x = 0; x < mapwidth; x++) { if (NormalizedSpotAvailableMetal[x, y] > BestNormalizedAvailableSpotAmount || (NormalizedSpotAvailableMetal[x, y] == BestNormalizedAvailableSpotAmount && metalremaining[x, y] > actualmetalatbestspot)) { BestNormalizedAvailableSpotAmount = NormalizedSpotAvailableMetal[x, y]; bestspotx = x; bestspoty = y; actualmetalatbestspot = metalremaining[x, y]; } } } logfile.WriteLine("BestNormalizedAvailableSpotAmount: " + BestNormalizedAvailableSpotAmount); if (BestNormalizedAvailableSpotAmount < MinMetalForSpot) { Stopme = true; // if the spots get too crappy it will stop running the loops to speed it all up logfile.WriteLine("Remaining spots too small; stopping search"); } if (!Stopme) { Float3 pos = new Float3(); pos.x = bestspotx * 2 * MovementMaps.SQUARE_SIZE; pos.z = bestspoty * 2 * MovementMaps.SQUARE_SIZE; pos.y = aicallback.GetElevation(pos.x, pos.z); //pos = Map.PosToFinalBuildPos( pos, biggestmex ); logfile.WriteLine("Metal spot: " + pos + " " + BestNormalizedAvailableSpotAmount); MetalSpot thismetalspot = new MetalSpot((int)((BestNormalizedAvailableSpotAmount * mapmaxmetal * maxmetalspotamount) / 255), pos); // if (aicallback.CanBuildAt(biggestmex, pos) ) // { // pos = Map.PosToBuildMapPos( pos, biggestmex ); // logfile.WriteLine( "Metal spot: " + pos + " " + BestNormalizedAvailableSpotAmount ); // if(pos.z >= 2 && pos.x >= 2 && pos.x < mapwidth -2 && pos.z < mapheight -2) // { // if(CanBuildAt(pos.x, pos.z, biggestmex.xsize, biggestmex.ysize)) // { metalspotsal.Add(thismetalspot); SpotsFound++; //if(pos.y >= 0) //{ // SetBuildMap(pos.x-2, pos.z-2, biggestmex.xsize+4, biggestmex.ysize+4, 1); //} //else //{ //SetBuildMap(pos.x-2, pos.z-2, biggestmex.xsize+4, biggestmex.ysize+4, 5); //} // } // } // } for (int myx = bestspotx - (int)ExtractorRadius; myx < bestspotx + (int)ExtractorRadius; myx++) { if (myx >= 0 && myx < mapwidth) { for (int myy = bestspoty - (int)ExtractorRadius; myy < bestspoty + (int)ExtractorRadius; myy++) { if (myy >= 0 && myy < mapheight && ((bestspotx - myx) * (bestspotx - myx) + (bestspoty - myy) * (bestspoty - myy)) <= (int)SquareExtractorRadius) { metalremaining[myx, myy] = 0; //wipes the metal around the spot so its not counted twice NormalizedSpotAvailableMetal[myx, myy] = 0; } } } } // Redo the whole averaging process around the picked spot so other spots can be found around it for (int y = bestspoty - (int)DoubleExtractorRadius; y < bestspoty + (int)DoubleExtractorRadius; y++) { if (y >= 0 && y < mapheight) { for (int x = bestspotx - (int)DoubleExtractorRadius; x < bestspotx + (int)DoubleExtractorRadius; x++) { //funcion below is optimized so it will only update spots between r and 2r, greatly speeding it up if ((bestspotx - x) * (bestspotx - x) + (bestspoty - y) * (bestspoty - y) <= (int)FourSquareExtractorRadius && x >= 0 && x < mapwidth && NormalizedSpotAvailableMetal[x, y] > 0) { totalmetal = 0; for (int myx = x - (int)ExtractorRadius; myx < x + (int)ExtractorRadius; myx++) { if (myx >= 0 && myx < mapwidth) { for (int myy = y - (int)ExtractorRadius; myy < y + (int)ExtractorRadius; myy++) { if (myy >= 0 && myy < mapheight && ((x - myx) * (x - myx) + (y - myy) * (y - myy)) <= (int)SquareExtractorRadius) { totalmetal += metalremaining[myx, myy]; //recalculate nearby spots to account for deleted metal from chosen spot } } } } NormalizedSpotAvailableMetal[x, y] = totalmetal * 255 / maxmetalspotamount; //set that spots metal amount } } } } } } if (SpotsFound > 500) { isMetalMap = true; metalspotsal.Clear(); logfile.WriteLine("Map is considered to be a metal map"); } else { isMetalMap = false; // debug //for(list<AAIMetalSpot>::iterator spot = metal_spots.begin(); spot != metal_spots.end(); spot++) } MetalSpots = ( MetalSpot[] )metalspotsal.ToArray(typeof(MetalSpot)); SaveCache(); logfile.WriteLine("SearchMetalSpots() <<<"); }
// note: need to check compatible area public Float3 GetNearestUnseen(Float3 currentpos, IUnitDef unitdef, int unseensmeansthismanyframes) { LosMap losmap = LosMap.GetInstance(); IAICallback aicallback = CSAI.GetInstance().aicallback; int mapwidth = aicallback.GetMapWidth(); int mapheight = aicallback.GetMapHeight(); int currentunitarea = MovementMaps.GetInstance().GetArea(unitdef, currentpos); int losmapwidth = losmap.LastSeenFrameCount.GetUpperBound(0) + 1; int losmapheight = losmap.LastSeenFrameCount.GetUpperBound(0) + 1; int maxradius = (int)Math.Sqrt(losmapheight * losmapheight + losmapwidth * losmapwidth); int unitlosradius = (int)unitdef.losRadius; // this is in map / 2 units, so it's ok Int2[] circlepoints = CreateCirclePoints(unitlosradius); int bestradius = 10000000; int bestarea = 0; Float3 bestpos = null; int unitmapx = (int)(currentpos.x / 16); int unitmapy = (int)(currentpos.y / 16); int thisframecount = aicallback.GetCurrentFrame(); // step around in unitlosradius steps for (int radiuslosunits = unitlosradius * 2; radiuslosunits <= maxradius; radiuslosunits += unitlosradius) { // calculate angle for a unitlosradius / 2 step at this radius. // DrawingUtils.DrawCircle(currentpos, radiuslosunits * 16); double anglestepradians = 2 * Math.Asin((double)unitlosradius / 2 / (double)radiuslosunits); //csai.DebugSay("anglestepradians: " + anglestepradians); //return null; for (double angleradians = 0; angleradians <= Math.PI * 2; angleradians += anglestepradians) { int unseenarea = 0; int searchmapx = unitmapx + (int)((double)radiuslosunits * Math.Cos(angleradians)); int searchmapy = unitmapy + (int)((double)radiuslosunits * Math.Sin(angleradians)); if (searchmapx >= 0 && searchmapy >= 0 && searchmapx < (mapwidth / 2) && searchmapy < (mapheight / 2)) { // if (csai.DebugOn) // { // int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 50 + aicallback.GetElevation( searchmapx * 16, searchmapy * 16 ), searchmapy * 16), unitlosradius * 16); // aicallback.SetFigureColor(groupnumber, 1, 1, 0, 0.5); // } int thisareanumber = MovementMaps.GetInstance().GetArea(unitdef, new Float3(searchmapx * 16, 0, searchmapy * 16)); if (thisareanumber == currentunitarea) {// //if (csai.DebugOn) // { // int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100, searchmapy * 16), unitlosradius * 16); // aicallback.SetFigureColor(groupnumber, 1, 1, 0, 0.5); // } foreach (Int2 point in circlepoints) { int thismapx = searchmapx + point.x; int thismapy = searchmapy + point.y; if (thismapx >= 0 && thismapy >= 0 && thismapx < mapwidth / 2 && thismapy < mapheight / 2) { if (thisframecount - losmap.LastSeenFrameCount[thismapx, thismapy] > unseensmeansthismanyframes) { unseenarea++; } } } if (unseenarea >= (circlepoints.GetUpperBound(0) + 1) * 8 / 10) { int groupnumber = DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100 * aicallback.GetElevation(searchmapx * 16, searchmapy * 16), searchmapy * 16), unitlosradius * 16); aicallback.SetFigureColor(groupnumber, 1, 0, 1, 0.5); return(new Float3(searchmapx * 16, 0, searchmapy * 16)); } // return new Float3(searchmapx * 16, 0, searchmapy * 16); // for debugging, remove later } } } } return(null); }