Esempio n. 1
0
        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());
            }
        }
Esempio n. 2
0
        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());
        }
Esempio n. 3
0
        public int GetSweepingScoutCount(IclusterIGCWrapper cluster)
        {
            int sweepingScoutCount;

            if (SweepingScoutCountByClusterObjectID.TryGetValue(cluster.GetObjectID(), out sweepingScoutCount) == true)
            {
                return(sweepingScoutCount);
            }

            return(0);
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        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));
            }
        }
Esempio n. 6
0
        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()]);
            }
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
 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);
         }
     }
 }
Esempio n. 9
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());
        }
Esempio n. 10
0
        //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;
            }
        }
Esempio n. 11
0
        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();
        }
Esempio n. 12
0
        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();
        }
Esempio n. 13
0
 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());
 }
Esempio n. 14
0
        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()}");
            //    }
            //}
        }
Esempio n. 15
0
        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);
            //}
        }
Esempio n. 16
0
 public int GetDistance(IclusterIGCWrapper fromCluster, IclusterIGCWrapper toCluster)
 {
     return(GetDistance(fromCluster.GetObjectID(), toCluster.GetObjectID()));
 }