Exemple #1
0
        private bool ProduceAddOn(ProductionOrder order)
        {
            var Structure2x2 = unitTypeRepository.Get(BlizzardConstants.Unit.SupplyDepot); // Use as add-on substitute, as add-ons have a size of 8!
            var ids          = techTree.GetProducersID(order.Unit);
            var targets      = intelManager.StructuresSelf(ids).Where(b =>
                                                                      b.AddOnTag == 0 &&
                                                                      b.BuildProgress == 1f &&
                                                                      b.Orders.Count == 0);
            var target = targets.FirstOrDefault(b => intelManager.GameMap.ValidPlacement(Structure2x2, new Point2D {
                X = b.Pos.X + 2.5f, Y = b.Pos.Y - 0.5f
            }));

            if (target == null && targets.Count() != 0)
            {
                return(LiftOff(order, targets.First()));
            }

            if (target == null || !ReserveRessource(order.Unit, false))
            {
                return(false);
            }
            order.Status       = ProductionOrder.OrderStatus.Commissioned;
            order.AssignedUnit = target;
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, order.AssignedUnit.Tag));
            target.Orders.Add(new UnitOrder {
            });
            return(true);
        }
Exemple #2
0
        private void QueueOrderInFront(ProductionOrder order)
        {
#if DEBUG
            if (order.Unit != null && order.Unit.Race != GameConstants.ParticipantRace)
            {
                log.LogError($"ProductionManager: {order.Unit.Name} is a {order.Unit.Race} unit, playing as {GameConstants.ParticipantRace}!");
                return;
            }
#else
            if (order.Unit != null && order.Unit.Race != GameConstants.ParticipantRace)
            {
                return;
            }
#endif
            var requirements = new List <ProductionOrder>();
            AddRequirementsToList(requirements, order, order.LowPriority);
            lock (_orders) {
                for (int i = 0; i < requirements.Count; i++)
                {
                    if (GetOrderOfType(_orders, requirements[i], out var moved))
                    {
#if DEBUG
                        log.LogWarning($"\t(Important {order.Unit?.Name}{order.Research?.Name}) => Prioritized {moved.Unit?.Name}{order.Research?.Name} from existing queue.");
#endif
                        _orders.Remove(moved);
                        requirements[i] = moved;
                    }
                }
                var copy = _orders.ToList(); // Clone
                _orders.Clear();
                requirements.ForEach(r => _orders.Add(r));
                _orders.Add(order);
                copy.ForEach(c => _orders.Add(c));
            }
        }
Exemple #3
0
        private bool HasRequirements(ProductionOrder order)
        {
            if (order.RequiredAddOn != 0 && !techTree.HasUnit(order.RequiredAddOn))
            {
                return(false);
            }
            if (order.Unit != null && !techTree.HasProducer(order.Unit))
            {
                return(false);
            }
            if (order.Research != null && !techTree.HasProducer(order.Research))
            {
                return(false);
            }
            var requiredBuildings = order.Unit == null ? new[] { techTree.GetProducer(order.Research) } : techTree.GetRequiredBuildings(order.Unit);

            if (requiredBuildings.Any() && !requiredBuildings.Any(b => techTree.HasUnit(b)))
            {
                return(false);
            }
            var requiredResearch = order.Research == null ? null : techTree.GetRequiredResearch(order.Research);

            if (requiredResearch != null && !techTree.HasResearch(requiredResearch))
            {
                return(false);
            }
            return(true);
        }
Exemple #4
0
        private bool ProducedMorphed(ProductionOrder order)
        {
            IUnit target = null;
            var   ids    = techTree.GetProducersID(order.Unit);

            if (IsStructure(ids.First()))
            {
                target = intelManager.StructuresSelf(ids).FirstOrDefault(u => u.Orders.Count == 0);
            }
            else
            {
                target = intelManager.UnitsSelf(ids).FirstOrDefault(u => u.Orders.Count == 0);
            }
            if (target == null || !ReserveRessource(order.Unit, false))
            {
                return(false);
            }
            ;
            target.Orders.Add(new UnitOrder {
            });
            if (target.UnitType == BlizzardConstants.Unit.Larva)
            {
                order.Status = ProductionOrder.OrderStatus.Commissioned;
            }
            else
            {
                order.Status      = ProductionOrder.OrderStatus.Producing;
                order.OrderedUnit = target;
            }
            order.AssignedUnit = target;
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, order.AssignedUnit.Tag));
            return(true);
        }
Exemple #5
0
        private bool ProduceBuilding(ProductionOrder order)
        {
            IPosition targetPosition;

            if (order.Position != null && intelManager.GameMap.ValidPlacement(order.Unit, order.Position, order.Spacing))
            {
                targetPosition = order;
            }
            else
            {
                targetPosition = intelManager.GameMap.FindPlacement(order.Unit, order.Position ?? intelManager.PrimaryColony.Point, order.Spacing);
            }
            var worker = GetWorker(targetPosition);

            if (worker == null || targetPosition == null)
            {
                return(false);
            }
            if (!ReserveRessource(order.Unit))
            {
                return(false);
            }
            order.Status       = ProductionOrder.OrderStatus.Commissioned;
            order.AssignedUnit = worker;
            intelManager.GameMap.Reserve(order.Unit, targetPosition.Point);
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, worker.Tag, targetPosition.Point));
            return(true);
        }
