// ReserveSpace; ideally the reserver would pass himself in as IBuildMapReserver or something , but object for now (not yet used) // note that destroying a unit over this space wont undo reservation, since not included in buildinginfobyid list // (maybe buildinginfobyowner???) public void ReserveSpace(object owner, int mapx, int mapy, int sizex, int sizey) { if (csai.DebugOn) { DrawingUtils.DrawRectangle( new Float3((mapx - sizex / 2) * 8, 0, (mapy - sizey / 2) * 8), sizex * 8, sizey * 8, 0); // logfile.WriteLine( "marking " + thisx + " " + thisy + " as used by " + owner.ToString() ); // aicallback.DrawUnit( "ARMMINE1", new Float3( thisx * 8, aicallback.GetElevation( thisx * 8, thisy * 8 ), thisy * 8 ), 0.0f, 400, aicallback.GetMyAllyTeam(), true, true); } for (int x = 0; x < sizex; x++) { for (int y = 0; y < sizey; y++) { int thisx = mapx + x - sizex / 2; int thisy = mapy + y - sizey / 2; if (thisx >= 0 && thisy >= 0 && thisx < mapwidth && thisy < mapheight) { SquareAvailable[thisx, thisy] = false; } } } }
public void DumpLosMap(string cmd, string[] split, int player) { bool[,] losmap = new bool[mapwidth / 2, mapheight / 2]; for (int y = 0; y < mapheight / 2; y++) { for (int x = 0; x < mapwidth / 2; x++) { losmap[x, y] = (aicallback.GetCurrentFrame() - LastSeenFrameCount[x, y] < 6000); } } DrawingUtils.DrawMap(losmap); }
// note: need to check compatible area public Float3 GetNearestUnseen(Float3 currentpos, IUnitDef unitdef, int unseensmeansthismanyframes) { int currentunitarea = MovementMaps.GetInstance().GetArea(unitdef, currentpos); int losmapwidth = LastSeenFrameCount.GetUpperBound(0) + 1; int losmapheight = LastSeenFrameCount.GetUpperBound(0) + 1; int maxradius = Math.Max(losmapheight, 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 / 2 steps for (int radius = unitlosradius * 2; radius <= maxradius; radius += unitlosradius / 2) { // calculate angle for a unitlosradius / 2 step at this radius. double anglestepradians = 2 * Math.Asin(unitlosradius / 2 / 2 / radius); for (double angleradians = 0; angleradians <= Math.PI * 2; angleradians += anglestepradians) { int unseenarea = 0; int searchmapx = unitmapx + (int)((double)radius * Math.Cos(angleradians)); int searchmapy = unitmapy + (int)((double)radius * Math.Sin(angleradians)); int thisareanumber = MovementMaps.GetInstance().GetArea(unitdef, new Float3(searchmapx * 16, 0, searchmapy * 16)); if (thisareanumber == currentunitarea) { if (csai.DebugOn) { DrawingUtils.DrawCircle(new Float3(searchmapx * 16, 100, searchmapy * 16), unitlosradius); } foreach (Int2 point in circlepoints) { if (thisframecount - LastSeenFrameCount[searchmapx + point.x, searchmapx + point.y] > unseensmeansthismanyframes) { unseenarea++; } } if (unseenarea >= (circlepoints.GetUpperBound(0) + 1) * 8 / 10) { return(new Float3(searchmapx * 16, 0, searchmapy * 16)); } } } } return(null); }
// mark squares as used // and keep record of where this unit was, and how big, in case it is destroyed public void UnitCreated(int id, IUnitDef unitdef) { if (!buildinginfobyid.Contains(id) && !unitdefhelp.IsMobile(unitdef)) { Float3 pos = aicallback.GetUnitPos(id); int mapposx = (int)(pos.x / 8); int mapposy = (int)(pos.z / 8); //int unitsizex = (int)Math.Ceiling( unitdef.xsize / 8.0 ); //int unitsizey = (int)Math.Ceiling( unitdef.ysize / 8.0 ); int unitsizex = unitdef.xsize; int unitsizey = unitdef.ysize; logfile.WriteLine("Buildmap unitcreated " + unitdef.name + " mappos " + mapposx + " " + mapposy + " unitsize " + unitsizex + " " + unitsizey); buildinginfobyid.Add(id, new BuildingInfo(mapposx, mapposy, unitsizex, unitsizey)); if (csai.DebugOn) { DrawingUtils.DrawRectangle( new Float3((mapposx - unitdef.xsize / 2) * 8, 0, (mapposy - unitdef.ysize / 2) * 8), unitdef.xsize * 8, unitdef.ysize * 8, 0); } for (int x = 0; x < unitsizex; x++) { for (int y = 0; y < unitsizey; y++) { int thisx = mapposx + x - unitdef.xsize / 2; int thisy = mapposy + y - unitdef.ysize / 2; SquareAvailable[thisx, thisy] = false; //if( csai.DebugOn ) //{ // logfile.WriteLine( "marking " + thisx + " " + thisy + " as used by " + unitdef.name ); // aicallback.DrawUnit( "ARMMINE1", new Float3( thisx * 8, aicallback.GetElevation( thisx * 8, thisy * 8 ), thisy * 8 ), 0.0f, 400, aicallback.GetMyAllyTeam(), true, true); //} } } } }
public void DumpBuildMap(string cmd, string[] split, int player) { DrawingUtils.DrawMap(SquareAvailable); }
// 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); }