Beispiel #1
0
    public override AIAction GFixedUpdate(UnitCommander unitCmd, Vector2 goalPos)
    {
        //Init
        Vector2 moveVec = Vector2.zero;
        Vector2 pos = unitCmd.transform.position;
        unitCmd.GetComponent<Rigidbody2D>().gravityScale = 1;
        state = AIState.MOVING;

        //Check for enemies
        float directionX = unitCmd.turnedRight ? 1f : -1f;
        Vector2 inFrontUpperLeft = new Vector2(pos.x + directionX * 0.5f, pos.y + 0.5f);
        Vector2 inFrontLowerRight = new Vector2(pos.x + directionX * 0.9f, pos.y - 0.5f);
        Collider2D[] inFrontColliders = Physics2D.OverlapAreaAll(inFrontUpperLeft, inFrontLowerRight);
        foreach (Collider2D coll in inFrontColliders) {
            if (coll.tag.Equals("Monster")){
                state = AIState.ATTACKING;
            }
        }

        switch (state) {
        case AIState.MOVING:
            moveVec = Movement(unitCmd, goalPos);
            break;
        case AIState.ATTACKING:
            moveVec = AttackMove(unitCmd, inFrontColliders);
            break;

        default:
            break;
        }

        Debug.DrawLine(inFrontUpperLeft, inFrontLowerRight, Color.green);

        return new AIAction(moveVec, state == AIState.ATTACKING);
    }
Beispiel #2
0
    /// <summary>
    /// Move as close as possible to closest enemy
    /// </summary>
    /// <returns>The move.</returns>
    /// <param name="unitCmd">Unit cmd.</param>
    /// <param name="goalPos">Goal position.</param>
    protected Vector2 AttackMove(UnitCommander unitCmd, Collider2D[] inFrontColliders)
    {
        Vector2 moveVec = Vector2.zero;
        Vector2 pos = unitCmd.transform.position;

        //Get closest enemy
        float closestDist = float.MaxValue;
        Transform closestMonster = null;
        foreach (Collider2D coll in inFrontColliders) {
            if (coll.tag.Equals("Monster")){
                float dist = Vector2.Distance(unitCmd.transform.position, coll.transform.position);
                if (dist < closestDist){
                    closestDist = dist;
                    closestMonster = coll.transform;
                }
            }
        }

        //Turn towards closest enemy
        if (closestMonster.position.x > pos.x) unitCmd.turnedRight = true;
        else unitCmd.turnedRight = false;

        //Move towards enemy
        float distToEnemy = 0.75f; //TODO
        float goalPosX = closestMonster.position.x + (unitCmd.turnedRight ? -1 : 1) * distToEnemy;
        moveVec.x = Mathf.MoveTowards(pos.x, goalPosX, 0.1f) - pos.x;

        //		Debug.Log("pos: " + pos + ", closestMonster.position: " + closestMonster.position + ", closestDist: " + closestDist + " , moveVec:  "+ moveVec);

        //keep distance to fellow heroes
        //		Vector2 upperLeft = new Vector2(pos.x - 0.1f, pos.y + 0.5f);
        //		Vector2 lowerRight = new Vector2(pos.x + 0.1f, pos.y - 0.5f);
        //		Collider2D[] colliders = Physics2D.OverlapAreaAll(upperLeft, lowerRight);
        //
        //		float totXForce = 0;
        //		foreach (Collider2D coll in colliders) {
        //
        //			if (coll.tag.Equals("Hero"))
        //			{
        //				float xDiff = coll.transform.position.x - pos.x;
        //				float xForce = xDiff == 0 ? 0 : 0.1f/xDiff;
        //				totXForce -= xForce;
        //			}
        //		}
        //		//Apply hero-distancer force
        //		if (totXForce > 0.1) totXForce = 0.1f;
        //		if (totXForce < -0.1) totXForce = -0.1f;
        //		if ((moveVec.x > 0 && totXForce < 0) || (moveVec.x < 0 && totXForce > 0)) moveVec.x += totXForce;

        return moveVec;
    }
    void Start()
    {
        //create UnitCommander
        unitCommander = (UnitCommander)Instantiate(Resources.Load(("Prefabs/UnitCommander"), typeof(UnitCommander)));
        unitCommander.transform.position = transform.parent.position;
        unitCommander.transform.parent = transform.parent;
        unitCommander.SetClan(clan);

        //create BuildingCommander
        buildingCommander = (BuildingCommander)Instantiate(Resources.Load(("Prefabs/BuildingCommander"), typeof(BuildingCommander)));
        buildingCommander.transform.position = transform.parent.position;
        buildingCommander.transform.parent = transform.parent;
        buildingCommander.SetClan(clan);
    }
        bool SupportArmy(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Shield < commander.UnitCalculation.Unit.ShieldMax / 2)
            {
                if (AvoidTargettedDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (AvoidDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (commander.UnitCalculation.Unit.Shield < 1)
                {
                    if (Retreat(commander, target, defensivePoint, frame, out action))
                    {
                        return(true);
                    }
                }
            }


            // follow behind at the range of cloak field
            var armyUnits = ActiveUnitData.Commanders.Where(u => u.Value.UnitCalculation.UnitClassifications.Contains(UnitClassification.ArmyUnit)).Select(s => s.Value);

            var unitToSupport = GetSupportTarget(commander, armyUnits, target, defensivePoint);

            if (unitToSupport == null)
            {
                return(false);
            }

            var moveTo = GetSupportSpot(commander, unitToSupport, target, defensivePoint);

            action = commander.Order(frame, Abilities.MOVE, moveTo);
            return(true);
        }
    public void UpdateHealthBar(UnitCommander unitCmd)
    {
        int instId = unitCmd.GetInstanceID();

        Transform healthBarT = null;
        if (!healthBarDict.ContainsKey(instId)){
            healthBarT = Instantiate(healthBarPrefab);
            healthBarT.SetParent(canvas);
            healthBarDict.Add(instId, healthBarT);
        }else{
            healthBarT = healthBarDict[instId];
        }

        Vector2 aboveHeadPosition = Camera.main.WorldToScreenPoint(unitCmd.transform.position);
        aboveHeadPosition.y += 25;

        healthBarT.position = aboveHeadPosition;

        float health = unitCmd.health / (float) unitCmd.maxHealth;
        healthBarT.GetComponent<HealthBar>().UpdateBar(health, HealthToColor(health));
    }
        Point2D GetTimeWarpLocation(UnitCommander commander)
        {
            var enemiesInRange = commander.UnitCalculation.NearbyEnemies.Where(e => !e.Attributes.Contains(SC2APIProtocol.Attribute.Structure) && Vector2.DistanceSquared(e.Position, commander.UnitCalculation.Position) < TimeWarpRange * TimeWarpRange);

            var damageCounts = new Dictionary <Point, float>();

            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                float damageReduction = 0;
                foreach (var hitEnemy in enemiesInRange)
                {
                    if (!hitEnemy.Attributes.Contains(SC2APIProtocol.Attribute.Structure) && Vector2.DistanceSquared(hitEnemy.Position, enemyAttack.Position) <= (hitEnemy.Unit.Radius + TImeWarpRadius) * (hitEnemy.Unit.Radius + TImeWarpRadius))
                    {
                        damageReduction += hitEnemy.Dps;
                    }
                }
                damageCounts[enemyAttack.Unit.Pos] = damageReduction;
            }

            return(GetBestTimeWarpLocation(damageCounts.OrderByDescending(x => x.Value)));
        }
