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 }));
            }
        }
예제 #2
0
        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);
            //}
        }
예제 #3
0
        // 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);
        }
예제 #4
0
 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() ) );
 }
예제 #5
0
        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);
        }
예제 #6
0
        // 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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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()));
        }
예제 #10
0
        // 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() <<<");
        }
예제 #11
0
        // 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);
        }