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); }
void Recoordinate() { if (!started) { return; } // first we scan the list to find the 5 closest units to target, in order // next we measure distance of first unit from 5th // if distance is less than MaxPackDiameter, we move in // otherwise 5th unit holds, and we move units to position of 5th unit // pack must have at least 5 units, otherwise we call AttackPackDead event if (!CheckIfPackAlive()) { return; } UnitInfo[] closestunits = GetClosestUnits(UnitDefListByDeployedId, targetpos, 5); Float3 packheadpos = closestunits[0].pos; Float3 packtailpos = closestunits[MinPackSize - 1].pos; double packsquareddiameter = Float3Helper.GetSquaredDistance(packheadpos, packtailpos); // logfile.WriteLine( "AttackPackCoordinator packheadpos " + packheadpos.ToString() + " packtailpos " + packtailpos.ToString() + " packsquareddiamter " + packsquareddiameter ); if (packsquareddiameter < (MaxPackDiameter * MaxPackDiameter)) { Attack(); } else { Regroup(closestunits[(MinPackSize / 2)].pos); } }
public void Tick() { itickcount++; double squaredvisibilitydistance = 40 * 40; if (itickcount > 30) { itickcount = 0; //logfile.WriteLine("EnemyController running static enemy clean" ); foreach (DictionaryEntry de in unitcontroller.UnitDefByDeployedId) { int unitid = (int)de.Key; Float3 thispos = aicallback.GetUnitPos(unitid); IntArrayList enemiestoclean = new IntArrayList(); foreach (DictionaryEntry enemyde in EnemyStaticPosByDeployedId) { int enemyid = (int)enemyde.Key; Float3 pos = enemyde.Value as Float3; if (Float3Helper.GetSquaredDistance(pos, thispos) < squaredvisibilitydistance) { enemiestoclean.Add(enemyid); } } foreach (int enemyidtoclean in enemiestoclean) { EnemyStaticPosByDeployedId.Remove(enemyidtoclean); } } if (autoshowenemies) { ShowEnemies(); } } }
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 } }
// 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()); } } } //} }
bool DoReclaim(int constructorid) { if (totalticks == 0) // check ticks first, beacuse metal shows as zero at start { return(false); } IUnitDef unitdef = UnitDefByUnitId[constructorid] as IUnitDef; 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.DebugOn) { aicallback.DrawUnit("ARMMEX", reclaimpos, 0.0f, 200, aicallback.GetMyAllyTeam(), true, true); } 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(reclaimfound); }
public bool NeedRadarAt(Float3 pos) { // scan through all radars and check if we are within two thirds of its range or not. If yes we return false (not need radar) // if not , we return true (need radar) foreach (DictionaryEntry de in Radars) { Radar radar = de.Value as Radar; if (Float3Helper.GetSquaredDistance(radar.Pos, pos) < (radar.radius * radar.radius * 4 / 9)) { return(false); } } return(true); }
void csai_UnitCreatedEvent(int deployedunitid, IUnitDef unitdef) { foreach (Order order in orders) { if (order.orderedunit.id == unitdef.id) { Float3 createdunitpos = aicallback.GetUnitPos(deployedunitid); if (Float3Helper.GetSquaredDistance(createdunitpos, order.pos) < maxdistanceconsideredsame * maxdistanceconsideredsame) { order.unitdeployedid = deployedunitid; order.factorycontroller.UnitCreated(order, deployedunitid); } } } }
public void Tick() { itickcount++; double squaredvisibilitydistance = 40 * 40; if (itickcount > 30) { itickcount = 0; /* * foreach (KeyValuePair<int, Float3> kvp in EnemyStaticPosByDeployedId) * { * int enemyid = kvp.Key; * Float3 pos = kvp.Value; * if (aicallback.GetCurrentFrame() - LosMap.GetInstance().LastSeenFrameCount[pos.x / 16, pos.z / 16] < 30) * { * * } * } */ //logfile.WriteLine("EnemyController running static enemy clean" ); foreach (KeyValuePair <int, IUnitDef> keyvaluepair in unitcontroller.UnitDefByDeployedId) { int unitid = keyvaluepair.Key; IUnitDef thisfriendlyunitdef = keyvaluepair.Value; Float3 thispos = aicallback.GetUnitPos(unitid); IntArrayList enemiestoclean = new IntArrayList(); foreach (KeyValuePair <int, Float3> kvp in EnemyStaticPosByDeployedId) { int enemyid = kvp.Key; Float3 pos = kvp.Value; if (Float3Helper.GetSquaredDistance(pos, thispos) < thisfriendlyunitdef.losRadius * thisfriendlyunitdef.losRadius * 16 * 16) { enemiestoclean.Add(enemyid); } } foreach (int enemyidtoclean in enemiestoclean) { EnemyStaticPosByDeployedId.Remove(enemyidtoclean); } } if (csai.DebugOn) { ShowEnemies(); } } }
void Recoordinate() { if (!activated) { return; } if (restartedfrompause || Float3Helper.GetSquaredDistance(targetpos, lasttargetpos) > (20 * 20)) { foreach (int deployedid in UnitDefListByDeployedId.Keys) { //int deployedid = (int)de.Key; //IUnitDef unitdef = de.Value as IUnitDef; Move(deployedid); } lasttargetpos = targetpos; } }
void MoveTo(Float3 pos) { // check whether we really need to do anything or if order is roughly same as last one if (csai.DebugOn) { aicallback.DrawUnit("ARMSOLAR", pos, 0.0f, 50, aicallback.GetMyAllyTeam(), true, true); } if (restartedfrompause || Float3Helper.GetSquaredDistance(pos, lasttargetpos) > (movetothreshold * movetothreshold)) { 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; } }
void DoIncrementalRefreshes() { // logfile.WriteLine( "LosMap start incrementalrefreshes" ); int numupdates = 0; int thresholddistancesquared = distancethresholdforunitupdate * distancethresholdforunitupdate; foreach (object mobileidobject in friendlyunitpositionobserver.MobileUnitIds) { int id = (int)mobileidobject; Float3 currentpos = friendlyunitpositionobserver.PosById[id] as Float3; Float3 lastpos = PosAtLastRefreshByUnitId[id] as Float3; double distancesquared = Float3Helper.GetSquaredDistance(lastpos, currentpos); if (distancesquared > thresholddistancesquared) { UpdateLosForUnit(id, unitcontroller.UnitDefByDeployedId[id] as IUnitDef); numupdates++; } } // logfile.WriteLine( "LosMap end incrementalrefreshes, " + numupdates + " units refreshed" ); }
void Recoordinate() { if (!started) { return; } // first we scan the list to find the 5 closest units to target, in order // next we measure distance of first unit from 5th // if distance is less than MaxPackDiameter, we move in // otherwise 5th unit holds, and we move units to position of 5th unit // pack must have at least 5 units, otherwise we call AttackPackDead event if (!CheckIfPackAlive()) { return; } int packsize = Math.Min(MaxPackToConsider, UnitDefListByDeployedId.Count); UnitInfo[] closestunits = GetClosestUnits(UnitDefListByDeployedId, targetpos, packsize); Float3 packheadpos = closestunits[0].pos; Float3 packtailpos = closestunits[packsize - 1].pos; double packsquareddiameter = Float3Helper.GetSquaredDistance(packheadpos, packtailpos); csai.DebugSay("packsize: " + packsize + " packdiameter: " + Math.Sqrt(packsquareddiameter)); // logfile.WriteLine( "AttackPackCoordinator packheadpos " + packheadpos.ToString() + " packtailpos " + packtailpos.ToString() + " packsquareddiamter " + packsquareddiameter ); if ((regrouping && (packsquareddiameter < (MaxPackDiameterInnerThreshold * MaxPackDiameterInnerThreshold))) || (!regrouping && (packsquareddiameter < (MaxPackDiameterOuterThreshold * MaxPackDiameterOuterThreshold)))) { regrouping = false; csai.DebugSay("attacking"); Attack(closestunits); } else { csai.DebugSay("regrouping"); regrouping = true; Regroup(closestunits[(packsize / 2)].pos); } }
public void UnitAdded(int deployedid, IUnitDef unitdef) { if (!isMetalMap) { if (!Extractors.Contains(deployedid) && unitdefhelp.IsMex(unitdef)) { Float3 mexpos = aicallback.GetUnitPos(deployedid); logfile.WriteLine("Metal.UnitAdded, pos " + mexpos.ToString()); Extractors.Add(deployedid, mexpos); double squareextractorradius = ExtractorRadius * ExtractorRadius; foreach (MetalSpot metalspot in MetalSpots) { double thisdistancesquared = Float3Helper.GetSquaredDistance(metalspot.Pos, mexpos); // logfile.WriteLine( "squareextractorradius: " + squareextractorradius + " thisdistancesquared: " + thisdistancesquared ); if (thisdistancesquared <= squareextractorradius) { MetalSpotsUsed.Add(metalspot); logfile.WriteLine("Marking metal spot used: " + metalspot.Pos.ToString()); } } } } }
void OfferAssistance(int constructorid) { int bestconstructor = 0; double bestsquareddistance = 1000000000; Float3 ourpos = aicallback.GetUnitPos(constructorid); foreach (int activeconstructor in ActiveConstructors) { Float3 constructorpos = aicallback.GetUnitPos(activeconstructor); if (constructorpos != null) { double thissquareddistance = Float3Helper.GetSquaredDistance(ourpos, constructorpos); if (thissquareddistance < bestsquareddistance) { bestconstructor = activeconstructor; bestsquareddistance = thissquareddistance; } } } if (bestconstructor != 0) { logfile.WriteLine("unit to assist should be " + bestconstructor); if (!AssistingConstructors.ContainsKey(constructorid)) { logfile.WriteLine("assisting " + bestconstructor); GiveOrderWrapper.GetInstance().Guard(constructorid, bestconstructor); AssistingConstructors.Add(constructorid, bestconstructor); } else if (AssistingConstructors[constructorid] != bestconstructor) { logfile.WriteLine("assisting " + bestconstructor); GiveOrderWrapper.GetInstance().Guard(constructorid, bestconstructor); AssistingConstructors[constructorid] = bestconstructor; } } }
public void UnitRemoved(int deployedid) { if (!isMetalMap) { if (Extractors.Contains(deployedid)) { Float3 mexpos = Extractors[deployedid] as Float3; logfile.WriteLine("Metal.UnitRemoved, pos " + mexpos.ToString()); double squareextractorradius = ExtractorRadius * ExtractorRadius; foreach (MetalSpot metalspot in MetalSpots) { if (Float3Helper.GetSquaredDistance(metalspot.Pos, mexpos) < squareextractorradius) { if (MetalSpotsUsed.Contains(metalspot)) { logfile.WriteLine("Marking metal spot free: " + metalspot.Pos.ToString()); MetalSpotsUsed.Remove(metalspot); } } } Extractors.Remove(deployedid); } } }
// 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 (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 (MovementMaps.GetInstance().GetArea(typicalunitdef, enemypos) == startarea) { if (Float3Helper.GetSquaredDistance(new Float3(0, 0, 0), enemypos) > 1) { 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 (KeyValuePair <int, Float3> kvp in enemycontroller.EnemyStaticPosByDeployedId) { // logfile.WriteLine( "EnemySelector: checking static... " ); int thisenemyid = kvp.Key; Float3 enemypos = kvp.Value; 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 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<<<"); }
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); } } } }