예제 #1
0
        private void QueueRequirementsUnit(List <ProductionOrder> queue, UnitTypeData unit, bool canSkip, string prefix = "\t")
        {
            if (RefineryNeeded(queue, unit))
            {
#if DEBUG
                log.LogWarning($"{prefix}{unit.Name} => Refinery/Assimilator/Extractor ({unit.VespeneCost} vespene cost, no production)");
#endif
                QueueRequirementsUnit(queue, unitTypeRepository.Get(GameConstants.RaceRefinery), canSkip, prefix + "\t");
            }

            var requiredProducers = techTree.GetProducers(unit);
            if (requiredProducers.Any() && !requiredProducers.Any(r => techTree.HasUnit(r) || IsQueued(queue, r)))
            {
#if DEBUG
                log.LogWarning($"{prefix}{unit.Name} => {requiredProducers.First().Name} (Producer)");
#endif
                QueueRequirementsUnit(queue, requiredProducers.First(), canSkip, prefix + "\t");
            }

            var requiredBuildings = techTree.GetRequiredBuildings(unit);
            if (requiredBuildings.Any() && !requiredBuildings.Any(r => techTree.HasUnit(r) || IsQueued(queue, r)))
            {
#if DEBUG
                log.LogWarning($"{prefix}{unit.Name} => {requiredBuildings.First().Name} (Producer)");
#endif
                QueueRequirementsUnit(queue, requiredBuildings.First(), canSkip, prefix + "\t");
            }

            queue.Add(new ProductionOrder {
                Unit = unit, LowPriority = canSkip
            });
        }
예제 #2
0
        public Unit(SC2APIProtocol.Unit unit)
        {
            this.original     = unit;
            this.unitTypeData = ControllerDefault.gameData.Units[(int)unit.UnitType];

            this.name            = unitTypeData.Name;
            this.tag             = unit.Tag;
            this.unitType        = unit.UnitType;
            this.position        = new Vector3(unit.Pos.X, unit.Pos.Y, unit.Pos.Z);
            this.integrity       = (unit.Health + unit.Shield) / (unit.HealthMax + unit.ShieldMax);
            this.buildProgress   = unit.BuildProgress;
            this.idealWorkers    = unit.IdealHarvesters;
            this.assignedWorkers = unit.AssignedHarvesters;

            this.order     = unit.Orders.Count > 0 ? unit.Orders[0] : new UnitOrder();
            this.orders    = unit.Orders;
            this.isVisible = (unit.DisplayType == DisplayType.Visible);

            this.supply = (int)unitTypeData.FoodRequired;

            this.vespene  = unit.VespeneContents;
            this.minerals = unit.MineralContents;
            this.sight    = this.unitTypeData.SightRange;
            this.target   = unit.EngagedTargetTag;
        }
예제 #3
0
    public UnitTypeData(UnitTypeData other)
    {
        id         = other.id;
        name       = other.name;
        spells     = null;
        attacks    = null;
        defense    = other.defense;
        armor      = other.armor;
        shield     = other.shield;
        health     = other.health;
        cost       = other.cost;
        hero       = other.hero;
        holy       = other.holy;
        spellLikes = null;

        if (other.spells != null)
        {
            spells = new int[other.spells.Length];
            Array.Copy(other.spells, spells, spells.Length);
        }

        if (other.attacks != null)
        {
            attacks = new AttackData[other.attacks.Length];
            Array.Copy(other.attacks, attacks, attacks.Length);
        }

        if (other.spellLikes != null)
        {
            spellLikes = new int[other.spellLikes.Length];
            Array.Copy(other.spellLikes, spellLikes, spellLikes.Length);
        }
    }
예제 #4
0
 public IEnumerable <UnitTypeData> GetProducers(UnitTypeData unit)
 {
     if (Unit_To_Producers.TryGetValue(unit.UnitId, out var ids))
     {
         return(ids.Select(i => unitTypeRepository.Get(i)));
     }
     throw new System.NotImplementedException();
 }
예제 #5
0
 public IEnumerable <UnitTypeData> GetRequiredBuildings(UnitTypeData unit)
 {
     if (Unit_To_RequiredBuildings.TryGetValue(unit.UnitId, out var ids))
     {
         return(ids.Select(i => unitTypeRepository.Get(i)));
     }
     return(Enumerable.Empty <UnitTypeData>());
 }
