Exemplo n.º 1
0
        public override IEnumerable <SC2APIProtocol.Action> PerformActions(int frame)
        {
            if (ScoutLocations == null)
            {
                GetScoutLocations();
            }
            if (!LateGame && frame > SharkyOptions.FramesPerSecond * 4 * 60)
            {
                LateGame       = true;
                ScoutLocations = new List <Point2D>();
                foreach (var baseLocation in BaseData.BaseLocations.Where(b => !BaseData.SelfBases.Any(s => s.Location == b.Location) && !BaseData.EnemyBases.Any(s => s.Location == b.Location)))
                {
                    ScoutLocations.Add(baseLocation.MineralLineLocation);
                }
                ScoutLocationIndex = 0;
            }

            var commands = new List <SC2APIProtocol.Action>();

            foreach (var commander in UnitCommanders)
            {
                if (commander.UnitRole != UnitRole.Scout)
                {
                    commander.UnitRole = UnitRole.Scout;
                }
                if (commander.UnitCalculation.NearbyEnemies.Any(e => e.UnitClassifications.Contains(UnitClassification.Worker) || e.Attributes.Contains(Attribute.Structure)) && commander.UnitCalculation.NearbyEnemies.Count() < 5)
                {
                    var enemy  = commander.UnitCalculation.NearbyEnemies.FirstOrDefault();
                    var action = IndividualMicroController.Attack(commander, new Point2D {
                        X = enemy.Unit.Pos.X, Y = enemy.Unit.Pos.Y
                    }, TargetingData.ForwardDefensePoint, null, frame);
                    if (action != null)
                    {
                        commands.AddRange(action);
                    }
                }
                else if (Vector2.DistanceSquared(new Vector2(ScoutLocations[ScoutLocationIndex].X, ScoutLocations[ScoutLocationIndex].Y), commander.UnitCalculation.Position) < 2)
                {
                    ScoutLocationIndex++;
                    if (ScoutLocationIndex >= ScoutLocations.Count())
                    {
                        ScoutLocationIndex = 0;
                    }
                }
                else
                {
                    var action = IndividualMicroController.Scout(commander, ScoutLocations[ScoutLocationIndex], TargetingData.ForwardDefensePoint, frame);
                    if (action != null)
                    {
                        commands.AddRange(action);
                    }
                }
            }

            return(commands);
        }
Exemplo n.º 2
0
        public override IEnumerable <SC2APIProtocol.Action> PerformActions(int frame)
        {
            var commands = new List <SC2APIProtocol.Action>();

            AssignHarassers();

            foreach (var scoutInfo in ScoutInfos.Where(s => s.Harassers.Count() > 0))
            {
                foreach (var commander in scoutInfo.Harassers)
                {
                    if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(scoutInfo.Location.X, scoutInfo.Location.Y)) < 4)
                    {
                        var action = IndividualMicroController.Attack(commander, scoutInfo.Location, TargetingData.ForwardDefensePoint, null, frame);
                        if (action != null)
                        {
                            commands.AddRange(action);
                        }

                        if (!commander.UnitCalculation.NearbyEnemies.Any(e => Vector2.DistanceSquared(new Vector2(scoutInfo.Location.X, scoutInfo.Location.Y), e.Position) < 100))
                        {
                            scoutInfo.LastClearedFrame = frame;
                            scoutInfo.Harassers.Remove(commander);
                            return(commands);
                        }
                    }
                    else
                    {
                        var action = IndividualMicroController.Attack(commander, scoutInfo.Location, TargetingData.ForwardDefensePoint, null, frame);
                        if (action != null)
                        {
                            commands.AddRange(action);
                        }
                    }
                }
            }
            foreach (var harassInfo in HarassInfos)
            {
                foreach (var commander in harassInfo.Harassers)
                {
                    if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(harassInfo.BaseLocation.MineralLineLocation.X, harassInfo.BaseLocation.MineralLineLocation.Y)) < 4)
                    {
                        var action = IndividualMicroController.Attack(commander, harassInfo.BaseLocation.MineralLineLocation, TargetingData.ForwardDefensePoint, null, frame);
                        if (action != null)
                        {
                            commands.AddRange(action);
                        }

                        if (!commander.UnitCalculation.NearbyEnemies.Any(e => Vector2.DistanceSquared(new Vector2(harassInfo.BaseLocation.MineralLineLocation.X, harassInfo.BaseLocation.MineralLineLocation.Y), e.Position) < 100))
                        {
                            harassInfo.LastClearedFrame = frame;
                            harassInfo.Harassers.Remove(commander);
                            return(commands);
                        }
                    }
                    else
                    {
                        var action = IndividualMicroController.Attack(commander, harassInfo.BaseLocation.MineralLineLocation, TargetingData.ForwardDefensePoint, null, frame);
                        if (action != null)
                        {
                            commands.AddRange(action);
                        }
                    }
                }
            }

            return(commands);
        }
