private bool ClusterContainsStation(StationType stationType, IclusterIGCWrapper currentCluster) { switch (stationType) { // If the tech rock is gone, then we'll consider this cluster to have this station in it case StationType.Expansion: case StationType.Supremacy: case StationType.Tactical: return(GetClusterTechRock(currentCluster) == null); case StationType.Garrison: return(currentCluster.GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID() && (p.GetName().Contains("Garrison") == true || p.GetName().Contains("Starbase") == true))); case StationType.ShipYard: return(currentCluster.GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID() && (p.GetName().Contains("Ship") == true || p.GetName().Contains("Dry") == true))); case StationType.Outpost: return(currentCluster.GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID() && (p.GetName().Contains("Outpost") == true || p.GetName().Contains("Garrison") == true || p.GetName().Contains("Starbase") == true))); case StationType.Refinery: return(currentCluster.GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID() && (p.GetName().Contains("Refinery") == true || p.GetName().Contains("Special") == true || p.GetName().Contains("Outpost") == true || p.GetName().Contains("Garrison") == true || p.GetName().Contains("Starbase") == true))); case StationType.Teleport: return(currentCluster.GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID() && p.GetName().Contains("Teleport") == true)); default: throw new NotSupportedException(stationType.ToString()); } }
private IasteroidIGCWrapper GetAsteroidClosestToClusterCenter(IclusterIGCWrapper cluster) { VectorWrapper centerPoint = new VectorWrapper(0, 0, 0); return(cluster.GetAsteroids() .Where(p => p.GetName().StartsWith("a") == true) .OrderBy(p => (centerPoint - p.GetPosition()).LengthSquared()) .FirstOrDefault()); }
public int GetSweepingScoutCount(IclusterIGCWrapper cluster) { int sweepingScoutCount; if (SweepingScoutCountByClusterObjectID.TryGetValue(cluster.GetObjectID(), out sweepingScoutCount) == true) { return(sweepingScoutCount); } return(0); }
public IclusterIGCWrapper NextCluster(IclusterIGCWrapper fromCluster, IclusterIGCWrapper toCluster) { int?nextClusterObjectID = NextClusterObjectID(fromCluster.GetObjectID(), toCluster.GetObjectID()); if (nextClusterObjectID != null) { return(fromCluster.GetMission().GetCluster((short)nextClusterObjectID)); } return(null); }
private IasteroidIGCWrapper GetStationBuildRock(StationType stationType, IclusterIGCWrapper cluster) { switch (stationType) { case StationType.Expansion: case StationType.Supremacy: case StationType.Tactical: return(GetClusterTechRock(cluster)); default: return(GetAsteroidClosestToClusterCenter(cluster)); } }
public int IncrementSweepingScoutCount(IclusterIGCWrapper cluster) { lock (SweepingScoutCountByClusterObjectID) { int sweepingScoutCount; if (SweepingScoutCountByClusterObjectID.TryGetValue(cluster.GetObjectID(), out sweepingScoutCount) == true) { SweepingScoutCountByClusterObjectID[cluster.GetObjectID()]++; } else { SweepingScoutCountByClusterObjectID.Add(cluster.GetObjectID(), 1); } return(SweepingScoutCountByClusterObjectID[cluster.GetObjectID()]); } }
private IclusterIGCWrapper FindNearestUnexploredCluster() { IclusterIGCWrapper nearestCluster = null; int nearestClusterDistance = int.MaxValue; foreach (var unexploredClusterObjectID in GameInfo.UnexploredClustersByObjectID.Keys) { var fromCluster = _client.GetShip().GetCluster(); var toCluster = _client.GetCore().GetCluster((short)unexploredClusterObjectID); DijkstraPathFinder pathFinder = new DijkstraPathFinder(_client.GetCore(), fromCluster, toCluster); int distance = pathFinder.GetDistance(fromCluster, toCluster); if (distance < nearestClusterDistance) { nearestCluster = toCluster; } } return(nearestCluster); }
public void DecrementSweepingScoutCount(IclusterIGCWrapper cluster) { lock (SweepingScoutCountByClusterObjectID) { int sweepingScoutCount; if (SweepingScoutCountByClusterObjectID.TryGetValue(cluster.GetObjectID(), out sweepingScoutCount) == true) { if (sweepingScoutCount <= 1) { SweepingScoutCountByClusterObjectID[cluster.GetObjectID()] = 0; } else { SweepingScoutCountByClusterObjectID[cluster.GetObjectID()]--; } } else { SweepingScoutCountByClusterObjectID.Add(cluster.GetObjectID(), 0); } } }
public DijkstraPathFinder(ImissionIGCWrapper mission, IclusterIGCWrapper fromCluster, IclusterIGCWrapper toCluster) { List <ClusterInfo> clusterInfos = new List <ClusterInfo>(); foreach (var cluster in mission.GetClusters()) { clusterInfos.Add(new ClusterInfo(cluster.GetObjectID(), cluster.GetHomeSector())); } foreach (var fromClusterInfo in clusterInfos) { foreach (var warp in mission.GetCluster(fromClusterInfo.GetObjectID()).GetWarps()) { var toClusterInfo = clusterInfos.Where(p => p.GetObjectID() == warp.GetDestination().GetCluster().GetObjectID()).FirstOrDefault(); if (toClusterInfo != null) { fromClusterInfo.GetWarps().Add(new WarpInfo(fromClusterInfo, toClusterInfo)); } } } BuildPath(clusterInfos, fromCluster.GetObjectID(), toCluster.GetObjectID()); }
//private void NavigateToNextSweepPoint() //{ // var ship = _client.GetShip(); // double nextSliceWidth = (Math.PI * 2 / 16); // double nextSlice = nextSliceWidth; // if (_sweepLeft == true) // { // nextSlice = _currentAngleInRadians + nextSliceWidth; // if (nextSlice > Math.PI * 2) // nextSlice -= Math.PI * 2; // } // else // { // nextSlice = _currentAngleInRadians - nextSliceWidth; // if (nextSlice < 0) // nextSlice += Math.PI * 2; // } // // Don't travel the last slice. // if (_totalRadiansTraversed + nextSliceWidth >= Math.PI * 2) // SelectNextAelphTarget(); // _totalRadiansTraversed += nextSliceWidth; // var centerPoint = new VectorWrapper(0, 0, 0); // VectorWrapper nextPoint = new VectorWrapper((_startingPoint - centerPoint).Length() * (float) Math.Cos(nextSlice), (_startingPoint - centerPoint).Length() * (float) Math.Sin(nextSlice), 0); // var buoy = _client.CreateBuoy((sbyte)BuoyType.c_buoyWaypoint, nextPoint.X(), nextPoint.Y(), nextPoint.Z(), ship.GetCluster().GetObjectID(), true); // var command = ship.GetDefaultOrder(buoy); // ship.SetCommand((sbyte)CommandType.c_cmdCurrent, buoy, command); // ship.SetAutopilot(true); //} private void SelectNextAelphTarget() { Log("SelectNextAelphTarget()"); var ship = _client.GetShip(); var visibleWarps = ship.GetCluster().GetWarps(); var otherFriendlyScoutShips = ship.GetCluster().GetShips().Where(p => p.GetObjectID() != ship.GetObjectID() && p.GetBaseHullType().GetName().Contains("Scout") == true && p.GetSide().GetObjectID() == ship.GetSide().GetObjectID()); bool foundTargetWarp = false; foreach (var visibleWarp in visibleWarps.Where(p => GameInfo.UnexploredClustersByObjectID.ContainsKey(p.GetDestination().GetCluster().GetObjectID()) == true).OrderBy(p => _client.GetDistanceSquared(p, ship))) { if (GameInfo.UnexploredClustersByObjectID.ContainsKey(visibleWarp.GetDestination().GetCluster().GetObjectID()) == true) { Log($"Unexplored Warp found: {visibleWarp.GetName()}"); float myDistance = _client.GetDistanceSquared(ship, visibleWarp); bool isAnotherScoutCloser = false; foreach (var otherScoutShip in otherFriendlyScoutShips) { float otherScoutDistance = _client.GetDistanceSquared(otherScoutShip, visibleWarp); if (otherScoutDistance < myDistance) { Log($"Another scout: {otherScoutShip.GetName()} is already closer to: {visibleWarp.GetName()}, looking for another target."); isAnotherScoutCloser = true; break; } } // The cluster is on the unexplored list, and there's no other scout that is closer, let's go for it! if (isAnotherScoutCloser == false) { Log($"Found target warp, going to {visibleWarp.GetName()}"); foundTargetWarp = true; ship.SetCommand((sbyte)CommandType.c_cmdCurrent, visibleWarp, (sbyte)CommandID.c_cidGoto); ship.SetAutopilot(true); break; } } } if (foundTargetWarp == false) { Log($"No target warp found, selecting a visible warp at random."); // Pick a random warp that is unexplored. var unvisitedWarps = visibleWarps.Where(p => GameInfo.UnexploredClustersByObjectID.ContainsKey(p.GetDestination().GetCluster().GetObjectID()) == true).ToList(); if (unvisitedWarps.Count > 0) { var targetWarp = unvisitedWarps[_random.Next(0, unvisitedWarps.Count)]; Log($"Found unvisited random warp, going to: {targetWarp.GetName()}"); ship.SetCommand((sbyte)CommandType.c_cmdCurrent, targetWarp, (sbyte)CommandID.c_cidGoto); ship.SetAutopilot(true); foundTargetWarp = true; } } // Couldn't find any immediately linked clusters, so find the nearest unexplored cluster and go to it. if (foundTargetWarp == false) { IclusterIGCWrapper nearestCluster = FindNearestUnexploredCluster(); if (nearestCluster != null) { Log($"Found an unexplored cluster {nearestCluster.GetName()}, navigating to it."); var buoy = _client.CreateBuoy((sbyte)BuoyType.c_buoyWaypoint, 0, 0, 0, nearestCluster.GetObjectID(), true); var command = ship.GetDefaultOrder(buoy); ship.SetCommand((sbyte)CommandType.c_cmdCurrent, buoy, command); ship.SetAutopilot(true); _navigatingToCluster = nearestCluster; foundTargetWarp = true; } } // All the immediate warps have been visited or have other scouts closer, just pick one at random. if (foundTargetWarp == false) { var targetWarp = visibleWarps[_random.Next(0, visibleWarps.Count)]; Log($"Found visited random warp, going to: {targetWarp.GetName()}"); ship.SetCommand((sbyte)CommandType.c_cmdCurrent, targetWarp, (sbyte)CommandID.c_cidGoto); ship.SetAutopilot(true); foundTargetWarp = true; } }
private void MessageReceiver_FMD_S_SHIP_STATUS(ClientConnection client, AllegianceInterop.FMD_S_SHIP_STATUS message) { Log("MessageReceiver_FMD_S_SHIP_STATUS"); var ship = _client.GetShip(); string shipName = ship.GetName(); UpdateUnexploredWarpsList(); //if (_sweepLeft == true || _sweepRight == true) // NavigateToNextSweepPoint(); if (ship.GetCluster() == null || message.status.GetSectorID() == _currentSectorID || _isSweeping == true) { Log($"Skipping message: ship.GetCluster() = {ship.GetCluster().GetName()}, message.status.GetSectorID() = {message.status.GetSectorID()}, _currentSectorID = {_currentSectorID}, _isSweeping = {_isSweeping}"); return; } if (_navigatingToCluster != null) { if (_navigatingToCluster.GetObjectID() != ship.GetCluster().GetObjectID()) { if (GameInfo.UnexploredClustersByObjectID.ContainsKey(_navigatingToCluster.GetObjectID()) == true) { Log($"Entered cluster: {ship.GetCluster().GetName()}, continuing on route to {_navigatingToCluster.GetName()}"); return; } else { Log($"Arrived at cluster: {ship.GetCluster().GetName()}, but destination cluster {_navigatingToCluster.GetName()} has already been swept. Cancelling navigation, checking for next step."); _navigatingToCluster = null; } } else { Log($"Arrived at cluster: {ship.GetCluster().GetName()}, checking for next step."); _navigatingToCluster = null; } } _currentSectorID = message.status.GetSectorID(); //_sweepLeft = false; //_sweepRight = false; //_startingAngleInRadians = 0; //_currentAngleInRadians = 0; //_totalRadiansTraversed = 0; //_startingPoint = ship.GetPosition(); //_currentSweepHop = 0; var otherFriendlyScoutShips = ship.GetCluster().GetShips().Where(p => p.GetObjectID() != ship.GetObjectID() && p.GetBaseHullType().GetName().Contains("Scout") == true && p.GetSide().GetObjectID() == ship.GetSide().GetObjectID()); var otherSweepingScoutShips = otherFriendlyScoutShips.Where(p => p.GetCommandTarget((sbyte)CommandType.c_cmdCurrent)?.GetObjectType() == (short)ObjectType.OT_buoy); Log($"otherFriendlyScoutShips: {otherFriendlyScoutShips.Count()}, otherSweepingScoutShips: {otherSweepingScoutShips.Count()}, is unexplored: {GameInfo.UnexploredClustersByObjectID.ContainsKey(ship.GetCluster().GetObjectID())} "); // Ship has entered a cluster, find the next target and start scouting. // If cluster is unexplored, and less than 2 ships sweeping, start sweeping if (GameInfo.UnexploredClustersByObjectID.ContainsKey(ship.GetCluster().GetObjectID()) == true && otherSweepingScoutShips.Count() < 2) { SweepCluster(); } // If there are two ships sweeping, fly to a point 1/3 of the angle we entered in at, and wait for alephs to appear. else if (otherSweepingScoutShips.Count() >= 2) { FlyToStationPointAndWaitForAelphs(); } // If there are no ships sweeping, go to the next system. else { SelectNextAelphTarget(); } //var mission = ship.GetMission(); //var warps = mission.GetWarps(); //// Get all the clusters that are available in the mission. //var missionClusters = mission.GetClusters(); //var currentShipCluster = ship.GetCluster(); //var currentMissionCluster = missionClusters.FirstOrDefault(p => p.GetObjectID() == currentShipCluster.GetObjectID()); //var shipVisibleWarps = currentShipCluster.GetWarps(); //var allWarpsInCluster = currentMissionCluster.GetWarps(); }
private void MessageReceiver_FMD_S_SHIP_STATUS(ClientConnection client, AllegianceInterop.FMD_S_SHIP_STATUS message) { var ship = ClientConnection.GetShip(); var station = ship.GetStation(); // Ignore messages that are not for us. if (message.shipID != ship.GetObjectID()) { return; } // Ignore messages until we actually get into a sector if (ship.GetCluster() == null) { return; } Log($"MessageReceiver_FMD_S_SHIP_STATUS: my ship id = {ship.GetObjectID()}, message.shipID = {message.shipID}, message.status.GetSectorID(): {message.status.GetSectorID()}"); string shipName = ship.GetName(); //UpdateUnexploredWarpsList(); // If we are in a station, then get into a scout and get out there. if (station != null) { if (_waitingForLaunchToComplete == false) { Log("\tI'm sitting in base? Time to launch a scout!"); ChangeShip(ShipType.Scout, new ScoutProbeLoadout()); return; } } else { _waitingForLaunchToComplete = false; } if (IsCurrentShipAScout() == false) { Log("\tI'm not in a scout... returning to base."); ReturnToBase(); return; } // If we don't have any command and the ship is stopped, reset and get moving! if ((CommandID)ship.GetCommandID((sbyte)CommandType.c_cmdCurrent) <= CommandID.c_cidNone && ship.GetVelocity().Length() == 0) { Log($"\tWe're stopped with no command. Resetting current variables, and selecting a new destination. _currentSectorID: {_currentSectorID}, _isSweeping: {_isSweeping}, _navigatingToCluster: {_navigatingToCluster}, _waitingForLaunchToComplete: {_waitingForLaunchToComplete}"); _currentSectorID = -1; _isSweeping = false; _navigatingToCluster = null; _waitingForLaunchToComplete = false; //return; } // If we are already moving, and this status message is for our current sector, or we are already sweeping, then ignore it. if (ship.GetVelocity().Length() > 0 && (message.status.GetSectorID() == _currentSectorID || _isSweeping == true)) { Log($"\tSkipping message: ship.GetVelocity(): {ship.GetVelocity().Length()}, ship.GetCluster() = {ship.GetCluster()?.GetName()}, message.status.GetSectorID() = {message.status.GetSectorID()}, _currentSectorID = {_currentSectorID}, _isSweeping = {_isSweeping}"); return; } // These clusters still need to be explored. var currentUnexploredClusters = GameInfo.GetUnexploredClusters(client.GetCore()); // Are we on the way to another cluster to explore? if (_navigatingToCluster != null) { // If we are not at the destination yet... if (_navigatingToCluster.GetObjectID() != ship.GetCluster().GetObjectID()) { // And our destination cluster still hasn't been explored... if (currentUnexploredClusters.ContainsKey(_navigatingToCluster.GetObjectID()) == true) { Log($"\tEntered cluster: {ship.GetCluster().GetName()}, continuing on route to {_navigatingToCluster.GetName()}"); return; } else // The detination was explored by someone else, let's find a new destination. { Log($"\tArrived at cluster: {ship.GetCluster().GetName()}, but destination cluster {_navigatingToCluster.GetName()} has already been swept. Cancelling navigation, checking for next step."); _navigatingToCluster = null; } } else // We've arrived, let's see what we need to do next. { Log($"\tArrived at cluster: {ship.GetCluster().GetName()}, checking for next step."); _navigatingToCluster = null; } } _currentSectorID = message.status.GetSectorID(); var otherFriendlyScoutShips = ship.GetCluster().GetShips().Where(p => p.GetObjectID() != ship.GetObjectID() && p.GetBaseHullType().GetName().Contains("Scout") == true && p.GetSide().GetObjectID() == ship.GetSide().GetObjectID()); //var otherSweepingScoutShips = otherFriendlyScoutShips.Where(p => p.GetCommandTarget((sbyte)CommandType.c_cmdCurrent)?.GetObjectType() == (short)ObjectType.OT_buoy); var sweepingScoutCount = GameInfo.GetSweepingScoutCount(ship.GetCluster()); Log($"\totherFriendlyScoutShips: {otherFriendlyScoutShips.Count()}, otherSweepingScoutShips: {sweepingScoutCount}, is unexplored: {currentUnexploredClusters.ContainsKey(ship.GetCluster().GetObjectID())} "); // Ship has entered a cluster, find the next target and start scouting. // If cluster is unexplored, and less than 2 ships sweeping, start sweeping if (currentUnexploredClusters.ContainsKey(ship.GetCluster().GetObjectID()) == true && sweepingScoutCount < 2) { SweepCluster(); } // If there are two ships sweeping, fly to a point 1/3 of the angle we entered in at, and wait for alephs to appear. else if (sweepingScoutCount >= 2) { FlyToStationPointAndWaitForAelphs(); } // If there are no ships sweeping, go to the next system. else { SelectNextAelphTarget(); } //var mission = ship.GetMission(); //var warps = mission.GetWarps(); //// Get all the clusters that are available in the mission. //var missionClusters = mission.GetClusters(); //var currentShipCluster = ship.GetCluster(); //var currentMissionCluster = missionClusters.FirstOrDefault(p => p.GetObjectID() == currentShipCluster.GetObjectID()); //var shipVisibleWarps = currentShipCluster.GetWarps(); //var allWarpsInCluster = currentMissionCluster.GetWarps(); }
private IasteroidIGCWrapper GetClusterTechRock(IclusterIGCWrapper cluster) { return(cluster.GetAsteroids().Where(p => p.GetName().StartsWith("He") == false && p.GetName().StartsWith("a") == false && String.IsNullOrWhiteSpace(p.GetName()) == false).FirstOrDefault()); }
private IclusterIGCWrapper GetStationBuildCluster(StationType stationType) { var stations = ClientConnection.GetSide().GetStations(); var homeStation = stations.Where(p => p.GetCluster().GetHomeSector() == true).FirstOrDefault(); var homeCluster = homeStation.GetCluster(); var homeRock = homeCluster.GetAsteroids().Where(p => p.GetName().StartsWith("He") == false && p.GetName().StartsWith("a") == false && String.IsNullOrWhiteSpace(p.GetName()) == false).FirstOrDefault(); var enemyHomeCluster = ClientConnection.GetCore().GetClusters().Where(p => p.GetHomeSector() == true && p.GetObjectID() != homeCluster.GetObjectID()).FirstOrDefault(); // Always build a home tele first if we don't have one in our home cluster. if (stationType == StationType.Teleport && homeCluster.GetStations().Exists(p => p.GetName().Contains("Teleport") == true) == false && _constuctorsInFlightToClusterObjectIDByShipObjectID.Values.Count(r => r.Cluster.GetObjectID() == homeCluster.GetObjectID()) == 0) { Log($"There is no home teleporter yet, let's put this tele con at home: {homeCluster.GetName()}"); return(homeCluster); } // Try to find empty clusters where we have secured all sides. if (stationType == StationType.Refinery) { // For hihigher, this is the middle cluster. Log("Checking for an empty cluster that is bordered by our own stations."); var goodRefCluster = ClientConnection.GetCore().GetClusters() .Where(p => p.GetStations().Count == 0 && // Make sure there are no stations in it already. _constuctorsInFlightToClusterObjectIDByShipObjectID.Values.Count(r => r.Cluster.GetObjectID() == p.GetObjectID()) == 0 && // Are any other cons heading to this cluster? GameInfo.GetUnexploredClusters(p.GetMission()).ContainsKey(p.GetObjectID()) == false && // Is this cluster fully explored? p.GetWarps().All(r => r.GetDestination().GetCluster().GetStations().Count > 0 && // Neighboring clusters have at least one station r.GetDestination().GetCluster().GetStations().All(s => s.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID()))) // And all the stations belong to our side. .FirstOrDefault(); if (goodRefCluster != null) { Log($"Found a good cluster for a refinery: {goodRefCluster.GetName()}"); return(goodRefCluster); } else { Log($"No good refinery cluster found. Looking for a good spot on available lines."); } } //var availableClusters = GameInfo.Clusters.Where(p => p.GetHomeSector() == true || ClientConnection. var routeFinder = new DijkstraPathFinder(GameInfo.Clusters, homeCluster.GetObjectID(), enemyHomeCluster.GetObjectID()); var singleHopClusterDistances = homeCluster.GetWarps() .ToDictionary( p => p.GetDestination().GetCluster(), r => new DijkstraPathFinder(GameInfo.Clusters, r.GetDestination().GetCluster().GetObjectID(), enemyHomeCluster.GetObjectID()) .GetDistance(r.GetDestination().GetCluster(), enemyHomeCluster)); List <ClusterInfo> clustersNextToHome = GameInfo.Clusters.Where(p => p.GetWarps().Exists(r => r.GetDestinationCluster().GetObjectID() == homeCluster.GetObjectID()) == true).ToList(); // Walk each path until a station is found. while (clustersNextToHome.Count > 0) { var currentClusterObjectID = clustersNextToHome[_random.Next(0, clustersNextToHome.Count)]; clustersNextToHome.Remove(currentClusterObjectID); var pathFinder = new DijkstraPathFinder(GameInfo.Clusters, currentClusterObjectID.GetObjectID(), enemyHomeCluster.GetObjectID()); var currentCluster = ClientConnection.GetCore().GetCluster(currentClusterObjectID.GetObjectID()); Log($"Considering line for {currentCluster.GetName()}"); for (var nextClusterObjectID = (short)pathFinder.NextClusterObjectID(currentCluster.GetObjectID(), enemyHomeCluster.GetObjectID()); currentCluster.GetObjectID() != enemyHomeCluster.GetObjectID(); currentCluster = ClientConnection.GetCore().GetCluster(nextClusterObjectID), nextClusterObjectID = (short)pathFinder.NextClusterObjectID(nextClusterObjectID, enemyHomeCluster.GetObjectID()).GetValueOrDefault(-1)) { var nextCluster = ClientConnection.GetCore().GetCluster(nextClusterObjectID); Log($"Considering cluster: {currentCluster.GetName()}, nextCluster: {nextCluster.GetName()}"); // Don't select this cluster if another constructor is already on the way to it. if (_constuctorsInFlightToClusterObjectIDByShipObjectID.Values.Count(r => r.Cluster.GetObjectID() == currentCluster.GetObjectID()) > 0) //if (_constuctorsInFlightToClusterObjectIDByShipObjectID.ContainsValue(currentCluster.GetObjectID()) == true) { Log($"There is already a constructor heading to {currentCluster.GetName()}, skipping to next sector."); continue; } // If the station is a friendly station, then we can put a ref or tech base next to it. if (ClientConnection.GetCore().GetCluster(nextClusterObjectID).GetStations().Exists(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID()) == true) { Log($"Friendly station found in nextCluster: {nextCluster.GetName()}"); // We don't want to put an output behind another friendly station. See if we can get closer! if (stationType == StationType.Outpost) { Log("There is an outpost already in this line, so we don't want to put another one behind it."); continue; } // If this matches to our home tech rock, then let's drop it here. if (stationType == StationType.Teleport) { // If the sector already has a teleport, then see if we can get closer! if (ClusterContainsStation(StationType.Teleport, currentCluster) == true) { Log("There is already a teleport here, seeing if we can get closer."); continue; } // If the sector's tech rock matches the home rock, then put a tele in it. if (currentCluster.GetStations().Count == 0 && GetClusterTechRock(currentCluster).GetName()[0] == homeRock.GetName()[0]) { Log("There is a good tech rock here, let's a put a tele here too!"); return(currentCluster); } } // We have a covering station in front of this one, so this is a good sector use for mining or tech bases, but we want refs to be as close to home as possible. if (stationType == StationType.Refinery && ClusterContainsStation(StationType.Refinery, currentCluster) == false) { var homeSectorPath = new DijkstraPathFinder(ClientConnection.GetCore(), currentCluster, homeCluster); IclusterIGCWrapper refCluster = currentCluster; for (nextCluster = currentCluster; nextCluster != homeCluster && nextCluster != null; nextCluster = homeSectorPath.NextCluster(nextCluster, homeCluster)) { if (nextCluster.GetStations().Count(p => p.GetSide().GetObjectID() == ClientConnection.GetSide().GetObjectID()) > 0) { Log($"Found a refinery cluster that is on a line protected by another station, with a friendly station backing it: {refCluster.GetName()}"); return(refCluster); } refCluster = nextCluster; } //Log($"This is good spot for a refinery! Recommending: {currentCluster.GetName()}"); //return currentCluster; } if (stationType == StationType.Garrison && ClusterContainsStation(StationType.Garrison, currentCluster) == false) { Log($"This is good spot for a garrison! Recommending: {currentCluster.GetName()}"); return(currentCluster); } if (stationType == StationType.ShipYard && ClusterContainsStation(StationType.ShipYard, currentCluster) == false) { Log($"This is good spot for a ship yard! Recommending: {currentCluster.GetName()}"); return(currentCluster); } if (stationType == StationType.Supremacy && ClusterContainsStation(StationType.Supremacy, currentCluster) == false) { Log($"This is good spot for a supremacy! Recommending: {currentCluster.GetName()}"); return(currentCluster); } if (stationType == StationType.Expansion && ClusterContainsStation(StationType.Expansion, currentCluster) == false) { Log($"This is good spot for an expansion! Recommending: {currentCluster.GetName()}"); return(currentCluster); } if (stationType == StationType.Tactical && ClusterContainsStation(StationType.Tactical, currentCluster) == false) { Log($"This is good spot for a tactical! Recommending: {currentCluster.GetName()}"); return(currentCluster); } } // If the station is an enemy station, then we want to put a tele or outpost next to it. if (ClientConnection.GetCore().GetCluster(nextClusterObjectID).GetStations().Exists(p => p.GetSide().GetObjectID() != ClientConnection.GetSide().GetObjectID()) == true || (nextCluster.GetAsteroids().Count == 0 && ClientConnection.GetCore().GetCluster(nextClusterObjectID).GetHomeSector() == true)) // If we haven't actually eyed the enemy home, then we know their garrison is in there. { Log($"Next sector: {nextCluster.GetName()} has an enemy station in it."); // Always put outposts next to enemy stations. That's our favorite! if (stationType == StationType.Outpost && ClusterContainsStation(StationType.Outpost, currentCluster) == false) { Log($"Found a good cluster for this outpost: {currentCluster.GetName()}, next to an enemy sector."); return(currentCluster); } // If the target sector doesn't already have an outpost in it, then put a tele one sector back if possible to allow an outpost to come forward. if (stationType == StationType.Teleport && ClusterContainsStation(StationType.Outpost, currentCluster) == false) { var previousCluster = ClientConnection.GetCore().GetCluster((short)pathFinder.NextClusterObjectID(currentCluster.GetObjectID(), homeCluster.GetObjectID())); if (previousCluster.GetStations().Count == 0) { Log($"There is an open cluster in {previousCluster.GetName()}, let's send the tele to there!"); return(previousCluster); } } } } } if (stationType == StationType.Refinery) { Log($"No good cluster found for this refinery, waiting for a good option to appear."); return(null); } Log($"No targeted clusters were found, placing con in a random open cluster."); // No targeted clusters were found, let's go with any random empty cluster that we know about. var emptyClusters = ClientConnection.GetCore().GetClusters().Where(p => p.GetAsteroids().Count > 0 && p.GetStations().Count == 0 && _constuctorsInFlightToClusterObjectIDByShipObjectID.Values.Count(r => r.Cluster.GetObjectID() == p.GetObjectID()) == 0) .ToArray(); if (emptyClusters.Count() == 0) { return(null); } var targetCluster = emptyClusters[_random.Next(0, emptyClusters.Count())]; Log($"Selecting random cluster: {targetCluster.GetName()} as target."); return(targetCluster); //int minHops = singleHopClusterDistances.Select(p => p.Value).OrderBy(p => p).First(); //var bestClusterRoutesForOutposts = singleHopClusterDistances.Where(p => p.Value == minHops).ToDictionary(p => p.Key, r => r.Value); //foreach (var cluster in bestClusterRoutesForOutposts.Keys) //{ // Log($"Start: {cluster.GetName()}"); // routeFinder = new DijkstraPathFinder(GameInfo.Clusters, cluster.GetObjectID(), enemyHomeCluster.GetObjectID()); // for (var nextCluster = routeFinder.NextClusterObjectID(cluster.GetObjectID(), enemyHomeCluster.GetObjectID()); nextCluster != null; nextCluster = routeFinder.NextClusterObjectID(nextCluster.GetValueOrDefault(0), enemyHomeCluster.GetObjectID())) // { // Log($"\tNext: {ClientConnection.GetCore().GetCluster((short)nextCluster.GetValueOrDefault(0)).GetName()}"); // } //} }
private void PlaceStation(IshipIGCWrapper ship, short clusterID) { if (_constuctorsInFlightToClusterObjectIDByShipObjectID.ContainsKey(ship.GetObjectID()) == true) { return; } StationType stationType; if (ship.GetName().Contains("Outpost") == true) { stationType = StationType.Outpost; } else if (ship.GetName().Contains("Teleport") == true) { stationType = StationType.Teleport; } else if (ship.GetName().Contains("Refinery") == true) { stationType = StationType.Refinery; } else { throw new NotSupportedException($"No station type found for ship name: {ship.GetName()}"); } var targetCluster = GetStationBuildCluster(stationType); var shipCluster = ClientConnection.GetCore().GetCluster(clusterID); Log($"\tPlaceStation: {stationType.ToString()}, constructor: {ship.GetName()}, currentCluster: {shipCluster.GetName()}"); if (targetCluster == null) { Log("\t\tNo valid target cluster could be found, waiting for a cluster finish building to plot this station's destination."); return; } _constuctorsInFlightToClusterObjectIDByShipObjectID.Add(ship.GetObjectID(), new InflightConstructor() { Cluster = targetCluster, Ship = ship, StationType = stationType }); if (targetCluster != null) { Task.Run(() => { IclusterIGCWrapper intermediateCluster = null; while (targetCluster.GetAsteroids().Count == 0 && _cancellationTokenSource.IsCancellationRequested == false) { if (intermediateCluster == null || (shipCluster.GetObjectID() == intermediateCluster.GetObjectID())) //if (ship.GetCommandID((sbyte) CommandType.c_cmdCurrent) <= (sbyte) CommandID.c_cidNone) { Log($"Looking for intermediate cluster, target cluster: {targetCluster.GetName()} has not been discovered yet. Current ship command is: {((CommandID)ship.GetCommandID((sbyte)CommandType.c_cmdCurrent)).ToString()}"); var pathFinder = new DijkstraPathFinder(GameInfo.Clusters, targetCluster.GetObjectID(), GetHomeCluster().GetObjectID()); // Find a sector on the route that we have already explored, we will send the constructor there while we wait for scouts to find the way. for (intermediateCluster = targetCluster; intermediateCluster.GetAsteroids().Count == 0; intermediateCluster = pathFinder.NextCluster(intermediateCluster, GetHomeCluster())) { ; } if (intermediateCluster != null && shipCluster != null && shipCluster.GetObjectID() != intermediateCluster.GetObjectID()) { Log($"Found intermediate cluster: {intermediateCluster.GetName()}, sending con there."); // Send the con to the middle of the cluster, and wait for the way to be found. var buoy = ClientConnection.CreateBuoy((sbyte)BuoyType.c_buoyWaypoint, 0, 0, 0, intermediateCluster.GetObjectID(), true); var command = ship.GetDefaultOrder(buoy); ClientConnection.SendChat(ClientConnection.GetShip(), ChatTarget.CHAT_INDIVIDUAL, ship.GetObjectID(), 0, "", (sbyte)command, buoy.GetObjectType(), buoy.GetObjectID(), buoy, true); } } Thread.Sleep(250); } if (targetCluster.GetAsteroids().Count > 0) { var targetRock = GetStationBuildRock(stationType, targetCluster); Log($"Found target rock for con: {ship.GetName()}, sending con to: {targetCluster.GetName()}, {targetRock.GetName()}"); ClientConnection.SendChat(ClientConnection.GetShip(), ChatTarget.CHAT_INDIVIDUAL, ship.GetObjectID(), 0, "", (sbyte)CommandID.c_cidBuild, targetRock.GetObjectType(), targetRock.GetObjectID(), targetRock, true); } }); } //var foundClusters = ClientConnection.GetCore().GetClusters(); //var stations = ClientConnection.GetSide().GetStations(); //var homeStation = stations.Where(p => p.GetCluster().GetHomeSector() == true).FirstOrDefault(); //var homeCluster = homeStation.GetCluster(); //var asteroidNames = homeCluster.GetAsteroids().ToDictionary(r => r.GetObjectID(), p => p.GetName()); //Log("\t\tHome asteroids"); //foreach (var name in asteroidNames.Values) //{ // Log($"\t\t\t{name}"); //} //var homeRock = homeCluster.GetAsteroids().Where(p => p.GetName().StartsWith("He") == false && p.GetName().StartsWith("a") == false && String.IsNullOrWhiteSpace(p.GetName()) == false).FirstOrDefault(); //Log($"\t\thomeRock: {homeRock.GetName()}"); //var nextSectorTechRocks = homeCluster.GetWarps() // .Select(p => p.GetDestination().GetCluster()) // .Select(r => r.GetAsteroids()) // .Select(q => q.Where(s => s.GetName().StartsWith("He") == false && s.GetName().StartsWith("a") == false && String.IsNullOrWhiteSpace(s.GetName()) == false).FirstOrDefault()) // .Where(t => t != null && String.IsNullOrWhiteSpace(t.GetName()) == false); //foreach (var nextSectorTechRock in nextSectorTechRocks) // Log($"\t\tnextSectorTechRock: {nextSectorTechRock.GetName()}"); //var viableNextSectors = nextSectorTechRocks.Where(p => String.IsNullOrWhiteSpace(p.GetName()) == false && String.IsNullOrWhiteSpace(homeRock.GetName()) == false && p.GetName()[0] == homeRock.GetName()[0]); //foreach (var viableNextSectorItem in viableNextSectors) // Log($"\t\tviableNextSector: {viableNextSectorItem.GetName()}"); //var viableNextSector = viableNextSectors.FirstOrDefault(); //var targetNextSector = homeCluster.GetWarps().FirstOrDefault().GetDestination().GetCluster(); //if (viableNextSector != null) // targetNextSector = viableNextSector.GetCluster(); //Log($"targeting {targetNextSector.GetName()} for possible future tech base, will build outpost forward of this sector."); //// Find the next adjacent sector that does not lead back to the home sector! (We want a sector that is at least two hops away!) ////var targetBuildCluster = targetNextSector.GetWarps() //// .Where(p => //// p.GetDestination().GetCluster().GetObjectID() != homeCluster.GetObjectID() // Don't go back to the home sector! //// && p.GetDestination().GetCluster().GetWarps().Exists(r => r.GetDestination().GetCluster().GetObjectID() == homeCluster.GetObjectID()) == false) //// .FirstOrDefault() //// ?.GetCluster(); // Don't go to a sector that leads back to the home sector. //var targetBuildCluster = targetNextSector.GetWarps() // .OrderByDescending(p => new DijkstraPathFinder(GameInfo.Clusters, p.GetDestination().GetCluster().GetObjectID(), homeCluster.GetObjectID()).GetDistance(p.GetDestination().GetCluster().GetObjectID(), homeCluster.GetObjectID())) // .Select(p => p.GetDestination().GetCluster()) // .FirstOrDefault(); //// Find the next forward sector if it's been found yet. We are only interested a sector that is two hops from home base. ////foreach (var nextSectorWarp in targetNextSector.GetWarps()) ////{ //// var d = new DijkstraPathFinder(ClientConnection.GetCore(), nextSectorWarp.GetDestination().GetCluster(), homeCluster); ////} //bool foundTarget = false; //if (targetBuildCluster != null) //{ // Log($"\t\ttargeting {targetBuildCluster.GetName()} for outpost cluster."); // // find closest rock to the center // VectorWrapper centerPoint = new VectorWrapper(0, 0, 0); // var targetRock = targetBuildCluster.GetAsteroids() // .Where(p => p.GetName().StartsWith("a") == true) // .OrderBy(p => (centerPoint - p.GetPosition()).LengthSquared()) // .FirstOrDefault(); // if (targetRock != null) // { // Log($"\t\ttargeting {targetRock.GetName()} for outpost rock."); // ClientConnection.SendChat(ClientConnection.GetShip(), ChatTarget.CHAT_INDIVIDUAL, ship.GetObjectID(), 0, "", (sbyte)CommandID.c_cidBuild, targetRock.GetObjectType(), targetRock.GetObjectID(), targetRock, true); // //ship.SetCommand((sbyte)CommandType.c_cmdCurrent, targetRock, (sbyte)CommandID.c_cidBuild); // //ship.SetCommand((sbyte)CommandType.c_cmdAccepted, targetRock, (sbyte)CommandID.c_cidBuild); // foundTarget = true; // //ship.SetAutopilot(true); // } // else // { // Log($"Couldn't find a target rock in cluster: {targetBuildCluster.GetName()}"); // } //} //else //{ // Log($"Couldn't find a target cluster to build in."); //} //if (foundTarget == false) //{ // Log($"Couldn't find a target build rock, moving to sector: {targetNextSector.GetName()} while we wait for the rock to be found."); // var buoy = ClientConnection.CreateBuoy((sbyte)BuoyType.c_buoyWaypoint, 0, 0, 0, targetNextSector.GetObjectID(), true); // var command = ship.GetDefaultOrder(buoy); // ClientConnection.SendChat(ClientConnection.GetShip(), ChatTarget.CHAT_INDIVIDUAL, ship.GetObjectID(), 0, "", (sbyte)command, buoy.GetObjectType(), buoy.GetObjectID(), buoy, true); // //ship.SetCommand((sbyte)CommandType.c_cmdCurrent, buoy, command); // //ship.SetCommand((sbyte)CommandType.c_cmdAccepted, buoy, command); // //ship.SetCommand((sbyte)CommandType.c_cmdCurrent, targetNextSector, (sbyte)CommandID.c_cidGoto); // //ship.SetCommand((sbyte)CommandType.c_cmdAccepted, targetNextSector, (sbyte)CommandID.c_cidGoto); //} }
public int GetDistance(IclusterIGCWrapper fromCluster, IclusterIGCWrapper toCluster) { return(GetDistance(fromCluster.GetObjectID(), toCluster.GetObjectID())); }