예제 #6
0
 public uint GetProducer(UnitTypeData unit)
 {
     if (Unit_To_Producers.TryGetValue(unit.UnitId, out var ids))
     {
         return(ids[0]);
     }
     throw new System.NotImplementedException();
 }
예제 #7
0
        private IPosition FindPlacement(float xPosition, float yPosition, UnitTypeData structure, float spacing = 0.0f)
        {
            var r = FootprintRadius(structure) + spacing;
            var d = (int)(r * 2);

            AlignCoordinates(d, ref xPosition, ref yPosition);

            bool rCreep    = structure.Race == Race.Zerg && structure.UnitId != BlizzardConstants.Unit.Hatchery;
            bool rPower    = structure.Race == Race.Protoss && structure.UnitId != BlizzardConstants.Unit.Nexus && structure.UnitId != BlizzardConstants.Unit.Pylon;
            bool aCreep    = structure.Race != Race.Zerg;
            bool aNaturals = GameConstants.IsHeadquarter(structure.UnitId);

            if (ValidPlacement((int)(xPosition - r), (int)(yPosition - r), d, rCreep, rPower, aCreep, aNaturals))
            {
                return(new Position(xPosition, yPosition));
            }

            bool b = true;

            for (int count = 1; count < 50; count++)
            {
                // Move vertical
                for (int i = 0; i < count; i++)
                {
                    if (b)
                    {
                        yPosition++;
                    }
                    else
                    {
                        yPosition--;
                    }
                    if (ValidPlacement((int)(xPosition - r), (int)(yPosition - r), d, rCreep, rPower, aCreep, aNaturals))
                    {
                        return(new Position(xPosition, yPosition));
                    }
                }
                // Move horizontal
                for (int i = 0; i < count; i++)
                {
                    if (b)
                    {
                        xPosition--;
                    }
                    else
                    {
                        xPosition++;
                    }
                    if (ValidPlacement((int)(xPosition - r), (int)(yPosition - r), d, rCreep, rPower, aCreep, aNaturals))
                    {
                        return(new Position(xPosition, yPosition));
                    }
                }
                // Change direction
                b = !b;
            }
            return(null);
        }
예제 #8
0
        /// <summary>
        ///     Checks if there is enough supply to build a unit.
        /// </summary>
        /// <param name="unitType">the unit type of the desired unit</param>
        /// <returns>true if supply is available, false otherwise</returns>
        public static bool CheckSupply(uint unitType)
        {
            UnitTypeData unitData = VBot.Bot.Data.Units[(int)unitType];

            if (VBot.Bot.AvailableSupply() >= unitData.FoodRequired)
            {
                return(true);
            }
            return(false);
        }
예제 #9
0
 public bool HasProducer(UnitTypeData unit)
 {
     foreach (var id in GetProducersID(unit))
     {
         if (HasUnit(id))
         {
             return(true);
         }
     }
     return(false);
 }
        private float GetPurificationNovaDamage(Unit unit, UnitTypeData unitTypeData)
        {
            float bonusDamage = 0;

            if (unit.Shield > 0)
            {
                bonusDamage = 55;
            }

            return(145 + bonusDamage - unitTypeData.Armor); // TODO: armor upgrades
        }
예제 #11
0
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="other">The unit type to clone</param>
 public UnitType(UnitType other)
 {
     _data    = new UnitTypeData(other._data);
     _attacks = new List <Attack>();
     // attacks can't be shared - they may get different qualities
     for (int i = 0; i < other._attacks.Count; i++)
     {
         _attacks.Add(new Attack(other._attacks[i].GetData()));
     }
     // spells and spell-like abilities can be shared (for now)
     _spells             = new List <Spell>(other._spells);
     _spellLikeAbilities = new List <Spell>(other._spellLikeAbilities);
 }
예제 #12
0
        bool IGameMap.ValidPlacement(UnitTypeData structure, Point2D point, int spacing) //TODO: Improve to avoid code duplication
        {
            var r = FootprintRadius(structure) + spacing;
            var d = (int)(r * 2);
            var x = point.X;
            var y = point.Y;

            AlignCoordinates(d, ref x, ref y);
            bool rCreep = structure.Race == Race.Zerg && structure.UnitId != BlizzardConstants.Unit.Hatchery;
            bool rPower = structure.Race == Race.Protoss && structure.UnitId != BlizzardConstants.Unit.Nexus && structure.UnitId != BlizzardConstants.Unit.Pylon;
            bool aCreep = structure.Race != Race.Zerg;

            return(ValidPlacement((int)(x - r), (int)(y - r), d, rCreep, rPower, aCreep));
        }