Beispiel #7
0
        public List <SC2APIProtocol.Action> HarassWorkers(UnitCommander commander, Point2D target, Point2D defensivePoint, int frame)
        {
            List <SC2APIProtocol.Action> action = null;

            var bestTarget = GetBestHarassTarget(commander, target);

            if (PreOffenseOrder(commander, target, defensivePoint, null, bestTarget, frame, out action))
            {
                return(action);
            }

            if (WeaponReady(commander) && commander.UnitCalculation.EnemiesInRange.Count() > 0)
            {
                if (AttackBestTarget(commander, target, defensivePoint, null, bestTarget, frame, out action))
                {
                    return(action);
                }
            }

            return(NavigateToPoint(commander, target, defensivePoint, null, frame));
        }
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (PulsarBeam(commander, frame, bestTarget, out action))
            {
                return(true);
            }

            if (Revelation(commander, frame, out action))
            {
                return(true);
            }

            if (StasisWard(commander, frame, bestTarget, out action))
            {
                return(true);
            }

            return(false);
        }
        protected override bool PreOffenseOrder(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Shield == commander.UnitCalculation.Unit.ShieldMax)
            {
                var cloakedPosition = CloakedInvader(commander);
                if (cloakedPosition != null)
                {
                    action = commander.Order(frame, Abilities.MOVE, cloakedPosition);
                    return(true);
                }
            }

            if (SupportArmy(commander, target, defensivePoint, groupCenter, frame, out action))
            {
                return(true);
            }

            return(false);
        }
Beispiel #10
0
        public List <SC2APIProtocol.Action> NavigateToPoint(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, int frame)
        {
            List <SC2APIProtocol.Action> action = null;

            if (PreOffenseOrder(commander, target, defensivePoint, null, null, frame, out action))
            {
                return(action);
            }

            if (MapDataService.InEnemyDetection(commander.UnitCalculation.Unit.Pos))
            {
                if (commander.UnitCalculation.NearbyEnemies.Count(e => e.DamageAir) > 0)
                {
                    if (commander.RetreatPathFrame + 20 < frame)
                    {
                        commander.RetreatPath      = SharkyPathFinder.GetSafeAirPath(target.X, target.Y, commander.UnitCalculation.Unit.Pos.X, commander.UnitCalculation.Unit.Pos.Y, frame);
                        commander.RetreatPathFrame = frame;
                    }

                    if (FollowPath(commander, frame, out action))
                    {
                        return(action);
                    }
                }

                if (AvoidTargettedDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(action);
                }

                if (AvoidDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(action);
                }
            }

            NavigateToTarget(commander, target, groupCenter, null, Formation.Normal, frame, out action);

            return(action);
        }
Beispiel #11
0
        bool StartWarping(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (!MapDataService.PathWalkable(commander.UnitCalculation.Unit.Pos))
            {
                return(false);
            }
            if (ActiveUnitData.Commanders.Values.Where(v => v.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPGATE && !v.UnitCalculation.Unit.IsActive && v.WarpInAlmostOffCooldown(frame, SharkyOptions.FramesPerSecond, SharkyUnitData)).Count() == 0)
            {
                return(false);
            }
            if (commander.UnitCalculation.Unit.Shield > 25 && !commander.UnitCalculation.NearbyAllies.Any(v => (v.Unit.UnitType == (uint)UnitTypes.PROTOSS_PYLON || v.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING) && DistanceSquared(commander.UnitCalculation, v) < 400)) // not near any pylons or other warping prisms
            {
                if (commander.UnitCalculation.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISM)
                {
                    action = commander.Order(frame, Abilities.MORPH_WARPPRISMPHASINGMODE, allowSpam: true);
                    return(true);
                }
            }
            return(false);
        }
        protected override bool PreOffenseOrder(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            var cloakedPosition = CloakedInvader(commander);

            if (cloakedPosition != null && commander.UnitCalculation.Unit.Energy >= 25)
            {
                action = commander.Order(frame, Abilities.EFFECT_ORACLEREVELATION, cloakedPosition);
                return(true);
            }

            var order = commander.UnitCalculation.Unit.Orders.FirstOrDefault(o => o.AbilityId == (uint)Abilities.EFFECT_ORACLEREVELATION && o.TargetWorldSpacePos != null);

            if (order != null && commander.UnitCalculation.Unit.Shield == commander.UnitCalculation.Unit.ShieldMax && commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.EFFECT_ORACLEREVELATION))
            {
                if (commander.UnitCalculation.Unit.Shield > commander.UnitCalculation.Unit.ShieldMax / 2.0)
                {
                    return(true);
                }

                if (Revelation(commander, frame, out action))
                {
                    return(true);
                }
            }

            if (AvoidTargettedDamage(commander, target, defensivePoint, frame, out action))
            {
                return(true);
            }

            if (AvoidDamage(commander, target, defensivePoint, frame, out action))
            {
                return(true);
            }

            return(false);
        }
        bool PulsarBeam(UnitCommander commander, int frame, UnitCalculation bestTarget, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (DeactivatePulsarBeam(commander, frame, bestTarget, out action))
            {
                return(true);
            }

            if (commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.ORACLEWEAPON) || commander.UnitCalculation.Unit.Energy < 50 || bestTarget == null)
            {
                return(false);
            }

            if (commander.UnitCalculation.EnemiesInRange.Any(e => e.Unit.Tag == bestTarget.Unit.Tag))
            {
                action = commander.Order(frame, Abilities.BEHAVIOR_PULSARBEAMON);
                return(true);
            }

            return(false);
        }
Beispiel #14
0
        protected override UnitCalculation GetBestDpsReduction(UnitCommander commander, Weapon weapon, IEnumerable <UnitCalculation> primaryTargets, IEnumerable <UnitCalculation> secondaryTargets)
        {
            float splashRadius  = 1f;
            var   dpsReductions = new Dictionary <ulong, float>();

            foreach (var enemyAttack in primaryTargets)
            {
                float dpsReduction = 0;
                foreach (var splashedEnemy in secondaryTargets)
                {
                    if (Vector2.DistanceSquared(splashedEnemy.Position, enemyAttack.Position) < (splashedEnemy.Unit.Radius + splashRadius) * (splashedEnemy.Unit.Radius + splashRadius))
                    {
                        dpsReduction += splashedEnemy.Dps / TimeToKill(weapon, splashedEnemy.Unit, SharkyUnitData.UnitData[(UnitTypes)splashedEnemy.Unit.UnitType]);
                    }
                }
                dpsReductions[enemyAttack.Unit.Tag] = dpsReduction;
            }

            var best = dpsReductions.OrderByDescending(x => x.Value).FirstOrDefault().Key;

            return(primaryTargets.FirstOrDefault(t => t.Unit.Tag == best));
        }