Exemplo n.º 3
0
        public List <SC2APIProtocol.Action> DealWithEnemies(int frame, List <UnitCommander> unitCommanders)
        {
            var actions = new List <SC2APIProtocol.Action>();

            foreach (var selfBase in BaseData.SelfBases)
            {
                bool preventGasSteal        = false;
                bool preventBuildingLanding = false;
                if (ActiveUnitData.Commanders.ContainsKey(selfBase.ResourceCenter.Tag) && ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Count() > 0)
                {
                    var flyingBuildings = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => u.Attributes.Contains(SC2APIProtocol.Attribute.Structure) && u.Unit.IsFlying);
                    if (flyingBuildings.Count() > 0)
                    {
                        var nearbyWorkers = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyAllies.Where(a => a.UnitClassifications.Contains(UnitClassification.Worker));
                        var commanders    = ActiveUnitData.Commanders.Where(c => nearbyWorkers.Any(w => w.Unit.Tag == c.Key));
                        preventBuildingLanding = true;
                        foreach (var flyingBuilding in flyingBuildings)
                        {
                            var closestDefender = commanders.OrderBy(d => Vector2.DistanceSquared(d.Value.UnitCalculation.Position, flyingBuilding.Position)).FirstOrDefault();
                            if (closestDefender.Value != null)
                            {
                                closestDefender.Value.UnitRole = UnitRole.PreventBuildingLand;
                                var action = closestDefender.Value.Order(frame, Abilities.MOVE, new SC2APIProtocol.Point2D {
                                    X = flyingBuilding.Position.X, Y = flyingBuilding.Position.Y
                                });
                                if (action != null)
                                {
                                    actions.AddRange(action);
                                }
                            }
                        }
                    }

                    if (!ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyAllies.Any(a => a.UnitClassifications.Contains(UnitClassification.ArmyUnit)) && (ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Any(e => e.UnitClassifications.Contains(UnitClassification.Worker) || e.Attributes.Contains(SC2APIProtocol.Attribute.Structure))))
                    {
                        var enemyGroundDamage = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(e => e.DamageGround).Sum(e => e.Damage);
                        var nearbyWorkers     = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyAllies.Where(a => a.UnitClassifications.Contains(UnitClassification.Worker));
                        var commanders        = ActiveUnitData.Commanders.Where(c => nearbyWorkers.Any(w => w.Unit.Tag == c.Key));
                        if (commanders.Count() < 1)
                        {
                            continue;
                        }

                        if (ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyAllies.Where(e => e.DamageGround || e.UnitClassifications.Contains(UnitClassification.Worker)).Sum(e => e.Damage) > enemyGroundDamage || BaseData.SelfBases.Count() == 1)
                        {
                            int desiredWorkers = 0;
                            var combatUnits    = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => u.UnitClassifications.Contains(UnitClassification.ArmyUnit));
                            var workers        = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => u.UnitClassifications.Contains(UnitClassification.Worker));

                            desiredWorkers = 1;

                            if (workers.Count(w => w.Unit.UnitType == (uint)UnitTypes.PROTOSS_PROBE) > 0)
                            {
                                var takenGases  = selfBase.GasMiningInfo.Select(i => i.ResourceUnit);
                                var openGeysers = BaseData.BaseLocations.SelectMany(b => b.VespeneGeysers).Where(g => g.VespeneContents > 0 && !takenGases.Any(t => t.Pos.X == g.Pos.X && t.Pos.Y == g.Pos.Y));
                                foreach (var gas in openGeysers)
                                {
                                    foreach (var worker in workers)
                                    {
                                        if (Vector2.DistanceSquared(new Vector2(gas.Pos.X, gas.Pos.Y), worker.Position) < 64)
                                        {
                                            preventGasSteal = true; // If enemy probe looking at empty gas send closest worker to touch that gas and prevent a steal
                                            var closestDefender = commanders.OrderBy(d => Vector2.DistanceSquared(d.Value.UnitCalculation.Position, new Vector2(gas.Pos.X, gas.Pos.Y))).FirstOrDefault();
                                            closestDefender.Value.UnitRole = UnitRole.PreventGasSteal;
                                            var action = closestDefender.Value.Order(frame, Abilities.MOVE, new SC2APIProtocol.Point2D {
                                                X = gas.Pos.X, Y = gas.Pos.Y
                                            });
                                            if (action != null)
                                            {
                                                actions.AddRange(action);
                                            }
                                        }
                                    }
                                }
                            }
                            if (workers.Count() > 1)
                            {
                                desiredWorkers = workers.Count() + 1;
                            }
                            if (workers.Count() > 8) // this is a worker rush
                            {
                                desiredWorkers = workers.Count() + 3;
                            }
                            if (desiredWorkers > commanders.Count())
                            {
                                desiredWorkers = commanders.Count();
                            }

                            if (ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => !u.Unit.IsFlying).Count() > 8)
                            {
                                DebugService.DrawText("--------------Defending Worker Rush-------------");
                                while (commanders.Count(c => c.Value.UnitRole == UnitRole.Defend) < desiredWorkers)
                                {
                                    var commander = commanders.FirstOrDefault(c => c.Value.UnitRole != UnitRole.Defend && c.Value.UnitRole != UnitRole.PreventGasSteal).Value;
                                    if (commander != null)
                                    {
                                        commander.UnitRole = UnitRole.Defend;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                var defenders = commanders.Where(c => c.Value.UnitRole == UnitRole.Defend);
                                foreach (var defender in defenders)
                                {
                                    actions.AddRange(WorkerMicroController.Attack(defender.Value, selfBase.Location, selfBase.MineralLineLocation, null, frame));
                                }
                                DebugService.DrawText($"--------------{defenders.Count()} versus {workers.Count()}-------------");
                            }
                            else
                            {
                                var baseVector     = new Vector2(selfBase.Location.X, selfBase.Location.Y);
                                var enemyBuildings = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => u.Attributes.Contains(SC2APIProtocol.Attribute.Structure)).OrderByDescending(u => u.Unit.BuildProgress).ThenBy(u => Vector2.DistanceSquared(u.Position, baseVector));
                                desiredWorkers = (enemyBuildings.Count() * 4) + workers.Count();

                                var enemy = ActiveUnitData.Commanders[selfBase.ResourceCenter.Tag].UnitCalculation.NearbyEnemies.Where(u => !u.Unit.IsFlying).OrderBy(u => Vector2.DistanceSquared(u.Position, new Vector2(selfBase.Location.X, selfBase.Location.Y))).FirstOrDefault();
                                if (enemyBuildings.Count() > 0 && !enemyBuildings.Any(u => u.Unit.UnitType == (uint)UnitTypes.PROTOSS_PHOTONCANNON && u.Unit.Shield == u.Unit.ShieldMax && u.Unit.BuildProgress == 1))
                                { // TODO: test this
                                    while (commanders.Count(c => c.Value.UnitRole == UnitRole.Defend) < desiredWorkers && commanders.Count(c => c.Value.UnitRole == UnitRole.Defend) < commanders.Count())
                                    {
                                        var commander = commanders.FirstOrDefault(c => c.Value.UnitRole != UnitRole.Defend && c.Value.UnitRole != UnitRole.PreventGasSteal).Value;
                                        if (commander != null)
                                        {
                                            commander.UnitRole = UnitRole.Defend;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                    var defenders   = commanders.Where(c => c.Value.UnitRole == UnitRole.Defend);
                                    var sentWorkers = new List <ulong>();
                                    foreach (var enemyBuilding in enemyBuildings)
                                    {
                                        var closestDefenders = defenders.Where(d => !sentWorkers.Contains(d.Key)).OrderBy(d => Vector2.DistanceSquared(d.Value.UnitCalculation.Position, enemyBuilding.Position)).Take(4); // attack each building with 4 workers
                                        foreach (var defender in closestDefenders)
                                        {
                                            var action = defender.Value.Order(frame, Abilities.ATTACK, null, enemyBuilding.Unit.Tag);
                                            if (action != null)
                                            {
                                                actions.AddRange(action);
                                            }
                                        }
                                        sentWorkers.AddRange(closestDefenders.Select(d => d.Key));
                                    }
                                    foreach (var enemyWorker in workers.OrderBy(u => Vector2.DistanceSquared(u.Position, baseVector)))
                                    {
                                        var closestDefenders = defenders.Where(d => !sentWorkers.Contains(d.Key)).OrderBy(d => Vector2.DistanceSquared(d.Value.UnitCalculation.Position, enemyWorker.Position)).Take(1);
                                        foreach (var defender in closestDefenders)
                                        {
                                            var action = defender.Value.Order(frame, Abilities.ATTACK, null, enemyWorker.Unit.Tag);
                                            if (action != null)
                                            {
                                                actions.AddRange(action);
                                            }
                                        }
                                        sentWorkers.AddRange(closestDefenders.Select(d => d.Key));
                                    }
                                }
                                else if (commanders.Count() < desiredWorkers)
                                {
                                    actions.AddRange(Run(frame, unitCommanders, selfBase));
                                }
                                else if (enemy != null)
                                {
                                    while (commanders.Count(c => c.Value.UnitRole == UnitRole.Defend) < desiredWorkers && commanders.Count(c => c.Value.UnitRole == UnitRole.Defend) < commanders.Count())
                                    {
                                        var commander = commanders.FirstOrDefault(c => c.Value.UnitRole != UnitRole.Defend && c.Value.UnitRole != UnitRole.PreventGasSteal).Value;
                                        if (commander != null)
                                        {
                                            commander.UnitRole = UnitRole.Defend;
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }

                                    var defenders = commanders.Where(c => c.Value.UnitRole == UnitRole.Defend);
                                    foreach (var defender in defenders)
                                    {
                                        actions.AddRange(WorkerMicroController.Attack(defender.Value, selfBase.Location, selfBase.MineralLineLocation, null, frame));
                                    }
                                }
                            }
                        }
                        else
                        {
                            actions.AddRange(Run(frame, unitCommanders, selfBase));
                        }
                    }
                    else
                    {
                        actions.AddRange(Run(frame, unitCommanders, selfBase));
                    }
                }
                if (!preventGasSteal)
                {
                    foreach (var commander in unitCommanders.Where(c => c.UnitRole == UnitRole.PreventGasSteal))
                    {
                        commander.UnitRole = UnitRole.None;
                    }
                }
                if (!preventBuildingLanding)
                {
                    foreach (var commander in unitCommanders.Where(c => c.UnitRole == UnitRole.PreventBuildingLand))
                    {
                        commander.UnitRole = UnitRole.None;
                    }
                }
            }

            var safeWorkers = ActiveUnitData.Commanders.Where(c => c.Value.UnitCalculation.UnitClassifications.Contains(UnitClassification.Worker) && (c.Value.UnitRole == UnitRole.Defend || c.Value.UnitRole == UnitRole.Bait) && c.Value.UnitCalculation.Unit.Orders.Count() == 0);

            foreach (var safeWorker in safeWorkers)
            {
                if (safeWorker.Value.UnitRole == UnitRole.Bait && safeWorker.Value.UnitCalculation.NearbyEnemies.Count() > 0)
                {
                    continue;
                }
                safeWorker.Value.UnitRole = UnitRole.None;
            }

            // only defend near the base, don't chase too far
            foreach (var commander in unitCommanders.Where(u => u.UnitRole == UnitRole.Defend))
            {
                if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.ATTACK_ATTACK) && (!commander.UnitCalculation.NearbyAllies.Any(a => a.UnitClassifications.Contains(UnitClassification.ResourceCenter)) || commander.UnitCalculation.NearbyAllies.Any(a => a.UnitClassifications.Contains(UnitClassification.ArmyUnit))))
                {
                    var action = commander.Order(frame, Abilities.STOP);
                    if (action != null)
                    {
                        actions.AddRange(action);
                    }
                }
            }

            return(actions);
        }