void DeregisterBird(Hummingbird bird)
 {
     Hummingbirds.Remove(bird);
     BirdToEnemy.Remove(bird);
     ScannerSubsystem.RemoveScannerGroup(BirdScannerGroups[bird]);
     BirdScannerGroups.Remove(bird);
 }
        void RegisterBird(Hummingbird newBird)
        {
            Hummingbirds.Add(newBird);
            BirdToEnemy.Add(newBird, 0);

            var birdCamGroup = new ScannerGroup(newBird.Cameras);

            BirdScannerGroups[newBird] = birdCamGroup;
            ScannerSubsystem.AddScannerGroup(birdCamGroup);
        }
        public Hummingbird Release()
        {
            releaseStage = -10;
            var bird = Hummingbird;

            Hummingbird          = null;
            turretRotor          = null;
            hummingbirdConnector = null;
            GridTerminalHelper.OtherMergeBlock(ChasisMerge).Enabled = false;
            TurretMerge.Enabled = true;

            return(bird);
        }
Beispiel #4
0
        public static Hummingbird GetHummingbird(IMyTerminalBlock reference, IMyBlockGroup group)
        {
            if (group == null)
            {
                throw new Exception($"CANNOT FIND GROUP {GroupName}");
            }

            Hummingbird hummingbird = new Hummingbird();

            group.GetBlocksOfType <IMyTerminalBlock>(null, (x) => hummingbird.CollectParts(x, reference));
            if (hummingbird.TurretRotor != null)
            {
                group.GetBlocksOfType <IMyTerminalBlock>(null, (x) => hummingbird.CollectParts(x, hummingbird.TurretRotor.Top));
            }

            hummingbird.SetUp();

            return(hummingbird);
        }
        public void Update()
        {
            if (!setup)
            {
                setup           = true;
                Piston.Velocity = 0.2f;

                if (!Hummingbird.CheckHummingbirdComponents(ChasisMerge, ref hummingbirdConnector, ref turretRotor, ref PartScratchpad, ref status))
                {
                    return;
                }

                if (Hummingbird.CheckHummingbirdComponents(TurretMerge, ref hummingbirdConnector, ref turretRotor, ref PartScratchpad, ref status))
                {
                    turretRotor.Detach();
                    releaseStage    = 1;
                    Piston.Velocity = -0.2f;
                    return;
                }

                if (turretRotor != null)
                {
                    Hummingbird = Hummingbird.GetHummingbird(turretRotor, Host.Context.Terminal.GetBlockGroupWithName(Hummingbird.GroupName));
                    if (Hummingbird.Gats.Count == 0)
                    {
                        Hummingbird         = null;
                        TurretMerge.Enabled = true;
                        return;
                    }
                    releaseStage             = 20;
                    turretRotor.Displacement = 0.11f;
                    return;
                }
            }


            if (releaseStage > 1 && releaseStage < 20)
            {
                releaseStage++;
            }
            if (releaseStage == 5)
            {
            }
            else if (releaseStage == 7)
            {
            }
            else if (releaseStage == 8)
            {
                GridTerminalHelper.OtherMergeBlock(TurretMerge).Enabled = false;
                TurretMerge.Enabled = false;
            }
            else if (releaseStage == 9)
            {
                turretRotor.Attach();
            }
            else if (releaseStage == 10)
            {
                Piston.Velocity = 0.2f;
            }
            else if (releaseStage > 11 && Piston.CurrentPosition == Piston.MaxLimit)
            {
                turretRotor.Displacement = 0.11f;
                Hummingbird = Hummingbird.GetHummingbird(turretRotor, Host.Context.Terminal.GetBlockGroupWithName(Hummingbird.GroupName));
            }
        }
 private void RetireBird(Hummingbird bird)
 {
     bird.SetDest(Controller.WorldMatrix.Translation);
     bird.IsRetiring = true;
 }
        public void Update(TimeSpan timestamp, UpdateFrequency updateFlags)
        {
            if (timestamp == TimeSpan.Zero)
            {
                return;
            }
            foreach (var bird in Hummingbirds)
            {
                if (bird.IsAlive())
                {
                    bird.Update();
                }
                else
                {
                    DeadBirds.Add(bird);
                }
            }

            foreach (var bird in DeadBirds)
            {
                DeregisterBird(bird);
            }

            runs++;
            if (runs % 20 == 0)
            {
                var intelItems = IntelProvider.GetFleetIntelligences(timestamp);

                // Get the top targets
                TopEnemies.Clear();
                EnemyToScore.Clear();

                foreach (var intelItem in intelItems)
                {
                    if (intelItem.Key.Item1 == IntelItemType.Enemy)
                    {
                        var esi  = (EnemyShipIntel)intelItem.Value;
                        var dist = (esi.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff) - Context.Reference.WorldMatrix.Translation).Length();
                        if (dist > MaxEngagementDist)
                        {
                            continue;
                        }

                        var priority = IntelProvider.GetPriority(esi.ID);
                        var size     = esi.Radius;

                        if (size < MinEngagementSize && priority < 3)
                        {
                            continue;
                        }

                        if (priority < 2)
                        {
                            continue;
                        }

                        int score = (int)(priority * 10000 + size);

                        EnemyToScore[esi] = score;

                        for (int i = 0; i <= TopEnemies.Count; i++)
                        {
                            if (i == TopEnemies.Count || score > EnemyToScore[TopEnemies[i]])
                            {
                                TopEnemies.Insert(i, esi);
                                break;
                            }
                        }
                    }
                }

                // Determine how many birds should be assigned to each enemy
                EnemyToNumBirds.Clear();

                int totalNeededBirds = 0;

                for (int i = 0; i < TopEnemies.Count && i < 4; i++)
                {
                    EnemyToNumBirds[TopEnemies[i]]      = EnemyCountToNumBirdsPerEnemy[TopEnemies.Count][i];
                    EnemyToAssignedBirds[TopEnemies[i]] = 0;
                    totalNeededBirds += EnemyToNumBirds[TopEnemies[i]];
                }

                // Remove excess birds from enemies
                foreach (var bird in Hummingbirds)
                {
                    var birdTargetID = BirdToEnemy[bird];
                    if (birdTargetID == 0)
                    {
                        continue;
                    }

                    if (!bird.IsCombatCapable())
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    var birdTargetKey = MyTuple.Create(IntelItemType.Enemy, birdTargetID);
                    if (!intelItems.ContainsKey(birdTargetKey))
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    var birdTarget = (EnemyShipIntel)intelItems[birdTargetKey];
                    if (!EnemyToNumBirds.ContainsKey(birdTarget) || EnemyToNumBirds[birdTarget] == 0)
                    {
                        BirdToEnemy[bird] = 0;
                        continue;
                    }

                    EnemyToNumBirds[birdTarget]--;
                    totalNeededBirds--;
                }

                // Assign birds to enemies
                foreach (var bird in Hummingbirds)
                {
                    if (totalNeededBirds == 0)
                    {
                        break;
                    }

                    // Bird can't fight, keep looking
                    if (!bird.IsCombatCapable())
                    {
                        continue;
                    }

                    // Bird already has target, keep looking
                    if (BirdToEnemy[bird] != 0)
                    {
                        continue;
                    }

                    EnemyShipIntel targetEnemy = null;
                    foreach (var enemy in EnemyToNumBirds.Keys)
                    {
                        if (EnemyToNumBirds[enemy] > 0)
                        {
                            targetEnemy = enemy;
                            break;
                        }
                    }

                    BirdToEnemy[bird] = targetEnemy.ID;
                    EnemyToNumBirds[targetEnemy]--;
                    totalNeededBirds--;
                }

                NeedsMoreBirds = totalNeededBirds > 0;
                int birdIndex;

                // ASSUME birds are not far enough from main controller that gravity direction matters too much
                var gravDir = Controller.GetTotalGravity();
                gravDir.Normalize();

                // For each enemy, assign bird target and destination
                foreach (var enemy in TopEnemies)
                {
                    birdIndex = 0;
                    foreach (var bird in Hummingbirds)
                    {
                        if (BirdToEnemy[bird] != enemy.ID)
                        {
                            continue;
                        }

                        if (bird.Gats.Count == 0)
                        {
                            continue;
                        }
                        var birdAltitudeTheta = Math.PI * ((runs / (BirdSineConstantSeconds * 30) % 2) - 1);
                        var birdSwayTheta     = Math.PI * ((runs / (BirdPendulumConstantSeconds * 30) % 2) - 1);
                        var targetPos         = enemy.GetPositionFromCanonicalTime(timestamp + IntelProvider.CanonicalTimeDiff);

                        bird.SetTarget(targetPos, enemy.GetVelocity() - gravDir * (float)TrigHelpers.FastCos(birdAltitudeTheta) * 2);

                        var targetToBase = bird.Base.WorldMatrix.Translation - targetPos;
                        targetToBase -= VectorHelpers.VectorProjection(targetToBase, gravDir);
                        var targetToBaseDist = targetToBase.Length();
                        targetToBase.Normalize();

                        var engageLocationLocus    = targetToBase * Math.Min(600, targetToBaseDist + 400) + targetPos;
                        var engageLocationSwayDir  = targetToBase.Cross(gravDir);
                        var engageLocationSwayDist = (TrigHelpers.FastCos(birdSwayTheta) - EnemyToAssignedBirds[enemy] * 0.5 + birdIndex + 0.5) * 100;

                        bird.SetDest(engageLocationLocus + engageLocationSwayDist * engageLocationSwayDir);

                        var birdDir = bird.Controller.WorldMatrix.Translation - Controller.WorldMatrix.Translation;
                        birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir);;
                        var birdDist = birdDir.Length();

                        bird.Drive.DesiredAltitude = birdDist < 100 ? Hummingbird.RecommendedServiceCeiling :
                                                     (float)TrigHelpers.FastSin(birdAltitudeTheta + Math.PI * 0.5) *
                                                     (Hummingbird.RecommendedServiceCeiling - Hummingbird.RecommendedServiceFloor) + Hummingbird.RecommendedServiceFloor;

                        birdIndex++;
                    }
                }

                // Assign orbit task for unassigned birds
                int numReserveBirds = 0;
                foreach (var bird in Hummingbirds)
                {
                    if (BirdToEnemy[bird] == 0 && bird.IsCombatCapable())
                    {
                        numReserveBirds++;
                    }
                }
                birdIndex = 0;
                var randomPoint = new Vector3D(190, 2862, 809);
                randomPoint -= VectorHelpers.VectorProjection(randomPoint, gravDir);
                randomPoint.Normalize();

                var randomPointCross = randomPoint.Cross(gravDir);

                foreach (var bird in Hummingbirds)
                {
                    if (BirdToEnemy[bird] != 0)
                    {
                        continue;
                    }
                    bird.SetTarget(Vector3D.Zero, Vector3D.Zero);
                    bird.Drive.DesiredAltitude = 30;

                    if (bird.IsCombatCapable() && !bird.IsRetiring)
                    {
                        var birdOrbitTheta = Math.PI * (((2 * birdIndex / (float)numReserveBirds) + runs / (BirdOrbitSeconds * 30)) % 2 - 1);

                        var birdOrbitDest = Controller.WorldMatrix.Translation +
                                            TrigHelpers.FastCos(birdOrbitTheta) * randomPoint * BirdOrbitDist +
                                            TrigHelpers.FastSin(birdOrbitTheta) * randomPointCross * BirdOrbitDist;

                        bird.SetDest(birdOrbitDest);

                        birdIndex++;
                    }
                    else if (!bird.IsRetiring)
                    {
                        RetireBird(bird);
                    }
                    else if (bird.IsRetiring)
                    {
                        if (!bird.IsLanding)
                        {
                            var birdDir = bird.Controller.WorldMatrix.Translation - bird.Destination;
                            birdDir -= VectorHelpers.VectorProjection(birdDir, gravDir);
                            var birdDist = birdDir.Length();
                            birdDir.Normalize();

                            if (birdDist < 50)
                            {
                                bird.SetDest(Vector3D.Zero);
                                bird.Drive.Flush();
                                foreach (var engine in bird.Drive.HoverEngines)
                                {
                                    engine.AltitudeMin = 0;
                                }
                                bird.IsLanding = true;
                            }
                        }
                        else
                        {
                            double altitude;
                            bird.Controller.TryGetPlanetElevation(MyPlanetElevation.Surface, out altitude);
                            if (altitude < 6)
                            {
                                foreach (var engine in bird.Drive.HoverEngines)
                                {
                                    engine.Block.Enabled = false;
                                    DeadBirds.Add(bird);
                                }
                            }
                        }
                    }
                }
            }

            foreach (var cradle in Cradles)
            {
                if (cradle == null)
                {
                    continue;
                }
                cradle.Update();
            }

            if (runs % 60 == 0)
            {
                BirdReleaseTimeout--;
                for (int i = 0; i < Cradles.Count(); i++)
                {
                    if (Cradles[i] == null)
                    {
                        continue;
                    }
                    if (Cradles[i].Hummingbird == null)
                    {
                        Cradles[i].CheckHummingbird();
                    }
                    else if (NeedsMoreBirds && BirdReleaseTimeout <= 0)
                    {
                        Hummingbird bird = Cradles[i].Release();
                        bird.Base = Context.Reference;
                        RegisterBird(bird);
                        BirdReleaseTimeout = 5;
                    }
                }
            }

            DeadBirds.Clear();
        }