예제 #13
0
        public static CombatUnit FromUnit(Unit unit, List <CombatMicro.CombatMicro> combatMicro, HashSet <uint> upgrades)
        {
            CombatUnit result = new CombatUnit();

            UnitTypeData unitType = UnitTypes.LookUp[unit.UnitType];

            result.Health            = unit.Health;
            result.HealthMax         = (int)unit.HealthMax;
            result.Shield            = unit.Shield;
            result.ShieldMax         = (int)unit.ShieldMax;
            result.Energy            = unit.Energy;
            result.EnergyMax         = (int)unit.EnergyMax;
            result.BaseMovementSpeed = unitType.MovementSpeed;
            result.MovementSpeed     = unitType.MovementSpeed;
            result.IsAir             = unit.IsFlying || unit.UnitType == UnitTypes.COLOSUS;
            result.IsGround          = !unit.IsFlying || unit.UnitType == UnitTypes.COLOSUS;
            result.Armor             = (int)unitType.Armor;
            result.Owner             = unit.Owner == Bot.Main.PlayerId ? 1 : 2;
            result.Pos      = new Point(unit.Pos.X, unit.Pos.Y);
            result.Tag      = (long)unit.Tag;
            result.UnitType = unit.UnitType;
            foreach (Weapon weapon in unitType.Weapons)
            {
                result.Weapons.Add(FromWeapon(weapon));
            }
            foreach (SC2APIProtocol.Attribute attribute in unitType.Attributes)
            {
                result.Attributes.Add(FromAttribute(attribute));
            }
            result.CombatMicros = combatMicro;

            if (unit.UnitType == UnitTypes.ZEALOT && upgrades.Contains(UpgradeType.Charge))
            {
                result.ActionProcessors.Add(new ZealotChargeProcessor());
                result.BaseMovementSpeed = 2.95f;
                result.MovementSpeed     = 2.95f;
            }
            else if (unit.UnitType == UnitTypes.MARAUDER && upgrades.Contains(UpgradeType.ConcussiveShells))
            {
                result.ActionProcessors.Add(new ConcussiveShellsProcessor());
            }
            else if (unit.UnitType == UnitTypes.IMMORTAL)
            {
                result.DamageProcessors.Add(new BarrierDamageProcessor());
            }

            return(result);
        }
예제 #14
0
        /// <summary>
        ///     Checks if there is enough minerals and gas to build a unit or structure.
        /// </summary>
        /// <param name="unitType">the unit type of the desired unit</param>
        /// <returns>true if resources are available, false otherwise</returns>
        public static bool CanAffordUnit(uint unitType)
        {
            UnitTypeData unitData = VBot.Bot.Data.Units[(int)unitType];

            if (Units.ZergStructures.Contains(unitType))
            {
                if (VBot.Bot.Minerals() >= (unitData.MineralCost - 50) && VBot.Bot.Gas() >= unitData.VespeneCost)
                {
                    return(true);
                }
            }
            if (VBot.Bot.Minerals() >= unitData.MineralCost && VBot.Bot.Gas() >= unitData.VespeneCost)
            {
                return(true);
            }
            return(false);
        }
예제 #15
0
 /// <summary>
 /// Class constructor
 /// </summary>
 /// <param name="data">Serialized unit type data</param>
 /// <param name="spells">Hash of spell id => spell</param>
 public UnitType(UnitTypeData data, Dictionary <Game.SpellId, Spell> spells)
 {
     _data    = data;
     _attacks = new List <Attack>();
     if (data.attacks != null)
     {
         for (int i = 0; i < data.attacks.Length; i++)
         {
             _attacks.Add(new Attack(data.attacks[i]));
         }
     }
     _spells = new List <Spell>();
     if (data.spells != null)
     {
         for (int i = 0; i < data.spells.Length; i++)
         {
             _spells.Add(spells[(Game.SpellId)data.spells[i]]);
         }
     }
     RegisterUnitType(this);
 }