Beispiel #15
0
        protected override bool AttackBestTargetInRange(UnitCommander commander, Point2D target, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;
            if (bestTarget != null)
            {
                if (commander.UnitCalculation.EnemiesInRange.Any(e => e.Unit.Tag == bestTarget.Unit.Tag) && bestTarget.Unit.DisplayType == DisplayType.Visible)
                {
                    action = commander.Order(frame, Abilities.ATTACK, null, bestTarget.Unit.Tag);
                    return(true);
                }

                var blinkReady = SharkyUnitData.ResearchedUpgrades.Contains((uint)Upgrades.BLINKTECH) && commander.AbilityOffCooldown(Abilities.EFFECT_BLINK_STALKER, frame, SharkyOptions.FramesPerSecond, SharkyUnitData);
                if (blinkReady)
                {
                    action = commander.Order(frame, Abilities.EFFECT_BLINK_STALKER, new Point2D {
                        X = bestTarget.Unit.Pos.X, Y = bestTarget.Unit.Pos.Y
                    });
                    return(true);
                }
            }

            return(false);
        }
        protected override UnitCalculation GetBestDpsReduction(UnitCommander commander, Weapon weapon, IEnumerable <UnitCalculation> primaryTargets, IEnumerable <UnitCalculation> secondaryTargets)
        {
            float splashRadius  = 0.3f;
            var   dpsReductions = new Dictionary <ulong, float>();

            foreach (var enemyAttack in primaryTargets)
            {
                float dpsReduction = 0;
                var   attackLine   = GetAttackLine(commander.UnitCalculation.Unit.Pos, enemyAttack.Unit.Pos);
                foreach (var splashedEnemy in secondaryTargets)
                {
                    if (CollisionCalculator.Collides(splashedEnemy.Position, splashedEnemy.Unit.Radius + splashRadius, attackLine.Start, attackLine.End))
                    {
                        dpsReduction += splashedEnemy.Dps / TimeToKill(weapon, splashedEnemy.Unit, SharkyUnitData.UnitData[(UnitTypes)splashedEnemy.Unit.UnitType]);
                    }
                }
                dpsReductions[enemyAttack.Unit.Tag] = dpsReduction;
            }

            var best = dpsReductions.OrderByDescending(x => x.Value).FirstOrDefault().Key;

            return(primaryTargets.FirstOrDefault(t => t.Unit.Tag == best));
        }
Beispiel #17
0
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (bestTarget != null && SharkyUnitData.ResearchedUpgrades.Contains((uint)Upgrades.DARKTEMPLARBLINKUPGRADE) && commander.AbilityOffCooldown(Abilities.EFFECT_SHADOWSTRIDE, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                var distanceSqaured = Vector2.DistanceSquared(commander.UnitCalculation.Position, bestTarget.Position);

                if (distanceSqaured <= ShadowStrikeRange * ShadowStrikeRange && distanceSqaured > 9)
                {
                    var x          = bestTarget.Unit.Radius * Math.Cos(bestTarget.Unit.Facing);
                    var y          = bestTarget.Unit.Radius * Math.Sin(bestTarget.Unit.Facing);
                    var blinkPoint = new Point2D {
                        X = bestTarget.Unit.Pos.X + (float)x, Y = bestTarget.Unit.Pos.Y - (float)y
                    };

                    action = commander.Order(frame, Abilities.EFFECT_SHADOWSTRIDE, blinkPoint);
                    return(true);
                }
            }

            return(false);
        }
Beispiel #18
0
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Energy < 50)
            {
                return(false);
            }

            if (commander.UnitCalculation.NearbyEnemies.Any(e => e.Unit.BuffIds.Contains((uint)Buffs.GRAVITONBEAM))) // only have one unit lifted at a time
            {
                return(false);
            }

            var bestGravitonTarget = GetBestGravitonBeamTarget(commander, target);

            if (bestGravitonTarget != null)
            {
                action = commander.Order(frame, Abilities.EFFECT_GRAVITONBEAM, null, bestGravitonTarget.Unit.Tag);
                return(true);
            }

            return(false);
        }
        bool TimeWarp(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.EFFECT_TIMEWARP))
            {
                return(true);
            }

            if (commander.UnitCalculation.Unit.Energy < 100 || !commander.AbilityOffCooldown(Abilities.EFFECT_TIMEWARP, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                return(false);
            }

            var point = GetTimeWarpLocation(commander);

            if (point == null)
            {
                return(false);
            }

            action = commander.Order(frame, Abilities.EFFECT_TIMEWARP, point);
            return(true);
        }
        Point2D CloakedInvader(UnitCommander commander)
        {
            var pos = commander.UnitCalculation.Position;

            var hiddenUnits = ActiveUnitData.EnemyUnits.Where(e => e.Value.Unit.DisplayType == DisplayType.Hidden).OrderBy(e => Vector2.DistanceSquared(pos, e.Value.Position));

            if (hiddenUnits.Count() > 0)
            {
                return(new Point2D {
                    X = hiddenUnits.FirstOrDefault().Value.Unit.Pos.X, Y = hiddenUnits.FirstOrDefault().Value.Unit.Pos.Y
                });
            }

            var unit = ActiveUnitData.SelfUnits.Values.Where(a => a.Unit.UnitType == (uint)UnitTypes.PROTOSS_NEXUS).SelectMany(a => a.NearbyEnemies).Where(e => SharkyUnitData.CloakableAttackers.Contains((UnitTypes)e.Unit.UnitType) && !e.Unit.BuffIds.Contains((uint)Buffs.ORACLEREVELATION)).OrderBy(e => Vector2.DistanceSquared(pos, e.Position)).FirstOrDefault();

            if (unit != null)
            {
                return(new Point2D {
                    X = unit.Unit.Pos.X, Y = unit.Unit.Pos.Y
                });
            }

            return(null);
        }
