Example #1
0
        public StrategyResult Apply(UnitBase unit)
        {
            if (unit.Power < 5)
            {
                return(StrategyResult.NotEnoughPower);
            }

            IUnit nearestEnemyUnit = unit.Enemy != null && !unit.Enemy.IsDead ? unit.Enemy : null;
            var   minDistance      = int.MaxValue;

            if (nearestEnemyUnit == null)
            {
                foreach (var testUnit in _world.Army.GetNearbyUnits(unit, _lookupRadius))
                {
                    if (testUnit == null || testUnit.Team == unit.Team || testUnit.IsDead)
                    {
                        continue;
                    }

                    var distanceSquared = DistanceHelper.GetDistanceSquared(unit, testUnit);

                    if (distanceSquared > minDistance)
                    {
                        continue;
                    }

                    // если два врага находятся на одинаковом расстоянии, бежать к тому, у кого ХП меньше.
                    if (distanceSquared == minDistance && nearestEnemyUnit != null && nearestEnemyUnit.Health > testUnit.Health)
                    {
                        continue;
                    }

                    minDistance      = distanceSquared;
                    nearestEnemyUnit = testUnit;
                }
            }

            if (nearestEnemyUnit != null)
            {
                unit.Enemy = nearestEnemyUnit;

                var moveVector = DistanceHelper.GetMoveTowardsPoint(unit, nearestEnemyUnit.X, nearestEnemyUnit.Y);
                var cost       = unit.GetMovementCost(moveVector, _world.Terrain[unit.X, unit.Y]);

                if (unit.Power < cost)
                {
                    return(StrategyResult.NotEnoughPower);
                }

                var x = unit.X + moveVector.X;
                var y = unit.Y + moveVector.Y;

                if (!_world.IsPointWithin(x, y))
                {
                    return(StrategyResult.NotApplicable);
                }

                bool okToMove = false;
                if (_world.Army.GetUnit(y, x) != null)
                {
                    // Так, прямо по курсу какой-то хер, попробуем обойти.

                    foreach (var possibleWay in DistanceHelper.GetAdjancedDirectionVectors(moveVector))
                    {
                        cost = unit.GetMovementCost(possibleWay, _world.Terrain[unit.X, unit.Y]);

                        if (unit.Power < cost)
                        {
                            return(StrategyResult.NotEnoughPower);
                        }

                        x = unit.X + possibleWay.X;
                        y = unit.Y + possibleWay.Y;

                        if (_world.IsPointWithin(x, y) && _world.Army.GetUnit(y, x) == null)
                        {
                            okToMove = true;
                            break;
                        }
                    }
                }
                else
                {
                    okToMove = true;
                }

                if (!okToMove)
                {
                    return(StrategyResult.NotApplicable);
                }

                _world.MoveUnit(unit, y, x);

                return(StrategyResult.Applied);
            }

            return(StrategyResult.NotApplicable);
        }