예제 #16
0
    void Start()
    {
        _unitTypesConfig = GameConfig.Get <UnitTypesConfig>();
        _unit            = _unitTypesConfig[UnitTypeIndex];
        GameModel.HandleGet <HexModel>(OnHexModelChange);

        Button.onClick.AddListener(OnButtonClick);

        Name.text = _unit.Name;
        Body.SetValue(_unit.Body);
        Mind.SetValue(_unit.Mind);
        Soul.SetValue(_unit.Soul);

        ResistanceTemperature.SetPosition(_unit.Temperature);
        ResistancePressure.SetPosition(_unit.Pressure);
        ResistanceHumidity.SetPosition(_unit.Humidity);
        ResistanceRadiation.SetPosition(_unit.Radiation);

        UIPropertyView currentEffect = Effect1;

        if (_unit.ITemperature != 0)
        {
            SetEffectValue(currentEffect, R.Temperature);
            currentEffect = Effect2;
        }
        if (_unit.IPressure != 0)
        {
            SetEffectValue(currentEffect, R.Pressure);
            currentEffect = Effect2;
        }
        if (_unit.IHumidity != 0)
        {
            SetEffectValue(currentEffect, R.Humidity);
            currentEffect = Effect2;
        }
        if (_unit.IRadiation != 0)
        {
            SetEffectValue(currentEffect, R.Radiation);
        }
    }
예제 #17
0
        public Unit(SC2APIProtocol.Unit unit, UnitTypeData unitTypeData)
        {
            this.Original     = unit;
            this.UnitTypeData = unitTypeData;

            this.Name            = UnitTypeData.Name;
            this.Tag             = unit.Tag;
            this.UnitType        = unit.UnitType;
            this.Position        = new Vector3(unit.Pos.X, unit.Pos.Y, unit.Pos.Z);
            this.Integrity       = (unit.Health + unit.Shield) / (unit.HealthMax + unit.ShieldMax);
            this.BuildProgress   = unit.BuildProgress;
            this.IdealWorkers    = unit.IdealHarvesters;
            this.AssignedWorkers = unit.AssignedHarvesters;

            this.Order     = unit.Orders.Count > 0 ? unit.Orders[0] : new UnitOrder();
            this.Orders    = unit.Orders;
            this.IsVisible = (unit.DisplayType == DisplayType.Visible);

            this.Supply     = (int)UnitTypeData.FoodRequired;
            this.Energy     = (int)unit.Energy;
            this.Energy     = (int)unit.EnergyMax;
            this.IsInjected = unit.BuffIds.Contains(Buffs.QUEENSPAWNLARVATIMER);
            this.Alliance   = unit.Alliance;
        }
예제 #18
0
 IPosition IGameMap.FindPlacement(UnitTypeData structure, Point2D point, int spacing) => FindPlacement(point.X, point.Y, structure, spacing);
예제 #19
0
 private bool RefineryNeeded(IEnumerable <ProductionOrder> queue, UnitTypeData unit) => unit.VespeneCost != 0 && RefineryNeeded(queue);
예제 #20
0
 private bool IsQueued(IEnumerable <ProductionOrder> queue, UnitTypeData unit) => IsUnitQueued(queue, unit.UnitId);
예제 #21
0
 private void QueueUnitImportant(UnitTypeData unit, Point2D position, int spacing) => QueueOrderInFront(new ProductionOrder {
     Unit = unit, Position = position, LowPriority = false, Spacing = spacing
 });
예제 #22
0
 private void QueueUnit(UnitTypeData unit, Point2D position, int spacing, bool lowPriority) => QueueOrder(new ProductionOrder {
     Unit = unit, Position = position, LowPriority = lowPriority, Spacing = spacing
 });
예제 #23
0
 public bool HasUnit(UnitTypeData unit) => unit == null || HasUnit(unit.UnitId);
예제 #24
0
 void IProductionManager.QueueUnit(UnitTypeData unit, Point2D desiredPosition, int spacing, bool lowPriority)
 => QueueUnit(unit, desiredPosition, spacing, lowPriority);
예제 #25
0
 void IProductionManager.QueueUnitImportant(UnitTypeData unit, Point2D desiredPosition, int spacing)
 => QueueUnitImportant(unit, desiredPosition, spacing);