Exemple #6
0
        private bool ProduceVespene(ProductionOrder order)
        {
            var colony     = order.Position == null ? intelManager.PrimaryColony : order.Position.GetClosest(intelManager.Colonies);
            var refineries = colony.Structures.Where(b => GameConstants.IsVespeneGeyserBuilding(b.UnitType));
            var target     = colony.Vespene.FirstOrDefault(v => !refineries.Any(r => r.Pos.X == v.Pos.X && r.Pos.Y == v.Pos.Y));
            var worker     = GetWorker(target);

#if DEBUG
            if (target == null)
            {
                log.LogError($"ProductionManager: No available vespene geyser for {order.Unit.Name} at colony {colony.Id}");
                return(false);
            }
            if (worker == null)
            {
                log.LogWarning($"ProductionManager: No worker found for {order.Unit.Name}");
                return(false);
            }
            if (!ReserveRessource(order.Unit))
            {
                return(false);
            }
#else
            if (target == null || worker == null || !ReserveRessource(order.Unit))
            {
                return(false);
            }
#endif
            order.Status       = ProductionOrder.OrderStatus.Commissioned;
            order.AssignedUnit = worker;
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, worker.Tag, target.Tag));
            return(true);
        }
Exemple #7
0
 private bool GetOrderOfType(List <ProductionOrder> orders, ProductionOrder order, out ProductionOrder moved)
 {
     if (order.Type == ProductionOrder.BuildType.Research)
     {
         moved = orders.Where(o => o.Research?.UpgradeId == order.Research.UpgradeId).FirstOrDefault();
     }
     else
     {
         moved = orders.Where(o => o.Unit?.UnitId == order.Unit.UnitId).FirstOrDefault();
     }
     return(moved != null);
 }
Exemple #8
0
        private bool ResearchUpgrade(ProductionOrder order)
        {
            IUnit target = intelManager.StructuresSelf(techTree.GetProducer(order.Research).UnitId).FirstOrDefault(b => b.BuildProgress == 1f && b.Orders.Count == 0);

            if (target == null || !ReserveRessource(order.Research))
            {
                return(false);
            }
            order.Status = ProductionOrder.OrderStatus.Built; //TODO: Not built... producing
            rawManager.QueueActions(RawCommand(order.Research.AbilityId, target.Tag));
            return(true);
        }
Exemple #9
0
        private void QueueOrder(ProductionOrder order)
        {
#if DEBUG
            if (order.Unit != null && order.Unit.Race != GameConstants.ParticipantRace)
            {
                log.LogError($"ProductionManager: {order.Unit.Name} is a {order.Unit.Race} unit, playing as {GameConstants.ParticipantRace}!");
                return;
            }
#else
            if (order.Unit != null && order.Unit.Race != GameConstants.ParticipantRace)
            {
                return;
            }
#endif
            lock (_orders) {
                AddRequirementsToList(_orders, order, order.LowPriority);
                _orders.Add(order);
            }
        }
Exemple #10
0
        private bool CanAfford(ProductionOrder order)
        {
            if (order.Unit?.FoodRequired != 0 && order.Unit?.FoodRequired > currentRessources.Supply)
            {
                return(false);
            }
            var minerals = order.Unit == null ? order.Research.MineralCost : order.Unit.MineralCost;

            if (minerals != 0 && minerals > currentRessources.Minerals)
            {
                return(false);
            }
            var vespene = order.Unit == null ? order.Research.VespeneCost : order.Unit.VespeneCost;

            if (vespene != 0 && vespene > currentRessources.Vespene)
            {
                return(false);
            }
            return(true);
        }
Exemple #11
0
        private bool Produce(ProductionOrder order)
        {
            if (!CanAfford(order))
            {
                return(false);
            }
            if (!HasRequirements(order))
            {
                return(false);
            }
            switch (order.Type)
            {
            case ProductionOrder.BuildType.Structure:
                if (order.Unit.UnitId == GameConstants.RaceRefinery)
                {
                    return(ProduceVespene(order));
                }
                else
                {
                    return(ProduceBuilding(order));
                }

            case ProductionOrder.BuildType.Unit:
                return(ProduceUnit(order));

            case ProductionOrder.BuildType.Morphed:
                return(ProducedMorphed(order));

            case ProductionOrder.BuildType.AddOn:
                return(ProduceAddOn(order));

            case ProductionOrder.BuildType.Research:
                return(ResearchUpgrade(order));

            default:
                throw new System.NotImplementedException();
            }
        }