Beispiel #21
0
        bool DetermineMiningAction(UnitCommander commander, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = new List <SC2APIProtocol.Action>();

            if (commander.UnitCalculation.NearbyEnemies.Count > 0)
            {
                return(false);
            }

            var nexuses = BaseData.SelfBases.Where(u => u.ResourceCenter.BuildProgress == 1 && u.MineralMiningInfo.Count() > 0).OrderBy(u => u.MineralMiningInfo.Sum(m => m.Workers.Count) / u.MineralMiningInfo.Count()).ThenBy(u => Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(u.Location.X, u.Location.Y)));

            //foreach (var nexusBase in BaseData.Bases)
            //{
            //    DrawSphere(SC2Util.Point(nexusBase.MineralLinePos.X, nexusBase.MineralLinePos.Y, 11));
            //}

            if (commander.UnitCalculation.Unit.Passengers.Count > 0)
            {
                //action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, null, commander.UnitCalculation.Unit.Tag);
                foreach (var passenger in commander.UnitCalculation.Unit.Passengers)
                {
                    var passengerAction = commander.UnloadSpecificUnit(frame, Abilities.UNLOADUNIT_WARPPRISM, passenger.Tag);
                    if (passengerAction != null)
                    {
                        action.AddRange(passengerAction);
                    }
                }
                return(true);
            }

            if (StopWarping(commander, frame, out action))
            {
                return(true);
            }

            var otherWarpPrisms = ActiveUnitData.SelfUnits.Where(u => u.Value.Unit.Tag != commander.UnitCalculation.Unit.Tag && (u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISM || u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_WARPPRISMPHASING));

            foreach (var nexus in nexuses)
            {
                if (!otherWarpPrisms.Any(o => Vector2.DistanceSquared(o.Value.Position, new Vector2(nexus.Location.X, nexus.Location.Y)) < 25))
                {
                    var miningLocation = GetMiningSpot(nexus);
                    if (miningLocation != null)
                    {
                        //DrawSphere(SC2Util.Point(miningLocation.X, miningLocation.Y, 11));

                        if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(miningLocation.X, miningLocation.Y)) < .5)
                        {
                            var probe = commander.UnitCalculation.NearbyAllies.Where(a => a.Unit.BuffIds.Any(b => SharkyUnitData.CarryingMineralBuffs.Contains((Buffs)b)) && InRange(a.Position, commander.UnitCalculation.Position, PickupRange) && !InRange(a.Position, new Vector2(nexus.Location.X, nexus.Location.Y), nexus.ResourceCenter.Radius + 1)).OrderByDescending(u => Vector2.DistanceSquared(new Vector2(nexus.Location.X, nexus.Location.Y), u.Position)).FirstOrDefault();
                            if (probe != null)
                            {
                                action = commander.Order(frame, Abilities.LOAD, null, probe.Unit.Tag);
                                return(true);
                            }
                            else
                            {
                                action = commander.Order(frame, Abilities.UNLOADALLAT_WARPPRISM, miningLocation);
                                return(true);
                            }
                        }

                        action = commander.Order(frame, Abilities.MOVE, miningLocation);
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #22
0
    protected Vector2 Movement(UnitCommander unitCmd, Vector2 goalPos)
    {
        Vector2 moveVec = Vector2.zero;
        Vector2 pos = unitCmd.transform.position;
        bool isOnStairs = false;
        Vector2 upperLeft = new Vector2(pos.x - 0.1f, pos.y + 0.5f);
        Vector2 lowerRight = new Vector2(pos.x + 0.1f, pos.y - 0.5f);
        Collider2D[] colliders = Physics2D.OverlapAreaAll(upperLeft, lowerRight);

        float totXForce = 0;
        foreach (Collider2D coll in colliders) {

            //Is on stairs?
            if (coll.tag.Equals("Stairs"))
            {
                isOnStairs = true;
                unitCmd.GetComponent<Rigidbody2D>().gravityScale = 0;
                unitCmd.GetComponent<Rigidbody2D>().velocity = Vector2.zero;
                break;
            }//Move away from other heroes
        //			else if (coll.tag.Equals("Hero"))
        //			{
        //				float xDiff = coll.transform.position.x - pos.x;
        //				float xForce = xDiff == 0 ? 0 : 0.1f/xDiff;
        //				totXForce -= xForce;
        //			}
        }

        //Move in x or y direction / Can move in y direction?
        if (isOnStairs && CanContinueOnStairs(pos, goalPos)){ // &&  transform.position.y - 0.5f < goalPos.y || transform.position.y - 0.6f > goalPos.y){
            moveVec.y = Mathf.MoveTowards(pos.y, goalPos.y, 0.1f) - pos.y;
        }else{
            moveVec.x = Mathf.MoveTowards(pos.x, goalPos.x, 0.1f) - pos.x;
        }

        //Apply hero-distancer force
        //		if (totXForce > 0.1) totXForce = 0.1f;
        //		if (totXForce < -0.1) totXForce = -0.1f;
        //		if ((moveVec.x > 0 && totXForce < 0) || (moveVec.x < 0 && totXForce > 0)) moveVec.x += totXForce;

        return moveVec;
    }
Beispiel #23
0
 public virtual AIAction GFixedUpdate(UnitCommander unitCmd, Vector2 goalPos)
 {
     return new AIAction(Vector2.zero, false);
 }
 bool StasisWard(UnitCommander commander, int frame, UnitCalculation bestTarget, out List <SC2APIProtocol.Action> action)
 {
     action = null;
     return(false); // TODO:  stasis ward, put stasis wards on the tops of ramps
 }
Beispiel #25
0
 public void Init(Vector2 velVec, Sprite sprite, UnitCommander unitCmd)
 {
     GetComponent<SpriteRenderer>().sprite = sprite;
     GetComponent<Rigidbody2D>().velocity = velVec;
     ownerUnitCmd = unitCmd;
 }
Beispiel #26
0
 protected override bool GetHighGroundVision(UnitCommander commander, Point2D target, Point2D defensivePoint, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
 {
     action = null;
     return(false);
 }
Beispiel #27
0
        protected override UnitCalculation GetBestTarget(UnitCommander commander, Point2D target, int frame)
        {
            var existingAttackOrder = commander.UnitCalculation.Unit.Orders.Where(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK).FirstOrDefault();

            var range = commander.UnitCalculation.Range;

            var attacks = new List <UnitCalculation>(commander.UnitCalculation.EnemiesInRange.Where(u => u.Unit.DisplayType == DisplayType.Visible)); // units that are in range right now

            UnitCalculation bestAttack = null;

            if (attacks.Count > 0)
            {
                var oneShotKills = attacks.Where(a => a.Unit.Health + a.Unit.Shield < GetDamage(commander.UnitCalculation.Weapons, a.Unit, a.UnitTypeData) && !a.Unit.BuffIds.Contains((uint)Buffs.IMMORTALOVERLOAD));
                if (oneShotKills.Count() > 0)
                {
                    if (existingAttackOrder != null)
                    {
                        var existing = oneShotKills.FirstOrDefault(o => o.Unit.Tag == existingAttackOrder.TargetUnitTag);
                        if (existing != null)
                        {
                            return(existing); // just keep attacking the same unit
                        }
                    }

                    var oneShotKill = GetBestTargetFromList(commander, oneShotKills, existingAttackOrder);
                    if (oneShotKill != null)
                    {
                        return(oneShotKill);
                    }
                    else
                    {
                        commander.BestTarget = oneShotKills.OrderBy(o => o.Dps).FirstOrDefault();
                        return(commander.BestTarget);
                    }
                }

                bestAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestAttack != null && (bestAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure) || (bestAttack.UnitClassifications.Contains(UnitClassification.Worker) && bestAttack.EnemiesInRange.Any(e => e.Unit.Tag == commander.UnitCalculation.Unit.Tag))))
                {
                    commander.BestTarget = bestAttack;
                    return(bestAttack);
                }
            }

            attacks = new List <UnitCalculation>(); // nearby units not in range right now
            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (enemyAttack.Unit.DisplayType == DisplayType.Visible && DamageService.CanDamage(commander.UnitCalculation, enemyAttack) && !InRange(enemyAttack.Position, commander.UnitCalculation.Position, range + enemyAttack.Unit.Radius + commander.UnitCalculation.Unit.Radius))
                {
                    attacks.Add(enemyAttack);
                }
            }

            var safeAttacks = attacks.Where(a => a.Damage < commander.UnitCalculation.Unit.Health);

            if (safeAttacks.Count() > 0)
            {
                var bestOutOfRangeAttack = GetBestTargetFromList(commander, safeAttacks, existingAttackOrder);
                if (bestOutOfRangeAttack != null && (bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                {
                    commander.BestTarget = bestOutOfRangeAttack;
                    return(bestOutOfRangeAttack);
                }
                if (bestAttack == null)
                {
                    bestAttack = bestOutOfRangeAttack;
                }
            }

            if (commander.UnitCalculation.Unit.Health < 6)
            {
                return(null);
            }

            if (attacks.Count > 0)
            {
                var bestOutOfRangeAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestOutOfRangeAttack != null && (bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                {
                    commander.BestTarget = bestOutOfRangeAttack;
                    return(bestOutOfRangeAttack);
                }
                if (bestAttack == null)
                {
                    bestAttack = bestOutOfRangeAttack;
                }
            }

            if (!MapDataService.SelfVisible(target)) // if enemy main is unexplored, march to enemy main
            {
                var fakeMainBase = new Unit(commander.UnitCalculation.Unit);
                fakeMainBase.Pos = new Point {
                    X = target.X, Y = target.Y, Z = 1
                };
                fakeMainBase.Alliance = Alliance.Enemy;
                return(new UnitCalculation(fakeMainBase, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame));
            }
            var unitsNearEnemyMain = ActiveUnitData.EnemyUnits.Values.Where(e => e.Unit.UnitType != (uint)UnitTypes.ZERG_LARVA && InRange(new Vector2(target.X, target.Y), e.Position, 20));

            if (unitsNearEnemyMain.Count() > 0 && InRange(new Vector2(target.X, target.Y), commander.UnitCalculation.Position, 100))
            {
                attacks = new List <UnitCalculation>(); // enemies in the main enemy base
                foreach (var enemyAttack in unitsNearEnemyMain)
                {
                    if (enemyAttack.Unit.DisplayType == DisplayType.Visible && DamageService.CanDamage(commander.UnitCalculation, enemyAttack))
                    {
                        attacks.Add(enemyAttack);
                    }
                }
                if (attacks.Count > 0)
                {
                    var bestMainAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                    if (bestMainAttack != null && (bestMainAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestMainAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                    {
                        commander.BestTarget = bestMainAttack;
                        return(bestMainAttack);
                    }
                    if (bestAttack == null)
                    {
                        bestAttack = bestMainAttack;
                    }
                }
            }

            commander.BestTarget = bestAttack;
            return(bestAttack);
        }
 protected override bool WeaponReady(UnitCommander commander)
 {
     return(commander.UnitCalculation.Unit.BuffIds.Contains((uint)Buffs.ORACLEWEAPON));
 }
        // TODO: regular range is 8, but leash range is 14

        protected override bool WeaponReady(UnitCommander commander)
        {
            return(commander.UnitCalculation.Unit.WeaponCooldown == 0 || commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK));
        }
Beispiel #30
0
        public override IEnumerable <Action> OnFrame(ResponseObservation observation)
        {
            //var total = new Stopwatch();
            //total.Start();

            //var stopwatch = new Stopwatch();
            //stopwatch.Start();

            var frame = (int)observation.Observation.GameLoop;

            if (observation.Observation.RawData.Event != null && observation.Observation.RawData.Event.DeadUnits != null)
            {
                ActiveUnitData.DeadUnits = observation.Observation.RawData.Event.DeadUnits.ToList();
            }
            else
            {
                ActiveUnitData.DeadUnits = new List <ulong>();
            }

            foreach (var unit in ActiveUnitData.SelfUnits.Where(u => u.Value.Unit.UnitType == (uint)UnitTypes.PROTOSS_DISRUPTORPHASED)) // remove things like purification novas that don't have dead unit events
            {
                if (!observation.Observation.RawData.Units.Any(u => u.Tag == unit.Key))
                {
                    ActiveUnitData.DeadUnits.Add(unit.Key);
                }
            }

            foreach (var tag in ActiveUnitData.DeadUnits)
            {
                if (ActiveUnitData.EnemyUnits.TryRemove(tag, out UnitCalculation removedEnemy))
                {
                    ActiveUnitData.EnemyDeaths++;
                }
                else if (ActiveUnitData.SelfUnits.TryRemove(tag, out UnitCalculation removedAlly))
                {
                    ActiveUnitData.SelfDeaths++;
                }
                else if (ActiveUnitData.NeutralUnits.TryRemove(tag, out UnitCalculation removedNeutral))
                {
                    ActiveUnitData.NeutralDeaths++;
                }

                ActiveUnitData.Commanders.TryRemove(tag, out UnitCommander removedCommander);
            }

            foreach (var unit in ActiveUnitData.EnemyUnits.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.Unit.UnitType)))
            {
                ActiveUnitData.EnemyUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }
            foreach (var unit in ActiveUnitData.SelfUnits.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.Unit.UnitType)))
            {
                ActiveUnitData.SelfUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }
            foreach (var unit in ActiveUnitData.Commanders.Where(u => UndeadTypes.Contains((UnitTypes)u.Value.UnitCalculation.Unit.UnitType)))
            {
                ActiveUnitData.Commanders.TryRemove(unit.Key, out UnitCommander removed);
            }

            foreach (var unit in ActiveUnitData.EnemyUnits.Where(u => u.Value.UnitTypeData.Attributes.Contains(SC2APIProtocol.Attribute.Structure))) // structures get replaced by snapshots if we can't see them, so just remove them and let them get readded
            {
                ActiveUnitData.EnemyUnits.TryRemove(unit.Key, out UnitCalculation removed);
            }

            //Debug.WriteLine($"removal {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            var repairers = observation.Observation.RawData.Units.Where(u => u.UnitType == (uint)UnitTypes.TERRAN_SCV || u.UnitType == (uint)UnitTypes.TERRAN_MULE);

            //Parallel.ForEach(observation.Observation.RawData.Units, (unit) =>
            //{
            //    if (unit.Alliance == Alliance.Enemy)
            //    {
            //        var repairingUnitCount = repairers.Where(u => u.Alliance == Alliance.Enemy && Vector2.DistanceSquared(new Vector2(u.Pos.X, u.Pos.Y), new Vector2(unit.Pos.X, unit.Pos.Y)) < (1.0 + u.Radius + unit.Radius) * (0.1 + u.Radius + unit.Radius)).Count();
            //        var attack = new UnitCalculation(unit, repairingUnitCount, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.EnemyUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.EnemyUnits[unit.Tag] = attack;
            //    }
            //    else if (unit.Alliance == Alliance.Self)
            //    {
            //        var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.SelfUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.SelfUnits[unit.Tag] = attack;
            //    }
            //    else if (unit.Alliance == Alliance.Neutral)
            //    {
            //        var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
            //        if (ActiveUnitData.NeutralUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
            //        {
            //            attack.SetPreviousUnit(existing, existing.FrameLastSeen);
            //        }
            //        ActiveUnitData.NeutralUnits[unit.Tag] = attack;
            //    }
            //});

            foreach (var unit in observation.Observation.RawData.Units)
            {
                if (unit.Alliance == Alliance.Enemy)
                {
                    var repairingUnitCount = repairers.Where(u => u.Alliance == Alliance.Enemy && Vector2.DistanceSquared(new Vector2(u.Pos.X, u.Pos.Y), new Vector2(unit.Pos.X, unit.Pos.Y)) < (1.0 + u.Radius + unit.Radius) * (0.1 + u.Radius + unit.Radius)).Count();
                    var attack             = new UnitCalculation(unit, repairingUnitCount, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.EnemyUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.EnemyUnits[unit.Tag] = attack;
                }
                else if (unit.Alliance == Alliance.Self)
                {
                    var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.SelfUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.SelfUnits[unit.Tag] = attack;
                }
                else if (unit.Alliance == Alliance.Neutral)
                {
                    var attack = new UnitCalculation(unit, 0, SharkyUnitData, SharkyOptions, UnitDataService, frame);
                    if (ActiveUnitData.NeutralUnits.TryGetValue(unit.Tag, out UnitCalculation existing))
                    {
                        attack.SetPreviousUnit(existing, existing.FrameLastSeen);
                    }
                    ActiveUnitData.NeutralUnits[unit.Tag] = attack;
                }
            }

            //Debug.WriteLine($"parallel {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var enemy in ActiveUnitData.EnemyUnits.Select(e => e.Value).ToList()) // if we can see this area of the map and the unit isn't there anymore remove it (we just remove it because visible units will get re-added below)
            {
                if (enemy.FrameLastSeen != frame && MapDataService.SelfVisible(enemy.Unit.Pos))
                {
                    ActiveUnitData.EnemyUnits.TryRemove(enemy.Unit.Tag, out UnitCalculation removed);
                }
            }

            //Debug.WriteLine($"remove vision {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var allyAttack in ActiveUnitData.SelfUnits)
            {
                foreach (var enemyAttack in ActiveUnitData.EnemyUnits)
                {
                    if (DamageService.CanDamage(allyAttack.Value, enemyAttack.Value) && Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= (allyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius) * (allyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius))
                    {
                        allyAttack.Value.EnemiesInRange.Add(enemyAttack.Value);
                        enemyAttack.Value.EnemiesInRangeOf.Add(allyAttack.Value);
                    }
                    if (DamageService.CanDamage(enemyAttack.Value, allyAttack.Value) && Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= (enemyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius) * (enemyAttack.Value.Range + allyAttack.Value.Unit.Radius + enemyAttack.Value.Unit.Radius))
                    {
                        enemyAttack.Value.EnemiesInRange.Add(allyAttack.Value);
                        allyAttack.Value.EnemiesInRangeOf.Add(enemyAttack.Value);
                    }

                    if (Vector2.DistanceSquared(allyAttack.Value.Position, enemyAttack.Value.Position) <= NearbyDistance * NearbyDistance)
                    {
                        enemyAttack.Value.NearbyEnemies.Add(allyAttack.Value);
                        allyAttack.Value.NearbyEnemies.Add(enemyAttack.Value);
                    }
                }

                allyAttack.Value.NearbyAllies = ActiveUnitData.SelfUnits.Where(a => a.Key != allyAttack.Key && Vector2.DistanceSquared(allyAttack.Value.Position, a.Value.Position) <= NearbyDistance * NearbyDistance).Select(a => a.Value).ToList();

                var commander = new UnitCommander(allyAttack.Value);
                ActiveUnitData.Commanders.AddOrUpdate(allyAttack.Value.Unit.Tag, commander, (tag, existingCommander) =>
                {
                    commander = existingCommander;
                    commander.UnitCalculation = allyAttack.Value;
                    return(commander);
                });
            }

            //Debug.WriteLine($"allyattack {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            foreach (var enemyAttack in ActiveUnitData.EnemyUnits)
            {
                enemyAttack.Value.NearbyAllies = ActiveUnitData.EnemyUnits.Where(a => a.Key != enemyAttack.Key && Vector2.DistanceSquared(enemyAttack.Value.Position, a.Value.Position) <= NearbyDistance * NearbyDistance).Select(a => a.Value).ToList();
            }

            //Debug.WriteLine($"enemyunits {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            if (TargetPriorityCalculationFrame + 10 < frame)
            {
                foreach (var selfUnit in ActiveUnitData.SelfUnits)
                {
                    if (selfUnit.Value.TargetPriorityCalculation == null || selfUnit.Value.TargetPriorityCalculation.FrameCalculated + 10 < frame)
                    {
                        var priorityCalculation = TargetPriorityService.CalculateTargetPriority(selfUnit.Value, frame);
                        selfUnit.Value.TargetPriorityCalculation = priorityCalculation;
                        foreach (var nearbyUnit in selfUnit.Value.NearbyAllies.Where(a => a.NearbyEnemies.Count() == selfUnit.Value.NearbyAllies.Count()))
                        {
                            nearbyUnit.TargetPriorityCalculation = priorityCalculation;
                        }
                    }

                    selfUnit.Value.Attackers = GetTargettedAttacks(selfUnit.Value).ToList();
                }
                TargetPriorityCalculationFrame = frame;
            }
            //foreach (var selfUnit in ActiveUnitData.SelfUnits)
            //{
            //    if (selfUnit.Value.TargetPriorityCalculation == null || selfUnit.Value.TargetPriorityCalculation.FrameCalculated + 10 < frame)
            //    {
            //        var priorityCalculation = TargetPriorityService.CalculateTargetPriority(selfUnit.Value, frame);
            //        selfUnit.Value.TargetPriorityCalculation = priorityCalculation;
            //        foreach (var nearbyUnit in selfUnit.Value.NearbyAllies)
            //        {
            //            nearbyUnit.TargetPriorityCalculation = priorityCalculation;
            //        }
            //    }

            //    selfUnit.Value.Attackers = GetTargettedAttacks(selfUnit.Value).ToList();
            //}

            //Debug.WriteLine($"selfunits {stopwatch.ElapsedMilliseconds}");
            //stopwatch.Restart();

            if (SharkyOptions.Debug)
            {
                foreach (var selfUnit in ActiveUnitData.SelfUnits)
                {
                    DebugService.DrawLine(selfUnit.Value.Unit.Pos, new Point {
                        X = selfUnit.Value.End.X, Y = selfUnit.Value.End.Y, Z = selfUnit.Value.Unit.Pos.Z + 1f
                    }, new SC2APIProtocol.Color {
                        R = 0, B = 0, G = 255
                    });
                }
                foreach (var enemyUnit in ActiveUnitData.EnemyUnits)
                {
                    DebugService.DrawLine(enemyUnit.Value.Unit.Pos, new Point {
                        X = enemyUnit.Value.End.X, Y = enemyUnit.Value.End.Y, Z = enemyUnit.Value.Unit.Pos.Z + 1f
                    }, new SC2APIProtocol.Color {
                        R = 255, B = 0, G = 0
                    });
                }
            }

            //stopwatch.Stop();
            //Debug.WriteLine($"debug {stopwatch.ElapsedMilliseconds}");
            //total.Stop();
            //Debug.WriteLine($"total {total.ElapsedMilliseconds}");

            //if (total.ElapsedMilliseconds > 15)
            //{
            //    var uhoh = true;
            //}

            //Debug.WriteLine($"");

            return(null);
        }
