public static Float3 GetNearestReclaim(Float3 mypos, int constructorid) { if( CSAI.GetInstance().aicallback.GetCurrentFrame() == 0 )// check ticks first, beacuse metal shows as zero at start { return null; } LogFile logfile = LogFile.GetInstance(); IAICallback aicallback = CSAI.GetInstance().aicallback; IUnitDef unitdef = UnitController.GetInstance().UnitDefByDeployedId[ constructorid ]; if (!new UnitDefHelp(aicallback).IsMobile(unitdef)) { return null; } //Float3 mypos = aicallback.GetUnitPos( constructorid ); MovementMaps movementmaps = MovementMaps.GetInstance(); int currentarea = movementmaps.GetArea( unitdef, mypos ); //double nearestreclaimdistancesquared = 1000000; //Float3 nearestreclaimpos = null; double bestmetaldistanceratio = 0; int bestreclaimid = 0; int metalspace = (int)( aicallback.GetMetalStorage() - aicallback.GetMetal() ); logfile.WriteLine( "available space in metal storage: " + metalspace ); int[] nearbyfeatures = aicallback.GetFeatures( mypos, maxreclaimradius ); bool reclaimfound = false; foreach( int feature in nearbyfeatures ) { IFeatureDef featuredef = aicallback.GetFeatureDef( feature ); if( featuredef.metal > 0 && featuredef.metal <= metalspace ) { Float3 thisfeaturepos = aicallback.GetFeaturePos( feature ); double thisdistance = Math.Sqrt( Float3Helper.GetSquaredDistance( thisfeaturepos, mypos ) ); double thismetaldistanceratio = featuredef.metal / thisdistance; if( thismetaldistanceratio > bestmetaldistanceratio && movementmaps.GetArea( unitdef, thisfeaturepos ) == currentarea ) { logfile.WriteLine( "Potential reclaim, distance = " + thisdistance + " metal = " + featuredef.metal + " ratio = " + thismetaldistanceratio ); bestmetaldistanceratio = thismetaldistanceratio; bestreclaimid = feature; // nearestreclaimpo reclaimfound = true; } } } if( reclaimfound && ( bestmetaldistanceratio > ( 1.0 / ( 100 * reclaimradiusperonehundredmetal ) ) ) ) { Float3 reclaimpos = aicallback.GetFeaturePos( bestreclaimid ); logfile.WriteLine( "Reclaim found, pos " + reclaimpos.ToString() ); if( CSAI.GetInstance().DebugOn ) { aicallback.DrawUnit( "ARMMEX", reclaimpos, 0.0f, 200, aicallback.GetMyAllyTeam(), true, true); } return reclaimpos; //aicallback.GiveOrder( constructorid, new Command( Command.CMD_RECLAIM, // new double[]{ reclaimpos.x, reclaimpos.y, reclaimpos.z, 10 } ) ); } else { //logfile.WriteLine( "No reclaim within parameters" ); return null; } }
public static Float3 operator *( double multiplier, Float3 a ) { Float3 result = new Float3(); result.x = a.x * multiplier; result.y = a.y * multiplier; result.z = a.z * multiplier; return result; }
public static Float3 operator-( Float3 a, Float3 b ) { Float3 result = new Float3(); result.x = a.x - b.x; result.y = a.y - b.y; result.z = a.z - b.z; return result; }
// cheap hack to respond to enemy shooting us void csai_UnitDamagedEvent(int damaged, int attacker, float damage, Float3 dir) { /* if (!EnemyUnitDefByDeployedId.ContainsKey(attacker)) { EnemyUnitDefByDeployedId.Add(attacker, aicallback.GetUnitDef(attacker)); } */ //if (!EnemyStaticPosByDeployedId.ContainsKey(attacker)) //{ Float3 enemypos = aicallback.GetUnitPos(attacker); if (enemypos != null && Float3Helper.GetSquaredDistance(enemypos, new Float3(0, 0, 0)) > 10 * 10) { logfile.WriteLine("unitdamaged, attacker " + attacker + " pos " + enemypos); if (!EnemyStaticPosByDeployedId.ContainsKey(attacker)) { EnemyStaticPosByDeployedId.Add(attacker, enemypos); } else { EnemyStaticPosByDeployedId[attacker] = enemypos; } if (NewStaticEnemyAddedEvent != null) { NewStaticEnemyAddedEvent(attacker, enemypos, null); } } else // else we guess... { if (FriendlyUnitPositionObserver.GetInstance().PosById.ContainsKey(damaged)) { Float3 ourunitpos = FriendlyUnitPositionObserver.GetInstance().PosById[damaged]; if (ourunitpos != null) { Float3 guessvectortotarget = dir * 300.0; logfile.WriteLine("vectortotarget guess: " + guessvectortotarget.ToString()); Float3 possiblepos = ourunitpos + guessvectortotarget; if (!EnemyStaticPosByDeployedId.ContainsKey(attacker)) { EnemyStaticPosByDeployedId.Add(attacker, possiblepos); } else { EnemyStaticPosByDeployedId[attacker] = possiblepos; } if (NewStaticEnemyAddedEvent != null) { NewStaticEnemyAddedEvent(attacker, possiblepos, null); } logfile.WriteLine("unitdamaged, attacker " + attacker + " our unit pos " + ourunitpos + " dir " + dir.ToString() + " guess: " + possiblepos.ToString()); } } } //} }
void UnitCreatedEvent(int deployedunitid, IUnitDef unitdef) { IAICallback aicallback = CSAI.GetInstance().aicallback; if (aicallback.GetCurrentFrame() <= 1) { if (unitdef.isCommander) { startposition = aicallback.GetUnitPos(deployedunitid); //aicallback.get } } }
public static void DrawCircle( Float3 pos, double radius ) { IAICallback aicallback = CSAI.GetInstance().aicallback; Float3 lastpos = null; for( int angle = 0; angle <= 360; angle += 10 ) { int x = (int)( (double)radius * Math.Cos ( (double)angle * Math.PI / 180 ) ); int y = (int)( (double)radius * Math.Sin ( (double)angle * Math.PI / 180 ) ); Float3 thispos = new Float3( x, 0, y ) + pos; if( lastpos != null ) { aicallback.CreateLineFigure( thispos,lastpos,10,false,200,0); } lastpos = thispos; } }
public void SetTarget(Float3 target) { //this.targetid = targetid; //Activate(); }
public void SetTarget( Float3 target ) { //this.targetid = targetid; //Activate(); }
public static double GetSquaredDistance( Float3 one, Float3 two ) { return ( two.x - one.x ) * ( two.x - one.x ) + ( two.y - one.y ) * ( two.y - one.y ) + ( two.z - one.z ) * ( two.z - one.z ); }
UnitInfo[] GetClosestUnits( Hashtable UnitDefListByDeployedId, Float3 targetpos, int numclosestunits ) { UnitInfo[] closestunits = new UnitInfo[ numclosestunits ]; double worsttopfivesquareddistance = 0; // got to get better than this to enter the list int numclosestunitsfound = 0; foreach( DictionaryEntry de in UnitDefListByDeployedId ) { int deployedid = (int)de.Key; IUnitDef unitdef = de.Value as IUnitDef; Float3 unitpos = aicallback.GetUnitPos( deployedid ); double unitsquareddistance = Float3Helper.GetSquaredDistance( unitpos, targetpos ); if( numclosestunitsfound < numclosestunits ) { UnitInfo unitinfo = new UnitInfo( deployedid, unitpos, unitdef, unitsquareddistance ); InsertIntoArray( closestunits, unitinfo, numclosestunitsfound ); numclosestunitsfound++; worsttopfivesquareddistance = closestunits[ numclosestunitsfound - 1 ].squareddistance; } else if( unitsquareddistance < worsttopfivesquareddistance ) { UnitInfo unitinfo = new UnitInfo( deployedid, unitpos, unitdef, unitsquareddistance ); InsertIntoArray( closestunits, unitinfo, numclosestunits ); worsttopfivesquareddistance = closestunits[ numclosestunits - 1 ].squareddistance; } } return closestunits; }
UnitInfo[] GetClosestUnits(Dictionary <int, IUnitDef> UnitDefListByDeployedId, Float3 targetpos, int numclosestunits) { UnitInfo[] closestunits = new UnitInfo[numclosestunits]; double worsttopfivesquareddistance = 0; // got to get better than this to enter the list int numclosestunitsfound = 0; foreach (KeyValuePair <int, IUnitDef> kvp in UnitDefListByDeployedId) { int deployedid = kvp.Key; IUnitDef unitdef = kvp.Value; Float3 unitpos = aicallback.GetUnitPos(deployedid); double unitsquareddistance = Float3Helper.GetSquaredDistance(unitpos, targetpos); if (numclosestunitsfound < numclosestunits) { UnitInfo unitinfo = new UnitInfo(deployedid, unitpos, unitdef, unitsquareddistance); InsertIntoArray(closestunits, unitinfo, numclosestunitsfound); numclosestunitsfound++; worsttopfivesquareddistance = closestunits[numclosestunitsfound - 1].squareddistance; } else if (unitsquareddistance < worsttopfivesquareddistance) { UnitInfo unitinfo = new UnitInfo(deployedid, unitpos, unitdef, unitsquareddistance); InsertIntoArray(closestunits, unitinfo, numclosestunits); worsttopfivesquareddistance = closestunits[numclosestunits - 1].squareddistance; } } return(closestunits); }
// 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); }
public static void WriteFloat3ToXmlElement(Float3 float3, XmlElement element) { element.SetAttribute("x", float3.x.ToString()); element.SetAttribute("y", float3.y.ToString()); element.SetAttribute("z", float3.z.ToString()); }
public IUnitOrder RegisterBuildingOrder(IFactoryController factorycontroller, IUnitDef orderedunittype, Float3 orderedpos) { Order order = new Order(factorycontroller, orderedunittype, orderedpos); orders.Add(order); return(order); }
void CommanderBuildAt(IUnitDef unitdef, Float3 buildsite) { logfile.WriteLine("Commander building " + unitdef.name + " at " + buildsite.ToString()); aicallback.DrawUnit(unitdef.name, buildsite, 0.0f, 500, aicallback.GetMyAllyTeam(), true, true); aicallback.GiveOrder(commanderid, new Command(-unitdef.id, buildsite.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() <<<"); }
public Order(IFactoryController factorycontroller, IUnitDef orderedunit, Float3 pos) { this.factorycontroller = factorycontroller; this.orderedunit = orderedunit; this.pos = pos; }
public MetalSpot(int amount, Float3 pos, bool isoccupied) { Amount = amount; IsOccupied = isoccupied; Pos = pos; }
public MetalSpot(int amount, Float3 pos) { Amount = amount; Pos = pos; }
public Float3 ClosestBuildSite(IUnitDef unitdef, Float3 approximatepos, int maxposradius, int mindistancemapunits) { // ok, so plan is we work our way out in a kindof spiral // we start in centre, and increase radius, and work around in a square at each radius, until we find something int centrex = (int)(approximatepos.x / 8); int centrey = (int)(approximatepos.z / 8); //int radius = 0; int radius = mindistancemapunits; int unitsizexwithmargin = unitdef.xsize + 2 * BuildMargin; int unitsizeywithmargin = unitdef.ysize + 2 * BuildMargin; if (unitdefhelp.IsFactory(unitdef)) { unitsizeywithmargin += 8; centrey += 4; } BuildMap buildmap = BuildMap.GetInstance(); MovementMaps movementmaps = MovementMaps.GetInstance(); // while( radius < mapwidth || radius < mapheight ) // hopefully we never get quite this far... while (radius < (maxposradius / 8)) { // logfile.WriteLine( "ClosestBuildSite radius " + radius ); for (int deltax = -radius; deltax <= radius; deltax++) { for (int deltay = -radius; deltay <= radius; deltay++) { if (deltax == radius || deltax == -radius || deltay == radius || deltay == -radius) // ignore the hollow centre of square { // logfile.WriteLine( "delta " + deltax + " " + deltay ); bool positionok = true; // go through each square in proposed site, check not build on for (int buildmapy = centrey - unitsizeywithmargin / 2; positionok && buildmapy < centrey + unitsizeywithmargin / 2; buildmapy++) { //string logline = ""; for (int buildmapx = centrex - unitsizexwithmargin / 2; positionok && buildmapx < centrex + unitsizexwithmargin / 2; buildmapx++) { int thisx = buildmapx + deltax; int thisy = buildmapy + deltay; if (thisx < 0 || thisy < 0 || thisx >= mapwidth || thisy >= mapwidth || !buildmap.SquareAvailable[thisx, thisy] || !movementmaps.vehiclemap[thisx / 2, thisy / 2]) { //logfile.WriteLine( "check square " + buildmapx + " " + buildmapy + " NOK" ); positionok = false; // logline += "*"; } else { // logline += "-"; } //logfile.WriteLine( "check square " + buildmapx + " " + buildmapy + "Ok" ); } // logfile.WriteLine( logline ); } // logfile.WriteLine(""); if (positionok) { return(new Float3((centrex + deltax) * 8, 0, (centrey + deltay) * 8)); } } } } radius++; } return(null); }
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() ) ); GiveOrderWrapper.GetInstance().MoveTo(unitid, destination); }
void Reappraise() { foreach (DictionaryEntry scoutde in ScoutUnitDefsById) { int scoutdeployedid = (int)scoutde.Key; Float3 scoutpos = aicallback.GetUnitPos(scoutdeployedid); Float3 nearestpos = null; double bestsquareddistance = 100000000; int targetid = 0; // need to add index by position for this, to speed things up foreach (DictionaryEntry de in EnemyController.GetInstance().EnemyUnitDefByDeployedId) { int deployedid = (int)de.Key; IUnitDef unitdef = de.Value as IUnitDef; if (unitdef != null) { Float3 thispos = aicallback.GetUnitPos(deployedid); if (IsPriorityTarget(unitdef)) { double thissquareddistance = Float3Helper.GetSquaredDistance(scoutpos, thispos); if (thissquareddistance < bestsquareddistance) { bool nolasertowersnear = true; foreach (DictionaryEntry attackerde in EnemyController.GetInstance().EnemyUnitDefByDeployedId) { int attackerid = (int)attackerde.Key; IUnitDef attackerunitdef = attackerde.Value as IUnitDef; if (attackerunitdef != null) { if (IsLaserTower(attackerunitdef)) { Float3 attackerpos = aicallback.GetUnitPos(attackerid); if (Float3Helper.GetSquaredDistance(attackerpos, thispos) < nearbyforenemiesmeans * nearbyforenemiesmeans) { nolasertowersnear = false; } } } } if (nolasertowersnear) { nearestpos = thispos; bestsquareddistance = thissquareddistance; targetid = deployedid; } } } } } if (nearestpos != null) { aicallback.GiveOrder(scoutdeployedid, new Command(Command.CMD_ATTACK, new double[] { targetid })); if (!attackingscouts.Contains(scoutdeployedid)) { attackingscouts.Add(scoutdeployedid); } } else { if (attackingscouts.Contains(scoutdeployedid)) { ExploreWith(scoutdeployedid); attackingscouts.Remove(scoutdeployedid); } } } }
void Reappraise() { // logfile.WriteLine("reappraise>>>"); foreach (KeyValuePair <int, IUnitDef> scoutkvp in ScoutUnitDefsById) { int scoutdeployedid = scoutkvp.Key; Float3 scoutpos = aicallback.GetUnitPos(scoutdeployedid); Float3 nearestpos = null; double bestsquareddistance = 100000000; int targetid = 0; // need to add index by position for this, to speed things up foreach (KeyValuePair <int, IUnitDef> enemykvp in EnemyController.GetInstance().EnemyUnitDefByDeployedId) { int deployedid = enemykvp.Key; IUnitDef unitdef = enemykvp.Value; if (unitdef != null) { if (IsPriorityTarget(unitdef)) { logfile.WriteLine("considering unit " + deployedid + " " + unitdef.name); Float3 thispos = aicallback.GetUnitPos(deployedid); double thissquareddistance = Float3Helper.GetSquaredDistance(scoutpos, thispos); if (thissquareddistance < bestsquareddistance) { bool nolasertowersnear = true; foreach (KeyValuePair <int, IUnitDef> attackerkvp in EnemyController.GetInstance().EnemyUnitDefByDeployedId) { int attackerid = attackerkvp.Key; IUnitDef attackerunitdef = attackerkvp.Value; if (attackerunitdef != null) { if (IsLaserTower(attackerunitdef)) { Float3 attackerpos = aicallback.GetUnitPos(attackerid); if (Float3Helper.GetSquaredDistance(attackerpos, thispos) < nearbyforenemiesmeans * nearbyforenemiesmeans) { nolasertowersnear = false; } } } } if (nolasertowersnear) { nearestpos = thispos; bestsquareddistance = thissquareddistance; targetid = deployedid; } } } } } if (nearestpos != null) { GiveOrderWrapper.GetInstance().Attack(scoutdeployedid, targetid); if (!attackingscouts.Contains(scoutdeployedid)) { attackingscouts.Add(scoutdeployedid); } } else { if (attackingscouts.Contains(scoutdeployedid)) { ExploreWith(scoutdeployedid); attackingscouts.Remove(scoutdeployedid); } } } // logfile.WriteLine("reappraise<<<"); }
public void EnemyDamaged(int damaged, int attacker, float damage, Float3 dir) //called when an enemy inside los or radar is damaged { }
//called when one of your units are damaged public void UnitDamaged(int damaged,int attacker,float damage, Float3 dir) { try { if( UnitDamagedEvent != null ) { UnitDamagedEvent( damaged, attacker, damage, dir ); } } catch( Exception e ) { logfile.WriteLine( "Exception: " + e.ToString() ); SendTextMsg("Exception: " + e.ToString()); } }
public IUnitDef WhatShouldIBuild(UnitDefArrayList constructordef, int constructorid, Float3 pos) { Priorities.Add( 1.0, tanks, 5 ) Priorities.Add( 0.8, radar, position ) if (isfactory) { if (numbertanks < 5 || numberscouts >= 2 ) { if (haveenergy(buildtank)) { if (havemetal(buildtank)) { buildtank(); } } else { buildenergy(); } } else { if (numberscouts < 1) { if( } } } if( isconstructor ) { } }
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; }
void Build(int constructorid, IUnitDef unitdef) { Float3 constructorpos = aicallback.GetUnitPos(constructorid); BuildAt(constructorid, unitdef, constructorpos); }
void Regroup( Float3 regouppos ) { // logfile.WriteLine( "AttackPackCoordinator regrouping to " + regouppos.ToString() ); // if( debugon ) // { // aicallback.SendTextMsg( "AttackPackCoordinator regrouping to " + regouppos.ToString(), 0 ); // } MoveTo( regouppos ); }
public static void WriteXmlElementToFloat3( XmlElement element, Float3 float3 ) { float3.x = Convert.ToDouble( element.GetAttribute( "x" ) ); float3.y = Convert.ToDouble( element.GetAttribute( "y" ) ); float3.z = Convert.ToDouble( element.GetAttribute( "z" ) ); }
public Float3(Float3 src) { this.x = src.x; this.y = src.y; this.z = src.z; }
public void Reclaim(int unitid, Float3 pos, double radius) { GiveOrder(new ReclaimCommand(unitid, pos, radius)); }
public UnitInCreation(IUnitRequester requester, IUnitDef unitdef, Float3 pos) { this.unitrequester = requester; this.unitdef = unitdef; this.pos = pos; }
public void BuildUnit(int builderid, string targetunitname, Float3 pos) { int targetunittypeid = BuildTable.GetInstance().UnitDefByName[targetunitname.ToLower()].id; GiveOrder( new BuildCommand( builderid, targetunittypeid, pos ) ); }
public static void WriteFloat3ToXmlElement( Float3 float3, XmlElement element ) { element.SetAttribute( "x", float3.x.ToString() ); element.SetAttribute( "y", float3.y.ToString() ); element.SetAttribute( "z", float3.z.ToString() ); }
public void UnitDamaged(int damaged, int attacker, float damage, Float3 dir) //called when one of your units are damaged { }
public void MoveTo(int unitid, Float3 pos) { GiveOrder( new MoveToCommand( unitid, pos ) ); }
public void InitStartPos(Float3 startpos) { startarea = MovementMaps.GetInstance().GetArea(typicalunitdef, startpos); }
public void Attack(int unitid, Float3 pos) { GiveOrder( new AttackCommand( unitid, new PositionTarget( pos ) ) ); }
// just get nearest known slow enemy // otherwise any enemy // no priority for buildings public Float3 ChooseAttackPoint(Float3 ourpos) { int bestid = 0; bool gotknownunit = false; IUnitDef defforbestid = null; Float3 posforbestid = null; double BestSquaredDistance = 100000000000; foreach (KeyValuePair <int, IUnitDef> kvp in enemycontroller.EnemyUnitDefByDeployedId) { int thisenemyid = kvp.Key; IUnitDef unitdef = kvp.Value; Float3 enemypos = aicallback.GetUnitPos(thisenemyid); //Float3 enemypos = EnemyMap.GetInstance(). // logfile.WriteLine( "Found building " + if (enemypos != null) { if (MovementMaps.GetInstance().GetArea(typicalunitdef, enemypos) == startarea) { if (Float3Helper.GetSquaredDistance(new Float3(0, 0, 0), enemypos) > 1) { double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); if (unitdef != null) { if (unitdef.speed < maxenemyspeed) // if we already have building we dont care { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best known so far" ); bestid = thisenemyid; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } else { if (!gotknownunit) // otherwise just ignore unknown units { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best unknown so far" ); bestid = thisenemyid; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } } } } foreach (KeyValuePair <int, Float3> kvp in enemycontroller.EnemyStaticPosByDeployedId) { // logfile.WriteLine( "EnemySelector: checking static... " ); int thisenemyid = kvp.Key; Float3 enemypos = kvp.Value; if (enemypos != null) { double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "EnemySelector: best distance so far" ); bestid = thisenemyid; //gotbuilding = true; gotknownunit = true; posforbestid = enemypos; //defforbestid = unitdef; } } } return(posforbestid); }
// this is going to have to interact with all sorts of stuff in the future // for now keep it simple // for now we look for nearby buildings, then nearby enemy units with low speed, then anything public Float3 ChooseAttackPoint(Float3 ourpos) { bool gotbuilding = false; bool gotknownunit = false; double BestSquaredDistance = 100000000000; int bestid = 0; IUnitDef defforbestid = null; Float3 posforbestid = null; // logfile.WriteLine( "EnemySelector: checking mobile... " ); foreach (DictionaryEntry de in enemycontroller.EnemyUnitDefByDeployedId) { int thisenemyid = (int)de.Key; IUnitDef unitdef = de.Value as IUnitDef; Float3 enemypos = aicallback.GetUnitPos(thisenemyid); // logfile.WriteLine( "Found building " + double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if (unitdef != null) { // logfile.WriteLine( "unitdef not null " + unitdef.humanName + " ismobile: " + unitdefhelp.IsMobile( unitdef ).ToString() ); // logfile.WriteLine( "gotbuilding = " + gotbuilding.ToString() ); if (gotbuilding) { if (!unitdefhelp.IsMobile(unitdef)) { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best building so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } else { if (unitdef.speed < maxenemyspeed) // if we already have building we dont care { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best known so far" ); bestid = thisenemyid; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } else // if unitdef unknown { // logfile.WriteLine( "gotknownunit = " + gotknownunit.ToString() ); if (!gotknownunit) // otherwise just ignore unknown units { if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "best unknown so far" ); bestid = thisenemyid; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } foreach (DictionaryEntry de in enemycontroller.EnemyStaticPosByDeployedId) { // logfile.WriteLine( "EnemySelector: checking static... " ); int thisenemyid = (int)de.Key; Float3 enemypos = de.Value as Float3; double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, enemypos); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if (thissquareddistance < BestSquaredDistance) { // logfile.WriteLine( "EnemySelector: best distance so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; //defforbestid = unitdef; } } //if( enemycontroller.EnemyStaticPosByDeployedId.Contains( bestid ) ) // { // enemycontroller.EnemyStaticPosByDeployedId.Remove( bestid ); // } return(posforbestid); }
void csai_UnitIdleEvent(int deployedunitid) { IUnitDef unitdef = UnitController.GetInstance().UnitDefByDeployedId[deployedunitid]; if (!unitdef.canBuild) { //logfile.WriteLine("cantbuild"); return; } logfile.WriteLine("unitidleevent " + deployedunitid + " " + unitdef.name + " " + unitdef.humanName); if (ActiveConstructors.Contains(deployedunitid)) { ActiveConstructors.Remove(deployedunitid); } Ownership.GetInstance().SignalConstructorIsIdle(deployedunitid); double highestpriority = 0; List <Order> bestorders = new List <Order>(); foreach (Order order in orders) { double thispriority = order.priority; if (thispriority >= highestpriority) { int currentunits = order.unitsunderconstruction.Count; if (UnitController.GetInstance().UnitDefsByName.ContainsKey(order.unitname)) { currentunits += UnitController.GetInstance().UnitDefsByName[order.unitname].Count; } if (currentunits < order.quantity) { if (BuildTree.GetInstance().CanBuild(unitdef.name.ToLower(), order.unitname)) { //if( CanBuild(deployedunitid, if (thispriority > highestpriority) { highestpriority = thispriority; bestorders = new List <Order>(); bestorders.Add(order); csai.DebugSay("Possible order: " + order.ToString()); } else if (thispriority == highestpriority) { bestorders.Add(order); csai.DebugSay("Possible order: " + order.ToString()); } } } } } //if (bestorders.Count == 0) // { // csai.DebugSay("No orders found"); // return; // } List <Order> possibleorders = new List <Order>(); // get orders this unit can build bool metalneeded = false; bool energyneeded = false; IUnitDef deftobuild = null; foreach (Order order in bestorders) { csai.DebugSay("bestorder " + order.unitname); //if( BuildTree.GetInstance().CanBuild( unitdef.name.ToLower(), order.unitname ) ) //{ deftobuild = BuildTable.GetInstance().UnitDefByName[order.unitname]; if (MetalController.GetInstance().CanBuild(deftobuild)) { if (EnergyController.GetInstance().CanBuild(deftobuild)) { possibleorders.Add(order); csai.DebugSay("possible: " + order.unitname); } else { csai.DebugSay("needs energy"); energyneeded = true; } } else { csai.DebugSay("needs metal"); metalneeded = true; } //} } if (possibleorders.Count == 0) { if (Level1ConstructorList.GetInstance().defbyid.Count < 1 && !UnitController.GetInstance().UnitDefsByName.ContainsKey("armcom")) { if (BuildConstructionVehicle(deployedunitid, unitdef)) { return; } } if (energyneeded || aicallback.GetEnergy() < aicallback.GetEnergyStorage() / 5) { if (BuildSolarCell(deployedunitid)) { logfile.WriteLine("building solarcell"); if (AssistingConstructors.ContainsKey(deployedunitid)) { AssistingConstructors.Remove(deployedunitid); } return; } } if (metalneeded || aicallback.GetMetal() < aicallback.GetMetalStorage() / 5) { Float3 reclaimpos = ReclaimHelper.GetNearestReclaim(aicallback.GetUnitPos(deployedunitid), deployedunitid); if (reclaimpos != null) { GiveOrderWrapper.GetInstance().Reclaim(deployedunitid, reclaimpos, 100); return; } if (BuildMex(deployedunitid)) { logfile.WriteLine("building mex"); if (AssistingConstructors.ContainsKey(deployedunitid)) { AssistingConstructors.Remove(deployedunitid); } return; } } logfile.WriteLine("offering assistance"); OfferAssistance(deployedunitid); return; } Order ordertodo = possibleorders[random.Next(0, possibleorders.Count)]; if (ordertodo.unitname == "armmex") { BuildMex(deployedunitid); if (AssistingConstructors.ContainsKey(deployedunitid)) { AssistingConstructors.Remove(deployedunitid); } } else { //ordertodo.unitsunderconstruction += 1; deftobuild = BuildTable.GetInstance().UnitDefByName[ordertodo.unitname]; Float3 pos = BuildUnit(deployedunitid, ordertodo.unitname); Ownership.IOrder ownershiporder = Ownership.GetInstance().RegisterBuildingOrder(this, deployedunitid, deftobuild, pos); logfile.WriteLine("building: " + ordertodo.unitname); ordertodo.unitsunderconstruction.Add(ownershiporder); if (AssistingConstructors.ContainsKey(deployedunitid)) { AssistingConstructors.Remove(deployedunitid); } } }
bool activated = false; // not started until Activate or SetTarget is called // does NOT imply Activate() public void SetTarget(Float3 newtarget) { this.targetpos = newtarget; //Activate(); }
// this is going to have to interact with all sorts of stuff in the future // for now keep it simple // for now we look for nearby buildings, then nearby enemy units with low speed, then anything public Float3 ChooseAttackPoint( Float3 ourpos ) { bool gotbuilding = false; bool gotknownunit = false; double BestSquaredDistance = 100000000000; int bestid = 0; IUnitDef defforbestid = null; Float3 posforbestid = null; // logfile.WriteLine( "EnemySelector: checking mobile... " ); foreach( DictionaryEntry de in enemycontroller.EnemyUnitDefByDeployedId ) { int thisenemyid = (int)de.Key; IUnitDef unitdef = de.Value as IUnitDef; Float3 enemypos = aicallback.GetUnitPos( thisenemyid ); // logfile.WriteLine( "Found building " + double thissquareddistance = Float3Helper.GetSquaredDistance( ourpos, enemypos ); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if( unitdef != null ) { // logfile.WriteLine( "unitdef not null " + unitdef.humanName + " ismobile: " + unitdefhelp.IsMobile( unitdef ).ToString() ); // logfile.WriteLine( "gotbuilding = " + gotbuilding.ToString() ); if( gotbuilding ) { if( !unitdefhelp.IsMobile( unitdef ) ) { if( thissquareddistance < BestSquaredDistance ) { // logfile.WriteLine( "best building so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } else { if( unitdef.speed < maxenemyspeed ) // if we already have building we dont care { if( thissquareddistance < BestSquaredDistance ) { // logfile.WriteLine( "best known so far" ); bestid = thisenemyid; gotknownunit = true; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } else // if unitdef unknown { // logfile.WriteLine( "gotknownunit = " + gotknownunit.ToString() ); if( !gotknownunit ) // otherwise just ignore unknown units { if( thissquareddistance < BestSquaredDistance ) { // logfile.WriteLine( "best unknown so far" ); bestid = thisenemyid; posforbestid = enemypos; defforbestid = unitdef; BestSquaredDistance = thissquareddistance; } } } } foreach( DictionaryEntry de in enemycontroller.EnemyStaticPosByDeployedId ) { // logfile.WriteLine( "EnemySelector: checking static... " ); int thisenemyid = (int)de.Key; Float3 enemypos = de.Value as Float3; double thissquareddistance = Float3Helper.GetSquaredDistance( ourpos, enemypos ); // logfile.WriteLine( "EnemySelector: Potential enemy at " + enemypos.ToString() + " squareddistance: " + thissquareddistance ); if( thissquareddistance < BestSquaredDistance ) { // logfile.WriteLine( "EnemySelector: best distance so far" ); bestid = thisenemyid; gotbuilding = true; gotknownunit = true; posforbestid = enemypos; //defforbestid = unitdef; } } //if( enemycontroller.EnemyStaticPosByDeployedId.Contains( bestid ) ) // { // enemycontroller.EnemyStaticPosByDeployedId.Remove( bestid ); // } return posforbestid; }
public BuildCommand(int builder, int idtobuild, Float3 pos) { this.UnitToReceiveOrder = builder; this.idtobuild = idtobuild; this.pos = pos; }
void ExploreWith(int unitid) { Float3 destination = GetRandomDestination(); aicallback.GiveOrder(unitid, new Command(Command.CMD_MOVE, destination.ToDoubleArray())); }
public Radar(Float3 pos, double radius, IUnitDef unitdef) { this.Pos = pos; this.radius = radius; this.unitdef = unitdef; }
//called when an enemy inside los or radar is damaged public void EnemyDamaged(int damaged,int attacker,float damage, Float3 dir) { }
public AdvancedFloat3(Float3 float3) : base(float3) { }
public static double GetSquaredDistance(Float3 one, Float3 two) { return((two.x - one.x) * (two.x - one.x) + (two.y - one.y) * (two.y - one.y) + (two.z - one.z) * (two.z - one.z)); }
public Float3 GetNearestMetalSpot( Float3 mypos ) { if( !isMetalMap ) { double closestdistancesquared = 1000000000000; Float3 bestpos = null; MetalSpot bestspot = null; foreach( MetalSpot metalspot in MetalSpots ) { if( !MetalSpotsUsed.Contains( metalspot ) ) { if( bestpos == null ) { bestpos = metalspot.Pos; } double thisdistancesquared = Float3Helper.GetSquaredDistance( mypos, metalspot.Pos ); //logfile.WriteLine( "thisdistancesquared = " + thisdistancesquared + " closestdistancesquared= " + closestdistancesquared ); if( thisdistancesquared < closestdistancesquared ) { closestdistancesquared = thisdistancesquared; bestpos = metalspot.Pos; bestspot = metalspot; } } } return bestspot.Pos; } else { return mypos; // if metal map just return passed-in pos } }
public static void WriteXmlElementToFloat3(XmlElement element, Float3 float3) { float3.x = Convert.ToDouble(element.GetAttribute("x")); float3.y = Convert.ToDouble(element.GetAttribute("y")); float3.z = Convert.ToDouble(element.GetAttribute("z")); }
public MetalSpot( int amount, Float3 pos ) { Amount = amount; Pos = pos; }
// does NOT imply Activate() public void SetTarget( Float3 newtarget ) { this.targetpos = newtarget; //Activate(); }
public MetalSpot( int amount, Float3 pos, bool isoccupied ) { Amount = amount; IsOccupied = isoccupied; Pos = pos; }
void MoveTo( Float3 pos ) { // check whether we really need to do anything or if order is roughly same as last one aicallback.DrawUnit("ARMSOLAR", pos, 0.0f, 50, aicallback.GetMyAllyTeam(), true, true); if( restartedfrompause || Float3Helper.GetSquaredDistance( pos, lasttargetpos ) > ( movetothreshold * movetothreshold ) ) { aicallback.GiveGroupOrder( groupid, new Command( Command.CMD_MOVE, pos.ToDoubleArray() ) ); /* foreach( DictionaryEntry de in UnitDefListByDeployedId ) { int deployedid = (int)de.Key; IUnitDef unitdef = de.Value as IUnitDef; aicallback.GiveOrder( deployedid, new Command( Command.CMD_MOVE, pos.ToDoubleArray() ) ); } */ restartedfrompause = false; lasttargetpos = pos; } }
// loads cache file // returns true if cache loaded ok, otherwise false if not found, out-of-date, etc // we check the version and return false if out-of-date bool LoadCache() { string MapName = aicallback.GetMapName(); string cachefilepath = Path.Combine( csai.CacheDirectoryPath, MapName + "_metal.xml" ); if( !File.Exists( cachefilepath ) ) { logfile.WriteLine( "cache file doesnt exist -> building" ); return false; } XmlDocument cachedom = XmlHelper.OpenDom( cachefilepath ); XmlElement metadata = cachedom.SelectSingleNode( "/root/metadata" ) as XmlElement; string cachemetalclassversion = metadata.GetAttribute( "version" ); if( cachemetalclassversion != MetalClassVersion ) { logfile.WriteLine( "cache file out of date ( " + cachemetalclassversion + " vs " + MetalClassVersion + " ) -> rebuilding" ); return false; } logfile.WriteLine( cachedom.InnerXml ); isMetalMap = Convert.ToBoolean( metadata.GetAttribute( "ismetalmap" ) ); if( isMetalMap ) { logfile.WriteLine( "metal map" ); return true; } XmlElement metalspots = cachedom.SelectSingleNode( "/root/metalspots" ) as XmlElement; ArrayList metalspotsal = new ArrayList(); foreach( XmlElement metalspot in metalspots.SelectNodes( "metalspot" ) ) { int amount = Convert.ToInt32( metalspot.GetAttribute("amount") ); Float3 pos = new Float3(); Float3Helper.WriteXmlElementToFloat3( metalspot, pos ); //pos.LoadCsv( metalspot.GetAttribute("pos") ); MetalSpot newmetalspot = new MetalSpot( amount, pos ); metalspotsal.Add( newmetalspot ); // logfile.WriteLine( "metalspot xml: " + metalspot.InnerXml ); logfile.WriteLine( "metalspot: " + newmetalspot.ToString() ); } MetalSpots = (MetalSpot[])metalspotsal.ToArray( typeof( MetalSpot ) ); logfile.WriteLine( "cache file loaded" ); return true; }
public UnitInfo( int deployedid, Float3 pos, IUnitDef unitdef, double squareddistance ) { this.deployedid = deployedid; this.pos = pos; this.unitdef = unitdef; this.squareddistance = squareddistance; }
// 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() <<<"); }