Exemple #12
0
        private bool LiftOff(ProductionOrder order, IUnit target)
        {
            var position = intelManager.GameMap.FindPlacementWithAddOn(target.Point);

            if (position == null || !ReserveRessource(order.Unit, false))
            {
                return(false);
            }
#if DEBUG
            log.LogWarning($"ProductionManager: Relocating {target.Tag} to X:{position.Point.X} Y:{position.Point.Y} ({order.Unit.Name})");
#endif
            order.Status       = ProductionOrder.OrderStatus.Commissioned;
            order.AssignedUnit = target;
            var Structure2x2 = unitTypeRepository.Get(BlizzardConstants.Unit.SupplyDepot); // Use as add-on substitute, as add-ons have a size of 8!
            intelManager.GameMap.Reserve(order.Unit, position.Point);
            intelManager.GameMap.Reserve(Structure2x2, new Point2D {
                X = position.Point.X + 2.5f, Y = position.Point.Y - 0.5f
            });
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, order.AssignedUnit.Tag, position.Point));
            target.Orders.Add(new UnitOrder {
            });
            return(true);
        }
Exemple #13
0
        private bool ProduceUnit(ProductionOrder order)
        {
            var   ids      = techTree.GetProducersID(order.Unit);
            IUnit producer = null;

            if (GameConstants.RequiresTechLab(order.Unit.UnitId))
            {
                producer = intelManager.StructuresSelf(ids).FirstOrDefault(b => b.AddOnTag != 0 && b.Orders.Count == 0 && GameConstants.IsTechLab(GetBuilding(b.AddOnTag).UnitType));
            }
            else
            {
                producer = intelManager.StructuresSelf(ids).FirstOrDefault(b => b.BuildProgress == 1f && ((b.Orders.Count == 0) ||
                                                                                                          (b.AddOnTag != 0 && GameConstants.IsReactor(GetBuilding(b.AddOnTag).UnitType) && b.Orders.Count < 2 && !GameConstants.IsReactorAbility(b.Orders.First().AbilityId))));
            }
            if (producer == null || !ReserveRessource(order.Unit, false))
            {
                return(false);
            }
            producer.Orders.Add(new UnitOrder()); // Fake order to prevent adding multiple units in same game loop
            order.Status = ProductionOrder.OrderStatus.Commissioned;
            rawManager.QueueActions(RawCommand(order.Unit.AbilityId, producer.Tag));
            return(true);
        }
Exemple #14
0
        private List <ProductionOrder> AddRequirementsToList(List <ProductionOrder> queue, ProductionOrder order, bool canSkip)
        {
            var requiredUnits = new List <UnitTypeData>();
            var requiredTech  = new List <UpgradeData>();

            if (order.Type == ProductionOrder.BuildType.Research)
            {
                var tech = techTree.GetRequiredResearch(order.Research);
                if (tech != null && !techTree.HasResearch(tech) && !IsQueued(queue, tech))
                {
                    requiredTech.Add(tech);
                }
                var unit = techTree.GetProducer(order.Research);
                if (unit != null && !techTree.HasUnit(unit) && !IsQueued(queue, unit))
                {
                    requiredUnits.Add(unit);
                }
                unit = techTree.GetRequiredBuilding(order.Research);
                if (unit != null && !techTree.HasUnit(unit) && !IsQueued(queue, unit))
                {
                    requiredUnits.Add(unit);
                }
            }
            else
            {
                var units = techTree.GetProducers(order.Unit);
                if (units.Any() && !units.Any(unit => techTree.HasUnit(unit) || IsQueued(queue, unit)))
                {
                    requiredUnits.Add(units.First());
                }
                units = techTree.GetRequiredBuildings(order.Unit);
                if (units.Any() && !units.Any(unit => techTree.HasUnit(unit) || IsQueued(queue, unit)))
                {
                    requiredUnits.Add(units.First());
                }
                if (order.RequiredAddOn != 0 && !(techTree.HasUnit(order.RequiredAddOn) || IsUnitQueued(queue, order.RequiredAddOn)))
                {
                    requiredUnits.Add(unitTypeRepository.Get(order.RequiredAddOn));
                }
            }
            if (requiredUnits.Count == 0 && requiredTech.Count == 0)
            {
                return(queue);
            }
#if DEBUG
            log.LogWarning($"ProductionManager: The queued {order.Unit?.Name}{order.Research?.Name} have unmet requirements - adding them to queue:");
#endif
            requiredUnits.ForEach(u => {
#if DEBUG
                log.LogWarning($"\t{order.Unit?.Name}{order.Research?.Name} => {u.Name} (Structure/Unit)");
#endif
                QueueRequirementsUnit(queue, u, canSkip, "\t\t");
            });
            requiredTech.ForEach(t => {
#if DEBUG
                log.LogWarning($"\t{order.Unit?.Name}{order.Research?.Name} => {t.Name} (Research)");
#endif
                QueueRequirementsTechnology(queue, t, canSkip, "\t\t");
            });
            return(queue);
        }