Beispiel #31
0
        protected override bool OffensiveAbility(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, UnitCalculation bestTarget, int frame, out List <SC2APIProtocol.Action> action)
        {
            action = null;

            if (!commander.AbilityOffCooldown(Abilities.EFFECT_PURIFICATIONNOVA, frame, SharkyOptions.FramesPerSecond, SharkyUnitData))
            {
                return(false);
            }

            if (commander.UnitCalculation.NearbyAllies.Any(a => a.Unit.UnitType == (uint)UnitTypes.PROTOSS_DISRUPTORPHASED && Vector2.DistanceSquared(a.Position, commander.UnitCalculation.Position) < PurificationNovaRange * PurificationNovaRange))
            {
                return(false);
            }

            if (lastPurificationFrame >= frame - 5)
            {
                return(false);
            }

            var attacks = new List <UnitCalculation>();
            var center  = commander.UnitCalculation.Position;

            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (!enemyAttack.Unit.IsFlying && InRange(enemyAttack.Position, commander.UnitCalculation.Position, PurificationNovaRange + enemyAttack.Unit.Radius + commander.UnitCalculation.Unit.Radius)) // TODO: do actual pathing to see if the shot can make it there, if a wall is in the way it can't
                {
                    attacks.Add(enemyAttack);
                }
            }

            if (attacks.Count > 0)
            {
                var oneShotKills = attacks.OrderBy(a => GetPurificationNovaDamage(a.Unit, SharkyUnitData.UnitData[(UnitTypes)a.Unit.UnitType])).ThenByDescending(u => u.Dps);
                if (oneShotKills.Count() > 0)
                {
                    var bestAttack = GetBestAttack(commander.UnitCalculation, oneShotKills, attacks);
                    if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.WinAir)
                    {
                        var airAttackers = oneShotKills.Where(u => u.DamageAir);
                        if (airAttackers.Count() > 0)
                        {
                            var air = GetBestAttack(commander.UnitCalculation, airAttackers, attacks);
                            if (air != null)
                            {
                                bestAttack = air;
                            }
                        }
                    }
                    else if (commander.UnitCalculation.TargetPriorityCalculation.TargetPriority == TargetPriority.WinGround)
                    {
                        var groundAttackers = oneShotKills.Where(u => u.DamageGround);
                        if (groundAttackers.Count() > 0)
                        {
                            var ground = GetBestAttack(commander.UnitCalculation, groundAttackers, attacks);
                            if (ground != null)
                            {
                                bestAttack = ground;
                            }
                        }
                    }
                    else
                    {
                        if (oneShotKills.Count() > 0)
                        {
                            var any = GetBestAttack(commander.UnitCalculation, oneShotKills, attacks);
                            if (any != null)
                            {
                                bestAttack = any;
                            }
                        }
                    }

                    if (bestAttack != null)
                    {
                        action = commander.Order(frame, Abilities.EFFECT_PURIFICATIONNOVA, bestAttack);
                        lastPurificationFrame = frame;
                        return(true);
                    }
                }
            }

            return(false);
        }