예제 #26
0
        public override void OnFrame(Bot bot)
        {
            foreach (Agent agent in Units)
            {
                if (!ParasitedFrame.ContainsKey(agent.Unit.Tag))
                {
                    ParasitedFrame.Add(agent.Unit.Tag, bot.Frame);
                }

                if (bot.Frame - ParasitedFrame[agent.Unit.Tag] == 1)
                {
                    agent.Order(Abilities.CANCEL);
                    continue;
                }

                if (bot.Frame - ParasitedFrame[agent.Unit.Tag] == 5)
                {
                    Unit target = null;
                    int  value  = 0;
                    foreach (Unit enemy in bot.Enemies())
                    {
                        if (!UnitTypes.LookUp.ContainsKey(enemy.UnitType))
                        {
                            continue;
                        }

                        UnitTypeData data   = UnitTypes.LookUp[enemy.UnitType];
                        int          newVal = (int)data.MineralCost + (int)data.VespeneCost;
                        if (newVal > value)
                        {
                            target = enemy;
                            value  = newVal;
                        }
                    }
                    if (target != null)
                    {
                        agent.Order(401, target.Tag);
                    }
                    continue;
                }

                if (bot.Frame - ParasitedFrame[agent.Unit.Tag] == 180)
                {
                    bool jumped = false;
                    foreach (Agent airAttacker in bot.UnitManager.Agents.Values)
                    {
                        if (!airAttacker.CanAttackAir() || airAttacker.Unit.UnitType == UnitTypes.INFESTOR || airAttacker.Unit.UnitType == UnitTypes.INFESTOR_BURROWED)
                        {
                            continue;
                        }
                        if (UnitTypes.LookUp[airAttacker.Unit.UnitType].Race != Race.Zerg)
                        {
                            continue;
                        }

                        int count = 0;
                        foreach (Agent airAttacker2 in bot.UnitManager.Agents.Values)
                        {
                            if (!airAttacker.CanAttackAir() || airAttacker.Unit.UnitType == UnitTypes.INFESTOR || airAttacker.Unit.UnitType == UnitTypes.INFESTOR_BURROWED)
                            {
                                continue;
                            }
                            if (UnitTypes.LookUp[airAttacker.Unit.UnitType].Race != Race.Zerg)
                            {
                                continue;
                            }
                            if (airAttacker.Unit.Tag == airAttacker2.Unit.Tag)
                            {
                                continue;
                            }
                            if (airAttacker.DistanceSq(airAttacker2) <= 8 * 8)
                            {
                                count++;
                            }
                        }
                        if (count >= 15)
                        {
                            agent.Order(2358, SC2Util.To2D(airAttacker.Unit.Pos));
                            DebugUtil.WriteLine("Jumping BC to attackers.");
                            jumped = true;
                            break;
                        }
                    }
                    if (!jumped)
                    {
                        agent.Order(2358, bot.TargetManager.PotentialEnemyStartLocations[0]);
                        DebugUtil.WriteLine("Jumping BC to enemy start location.");
                    }
                    continue;
                }
                if (bot.Frame - ParasitedFrame[agent.Unit.Tag] > 180)
                {
                    continue;
                }

                if (InfestorController.NeuralControllers.ContainsKey(agent.Unit.Tag) && bot.UnitManager.Agents.ContainsKey(InfestorController.NeuralControllers[agent.Unit.Tag]))
                {
                    agent.Order(Abilities.MOVE, SC2Util.To2D(bot.UnitManager.Agents[InfestorController.NeuralControllers[agent.Unit.Tag]].Unit.Pos));
                }
                else
                {
                    Attack(agent, bot.TargetManager.AttackTarget);
                }
            }
        }
예제 #27
0
 private void UpdateBlockedGrid(UnitTypeData unit, Point2D position, byte value) => UpdateImageGrid(FootprintRadius(unit), position.X, position.Y, value, BlockedGrid);
예제 #28
0
 private int StructureSize(UnitTypeData structure) => (int)FootprintRadius(structure) * 2;
예제 #29
0
 private float FootprintRadius(UnitTypeData structure) => abilityRepository.Get(structure.AbilityId).FootprintRadius;
예제 #30
0
 void IGameMap.Reserve(UnitTypeData structure, Point2D position) => UpdateBlockedGrid(structure, position, 1);