Beispiel #32
0
        public bool SupportArmy(UnitCommander commander, Point2D target, Point2D defensivePoint, Point2D groupCenter, int frame, out List <SC2APIProtocol.Action> action, IEnumerable <UnitCalculation> supportableUnits = null)
        {
            action = null;

            UpdateLoadTimes(commander);

            if (commander.UnitCalculation.Unit.Shield < commander.UnitCalculation.Unit.ShieldMax / 2)
            {
                if (AvoidTargettedDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (AvoidDamage(commander, target, defensivePoint, frame, out action))
                {
                    return(true);
                }

                if (commander.UnitCalculation.Unit.Shield < 1)
                {
                    if (Retreat(commander, target, defensivePoint, frame, out action))
                    {
                        return(true);
                    }
                }
            }

            // follow behind at the range of pickup
            var unitToSupport = GetSupportTarget(commander, target, defensivePoint, supportableUnits);

            if (unitToSupport == null)
            {
                return(false);
            }

            if (!commander.UnitCalculation.NearbyAllies.Any(a => a.Unit.Tag == unitToSupport.Unit.Tag))
            {
                if (Vector2.DistanceSquared(commander.UnitCalculation.Position, new Vector2(target.X, target.Y)) > Vector2.DistanceSquared(unitToSupport.Position, new Vector2(target.X, target.Y)))
                {
                    if (NavigateToSupportUnit(commander, target, frame, out action))
                    {
                        return(true);
                    }
                }
            }

            if (UnloadUnits(commander, defensivePoint, frame, out action))
            {
                return(true);
            }

            var moveTo = GetPickupSpot(new Point2D {
                X = unitToSupport.Unit.Pos.X, Y = unitToSupport.Unit.Pos.Y
            }, defensivePoint);

            if (commander.UnitCalculation.Unit.Orders.Any(o => o.AbilityId == (uint)Abilities.UNLOADALLAT_WARPPRISM || o.AbilityId == (uint)Abilities.UNLOADUNIT_WARPPRISM) || !MapDataService.PathWalkable(moveTo)) // TODO: does this groundpathable thing work right?
            {
                moveTo = new Point2D {
                    X = unitToSupport.Unit.Pos.X, Y = unitToSupport.Unit.Pos.Y
                };
            }

            if (InRange(new Vector2(moveTo.X, moveTo.Y), commander.UnitCalculation.Position, 2) && InRange(unitToSupport.Position, commander.UnitCalculation.Position, PickupRange))
            {
                //look at all units within pickup range, ordered by proximity to their closeest enemy
                // get average hp + shields of back
                // if unit is in front half weapon is off cooldown and (has below that hp + shields or could die in one hit) pick it up
                var friendliesInRange = commander.UnitCalculation.NearbyAllies.Where(u => !commander.UnitCalculation.Unit.Passengers.Any(p => p.Tag == u.Unit.Tag) && InRange(u.Position, commander.UnitCalculation.Position, PickupRange)).OrderBy(u => ClosestEnemyDistance(u));
                var frontHalf         = friendliesInRange.Take(friendliesInRange.Count() / 2);
                var backHalf          = friendliesInRange.Skip(friendliesInRange.Count() / 2);
                var backAverageHealth = backHalf.Sum(u => u.Unit.Health + u.Unit.Shield) / backHalf.Count();
                foreach (var friendly in frontHalf)
                {
                    if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                    {
                        if (ShouldLoadUnit(friendly, backAverageHealth, frame))
                        {
                            action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                            return(true);
                        }
                    }
                }

                if (friendliesInRange.Count() < 4)
                {
                    foreach (var friendly in friendliesInRange)
                    {
                        if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                        {
                            if (ShouldLoadUnit(friendly, friendly.Unit.Health + (friendly.Unit.ShieldMax / 2), frame))
                            {
                                if (friendly.Unit.WeaponCooldown > 0 && friendly.Unit.Shield < friendly.Unit.ShieldMax / 2)
                                {
                                    action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                                    return(true);
                                }
                            }
                        }
                    }
                }

                foreach (var friendly in friendliesInRange.Where(f => f.EnemiesInRangeOf.Count() > 0 && f.Range > 2).OrderBy(f => f.Unit.Shield).ThenBy(f => f.Unit.Health))
                {
                    if (commander.UnitCalculation.Unit.CargoSpaceMax - commander.UnitCalculation.Unit.CargoSpaceTaken >= UnitDataService.CargoSize((UnitTypes)friendly.Unit.UnitType))
                    {
                        if (friendly.Unit.WeaponCooldown > 0)
                        {
                            action = commander.Order(frame, Abilities.LOAD, null, friendly.Unit.Tag);
                            return(true);
                        }
                    }
                }

                StartWarping(commander, frame, out action);
                return(true);
            }
            else
            {
                // move to pickup the friendly closest to the enemy
                if (StopWarping(commander, frame, out action))
                {
                    return(true);
                }

                action = commander.Order(frame, Abilities.MOVE, moveTo);
                return(true);
            }
        }
Beispiel #33
0
        UnitCalculation GetBestHarassTarget(UnitCommander commander, Point2D target)
        {
            var existingAttackOrder = commander.UnitCalculation.Unit.Orders.Where(o => o.AbilityId == (uint)Abilities.ATTACK || o.AbilityId == (uint)Abilities.ATTACK_ATTACK).FirstOrDefault();

            var range = commander.UnitCalculation.Range;

            var attacks = new List <UnitCalculation>(commander.UnitCalculation.EnemiesInRange.Where(u => u.Unit.DisplayType != DisplayType.Hidden && u.UnitClassifications.Contains(UnitClassification.Worker))); // units that are in range right now

            UnitCalculation bestAttack = null;

            if (attacks.Count > 0)
            {
                var oneShotKills = attacks.Where(a => a.Unit.Health + a.Unit.Shield < GetDamage(commander.UnitCalculation.Weapon, a.Unit, a.UnitTypeData));
                if (oneShotKills.Count() > 0)
                {
                    if (existingAttackOrder != null)
                    {
                        var existing = oneShotKills.FirstOrDefault(o => o.Unit.Tag == existingAttackOrder.TargetUnitTag);
                        if (existing != null)
                        {
                            return(existing); // just keep attacking the same unit
                        }
                    }

                    var oneShotKill = GetBestTargetFromList(commander, oneShotKills, existingAttackOrder);
                    if (oneShotKill != null)
                    {
                        return(oneShotKill);
                    }
                    else
                    {
                        commander.BestTarget = oneShotKills.OrderBy(o => o.Dps).FirstOrDefault();
                        return(commander.BestTarget);
                    }
                }

                bestAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestAttack != null && bestAttack.UnitClassifications.Contains(UnitClassification.Worker) && bestAttack.EnemiesInRange.Any(e => e.Unit.Tag == commander.UnitCalculation.Unit.Tag))
                {
                    commander.BestTarget = bestAttack;
                    return(bestAttack);
                }
            }

            attacks = new List <UnitCalculation>(); // nearby units not in range right now
            foreach (var enemyAttack in commander.UnitCalculation.NearbyEnemies)
            {
                if (enemyAttack.Unit.DisplayType != DisplayType.Hidden && enemyAttack.UnitClassifications.Contains(UnitClassification.Worker) && !InRange(enemyAttack.Unit.Pos, commander.UnitCalculation.Unit.Pos, range + enemyAttack.Unit.Radius + commander.UnitCalculation.Unit.Radius))
                {
                    attacks.Add(enemyAttack);
                }
            }
            if (attacks.Count > 0)
            {
                var bestOutOfRangeAttack = GetBestTargetFromList(commander, attacks, existingAttackOrder);
                if (bestOutOfRangeAttack != null && (bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.ArmyUnit) || bestOutOfRangeAttack.UnitClassifications.Contains(UnitClassification.DefensiveStructure)))
                {
                    commander.BestTarget = bestOutOfRangeAttack;
                    return(bestOutOfRangeAttack);
                }
                if (bestAttack == null)
                {
                    bestAttack = bestOutOfRangeAttack;
                }
            }

            commander.BestTarget = bestAttack;
            return(bestAttack);
        }
Beispiel #34
0
 // TODO: when retreating cancel prismatic alignment
 protected override bool WeaponReady(UnitCommander commander)
 {
     return(true);
 }
 public override List <SC2APIProtocol.Action> Retreat(UnitCommander commander, Point2D defensivePoint, Point2D groupCenter, int frame)
 {
     return(Attack(commander, defensivePoint, defensivePoint, groupCenter, frame));
 }
 protected override bool WeaponReady(UnitCommander commander)
 {
     return(commander.UnitCalculation.Unit.WeaponCooldown < 5 || commander.UnitCalculation.Unit.WeaponCooldown > 15); // a zealot has 2 attacks, so we do this because after one attack the cooldown starts over instead of both
 }
Beispiel #37
0
 public LevelManagement(ICommanderFactory factory)
 {
     _enemyUnits  = factory.CreateEnemyCommander();
     _playerUnits = factory.CreatePlayerCommander();
 }