public override FInt GetCostToHack(GameEntity Target, GameEntity Hacker)
        {
            //it should probably cost hacking points. It does hurt the AI.
            //Lore can claim that the AI is monitoring the Nanobot network and
            //notices the trick you just used to get access to the Nanobots
            return(FInt.FromParts(000, 000));
//    return  (FInt)ExternalConstants.Instance.Balance_BaseHackingScale;
        }
Esempio n. 2
0
 public override void DoOneSecondOfHackingLogic(GameEntity Target, GameEntity Hacker, ArcenSimContext Context)
 {
     if (Hacker.ActiveHack_DurationThusFar >= this.GetTotalSecondsToHack(Target, Hacker))
     {
     }
     else
     {
         if (Hacker.ActiveHack_DurationThusFar % 10 == 0)
         {
             FInt AIPPerTick = -(ExternalConstants.Instance.Balance_BaseAIPScale * FInt.FromParts(0, 100));
             World_AIW2.Instance.ChangeAIP(AIPPerTick, AIPChangeReason.Hacking, Target.TypeData, Context);
             int  ticksThusFar               = Hacker.ActiveHack_DurationThusFar / 10;
             int  totalWholeAIPReduced       = (ticksThusFar * AIPPerTick).IntValue;
             FInt waveMultiplier             = FInt.One;
             FInt multiplierMultiplierPerAIP = FInt.FromParts(1, 030);
             for (int i = 0; i < totalWholeAIPReduced; i++)
             {
                 waveMultiplier *= multiplierMultiplierPerAIP;
             }
             WaveLogic.SendWave(Context, Target.Side.WorldSide, Target.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Wave].NormalMenusToBuyFrom, Target.Side.WorldSide.GetSpecificBudgetThreshold(AIBudgetType.Wave) * waveMultiplier, Target, null);
         }
     }
 }
        public void DoInitialOrReconquestDefenseSeeding(ArcenSimContext Context, Planet ThisPlanet)
        {
            GameEntity controller = ThisPlanet.GetController();

            AIBudgetItem budgetItem = controller.Side.WorldSide.AITypeData.BudgetItems[AIBudgetType.Reinforcement];

            int direGuardianCount = ThisPlanet.MarkLevel.PlanetDireGuardianCount;

            List <GameEntityTypeData> guardianTypes = new List <GameEntityTypeData>();

            if (direGuardianCount > 0)
            {
                for (int j = 0; j < budgetItem.DireGuardianMenusToBuyFrom.Count; j++)
                {
                    for (int i = 0; i < budgetItem.DireGuardianMenusToBuyFrom[j].List.Count; i++)
                    {
                        GameEntityTypeData entityType = budgetItem.DireGuardianMenusToBuyFrom[j].List[i];
                        guardianTypes.Add(entityType);
                    }
                }

                Helper_SeedDireGuardians(Context, ThisPlanet, controller.WorldLocation, controller, guardianTypes, direGuardianCount, FInt.FromParts(0, 250), FInt.FromParts(0, 400), EntityBehaviorType.Guard_Guardian_Patrolling, true);
            }

            guardianTypes.Clear();
            for (int j = 0; j < budgetItem.GuardianMenusToBuyFrom.Count; j++)
            {
                for (int i = 0; i < budgetItem.GuardianMenusToBuyFrom[j].List.Count; i++)
                {
                    GameEntityTypeData entityType = budgetItem.GuardianMenusToBuyFrom[j].List[i];
                    if (entityType.Balance_MarkLevel.Ordinal > 0 &&
                        entityType.Balance_MarkLevel != ThisPlanet.MarkLevel)
                    {
                        continue;
                    }
                    if (World_AIW2.Instance.CorruptedAIDesigns.Contains(entityType))
                    {
                        continue;
                    }
                    if (!entityType.AICanUseThisWithoutUnlockingIt && !World_AIW2.Instance.UnlockedAIDesigns.Contains(entityType))
                    {
                        continue;
                    }
                    guardianTypes.Add(entityType);
                }
            }

            FInt turretStrengthBudget    = ThisPlanet.GetGuardingAITurretStrengthCap() / 2;
            FInt shieldStrengthBudget    = ThisPlanet.GetGuardingAIShieldStrengthCap() / 2;
            FInt guardianStrengthBudget  = ThisPlanet.GetGuardingAIGuardianStrengthCap() / 2;
            FInt fleetShipStrengthBudget = ThisPlanet.GetGuardingAIFleetShipStrengthCap() / 2;

            int extraStrongPoints = this.GetNumberOfNonControllerStrongAreas(Context, ThisPlanet);

            // if seeding more than one strong point, seed half as many mobile patrollers, so we have enough for the static stuff
            FInt mobilePatrollingPortion = extraStrongPoints <= 0 ? FInt.FromParts(0, 400) : FInt.FromParts(0, 200);

            guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, Engine_AIW2.Instance.CombatCenter, controller, guardianTypes,
                                                           guardianStrengthBudget * mobilePatrollingPortion, FInt.FromParts(0, 500), FInt.FromParts(0, 750), EntityBehaviorType.Guard_Guardian_Patrolling, true, 0);

            // if seeding more than one strong point, don't seed the stationary patrollers, so we have enough for the static stuff
            if (extraStrongPoints <= 0)
            {
                guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, controller.WorldLocation, controller, guardianTypes,
                                                               guardianStrengthBudget * FInt.FromParts(0, 500), FInt.FromParts(0, 250), FInt.FromParts(0, 400), EntityBehaviorType.Guard_Guardian_Patrolling, false, 0);
            }

            FInt portionPerStrongPoint = FInt.One / (extraStrongPoints + 1);

            for (int i = -1; i < extraStrongPoints; i++)
            {
                ArcenPoint strongPointLocation;
                FInt       maxDistance;
                int        seedingsLeft  = extraStrongPoints - i;
                FInt       budgetPortion = FInt.One / seedingsLeft;
                if (i == -1)
                {
                    strongPointLocation = controller.WorldLocation;
                    maxDistance         = FInt.FromParts(0, 150);
                    //FInt portionNotSpending = FInt.One - budgetPortion;
                    //budgetPortion = FInt.One - ( portionNotSpending / 2 ); // leave half as much as we normally would
                    //budgetPortion = Mat.Max( budgetPortion * 2, FInt.One );
                }
                else
                {
                    strongPointLocation = this.GetPointForNonControllerStrongArea(Context, ThisPlanet, i);
                    maxDistance         = FInt.FromParts(0, 100);
                }
                guardianStrengthBudget -= Helper_SeedGuardians(Context, ThisPlanet, strongPointLocation, controller, guardianTypes,
                                                               guardianStrengthBudget * budgetPortion, FInt.FromParts(0, 050), maxDistance, EntityBehaviorType.Guard_Guardian_Anchored, false, 0);
            }

            Reinforce(Context, ThisPlanet, controller.Side.WorldSide, shieldStrengthBudget, ReinforcementType.Shield);
            Reinforce(Context, ThisPlanet, controller.Side.WorldSide, turretStrengthBudget, ReinforcementType.Turret);
            Reinforce(Context, ThisPlanet, controller.Side.WorldSide, fleetShipStrengthBudget, ReinforcementType.FleetShip);
        }
        private FInt Inner_ReinforceWithFleetShipsOrTurrets(ArcenSimContext Context, Planet planet, WorldSide side, ref FInt budget, ReinforcementType reinforcementType, FInt strengthCap, ref FInt strengthPresent, List <BuildMenu> buildMenus, List <GameEntity> entitiesWeCanReinforce, bool atMostOnePerReinforceable)
        {
            if (entitiesWeCanReinforce.Count <= 0)
            {
                return(FInt.Zero);
            }

            ArcenRandomDrawBag <GameEntityTypeData> bag = new ArcenRandomDrawBag <GameEntityTypeData>();

            for (int i = 0; i < buildMenus.Count; i++)
            {
                BuildMenu menu = buildMenus[i];
                for (int j = 0; j < menu.List.Count; j++)
                {
                    int timesToAdd = 0;
                    GameEntityTypeData buyableType = menu.List[j];
                    if (buyableType.Balance_MarkLevel.Ordinal > 0 && buyableType.Balance_MarkLevel != planet.MarkLevel)
                    {
                        continue;
                    }
                    if (World_AIW2.Instance.CorruptedAIDesigns.Contains(buyableType))
                    {
                        continue;
                    }
                    if (!buyableType.AICanUseThisWithoutUnlockingIt && !World_AIW2.Instance.UnlockedAIDesigns.Contains(buyableType))
                    {
                        continue;
                    }
                    timesToAdd = 1;
                    if (timesToAdd <= 0)
                    {
                        continue;
                    }
                    bag.AddItem(buyableType, timesToAdd);
                }
            }

            if (!bag.GetHasItems())
            {
                return(FInt.Zero);
            }

            entitiesWeCanReinforce.Sort(delegate(GameEntity Left, GameEntity Right)
            {
                return(Left.Working_ReinforcementsOnly_ContentsStrength.CompareTo(Right.Working_ReinforcementsOnly_ContentsStrength));
            });

            FInt result = FInt.Zero;

            while (budget > FInt.Zero && strengthPresent < strengthCap && entitiesWeCanReinforce.Count > 0)
            {
                int index = 0;
                switch (reinforcementType)
                {
                case ReinforcementType.Turret:
                case ReinforcementType.Shield:
                    index = Context.QualityRandom.Next(0, entitiesWeCanReinforce.Count);
                    break;
                }
                GameEntity         entityToReinforce = entitiesWeCanReinforce[index];
                GameEntityTypeData typeToBuy         = bag.PickRandomItemAndReplace(Context.QualityRandom);
                budget          -= typeToBuy.BalanceStats.StrengthPerSquad;
                result          += typeToBuy.BalanceStats.StrengthPerSquad;
                strengthPresent += typeToBuy.BalanceStats.StrengthPerSquad;

                switch (reinforcementType)
                {
                case ReinforcementType.Turret:
                case ReinforcementType.Shield:
                {
                    int        minDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 050)).IntValue;
                    int        maxDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 150)).IntValue;
                    ArcenPoint point       = planet.Combat.GetSafePlacementPoint(Context, typeToBuy, entityToReinforce.WorldLocation, minDistance, maxDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }

                    result += typeToBuy.BalanceStats.StrengthPerSquad;

                    GameEntity newEntity = GameEntity.CreateNew(planet.Combat.GetSideForWorldSide(side), typeToBuy, point, Context);
                    newEntity.EntitySpecificOrders.Behavior = EntityBehaviorType.Stationary;
                }
                break;

                case ReinforcementType.FleetShip:
                {
                    entityToReinforce.ChangeContents(typeToBuy, 1);
                    entityToReinforce.Working_ReinforcementsOnly_ContentsStrength += typeToBuy.BalanceStats.StrengthPerSquad;

                    for (int i = 1; i < entitiesWeCanReinforce.Count; i++)
                    {
                        GameEntity otherReinforceable = entitiesWeCanReinforce[i];
                        if (entityToReinforce.Working_ReinforcementsOnly_ContentsStrength <= otherReinforceable.Working_ReinforcementsOnly_ContentsStrength)
                        {
                            break;
                        }
                        entitiesWeCanReinforce[i - 1] = otherReinforceable;
                        entitiesWeCanReinforce[i]     = entityToReinforce;
                    }
                }
                break;
                }

                if (atMostOnePerReinforceable)
                {
                    entitiesWeCanReinforce.Remove(entityToReinforce);
                }
            }

            return(result);
        }
Esempio n. 5
0
        public ArcenEnumIndexedArray_AIBudgetType <FInt> GetSpendingRatios(WorldSide side)
        {
            ArcenEnumIndexedArray_AIBudgetType <FInt> aipToQuasiAllocate = new ArcenEnumIndexedArray_AIBudgetType <FInt>();

            FInt bottomOfStep;
            FInt topOfStep;
            ArcenEnumIndexedArray_AIBudgetType <FInt> aipRatioForStep = new ArcenEnumIndexedArray_AIBudgetType <FInt>();

            bottomOfStep = FInt.Zero;
            topOfStep    = FInt.FromParts(2, 500);
            aipRatioForStep[AIBudgetType.Wave]          = FInt.FromParts(0, 167);
            aipRatioForStep[AIBudgetType.Reinforcement] = FInt.FromParts(0, 83);
            aipRatioForStep[AIBudgetType.CPA]           = FInt.FromParts(0, 125);
            aipRatioForStep[AIBudgetType.SpecialForces] = FInt.FromParts(0, 500);
            aipRatioForStep[AIBudgetType.Reconquest]    = FInt.FromParts(0, 125);
            AllocateAIPWithinStep(aipToQuasiAllocate, aipRatioForStep, bottomOfStep, topOfStep);

            bottomOfStep = topOfStep;
            topOfStep    = FInt.FromParts(10, 000);
            aipRatioForStep[AIBudgetType.Wave]          = FInt.FromParts(0, 83);
            aipRatioForStep[AIBudgetType.Reinforcement] = FInt.FromParts(0, 167);
            aipRatioForStep[AIBudgetType.CPA]           = FInt.FromParts(0, 125);
            aipRatioForStep[AIBudgetType.SpecialForces] = FInt.FromParts(0, 500);
            aipRatioForStep[AIBudgetType.Reconquest]    = FInt.FromParts(0, 125);
            AllocateAIPWithinStep(aipToQuasiAllocate, aipRatioForStep, bottomOfStep, topOfStep);

            bottomOfStep = topOfStep;
            topOfStep    = FInt.FromParts(20, 000);
            aipRatioForStep[AIBudgetType.Wave]          = FInt.FromParts(0, 250);
            aipRatioForStep[AIBudgetType.Reinforcement] = FInt.FromParts(0, 000);
            aipRatioForStep[AIBudgetType.CPA]           = FInt.FromParts(0, 125);
            aipRatioForStep[AIBudgetType.SpecialForces] = FInt.FromParts(0, 500);
            aipRatioForStep[AIBudgetType.Reconquest]    = FInt.FromParts(0, 125);
            AllocateAIPWithinStep(aipToQuasiAllocate, aipRatioForStep, bottomOfStep, topOfStep);

            bottomOfStep = topOfStep;
            topOfStep    = FInt.FromParts(50, 000);
            aipRatioForStep[AIBudgetType.Wave]          = FInt.FromParts(0, 125);
            aipRatioForStep[AIBudgetType.Reinforcement] = FInt.FromParts(0, 000);
            aipRatioForStep[AIBudgetType.CPA]           = FInt.FromParts(0, 250);
            aipRatioForStep[AIBudgetType.SpecialForces] = FInt.FromParts(0, 500);
            aipRatioForStep[AIBudgetType.Reconquest]    = FInt.FromParts(0, 125);
            AllocateAIPWithinStep(aipToQuasiAllocate, aipRatioForStep, bottomOfStep, topOfStep);

            bottomOfStep = topOfStep;
            topOfStep    = (FInt)(-1);
            aipRatioForStep[AIBudgetType.Wave]          = FInt.FromParts(0, 000);
            aipRatioForStep[AIBudgetType.Reinforcement] = FInt.FromParts(0, 000);
            aipRatioForStep[AIBudgetType.CPA]           = FInt.FromParts(0, 375);
            aipRatioForStep[AIBudgetType.SpecialForces] = FInt.FromParts(0, 500);
            aipRatioForStep[AIBudgetType.Reconquest]    = FInt.FromParts(0, 125);
            AllocateAIPWithinStep(aipToQuasiAllocate, aipRatioForStep, bottomOfStep, topOfStep);

            ArcenEnumIndexedArray_AIBudgetType <FInt> result = new ArcenEnumIndexedArray_AIBudgetType <FInt>();
            FInt planetsWorthOfAIP = World_AIW2.Instance.AIProgress_Effective / ExternalConstants.Instance.Balance_BaseAIPScale;

            for (AIBudgetType i = AIBudgetType.None; i < AIBudgetType.Length; i++)
            {
                result[i] = aipToQuasiAllocate[i] / planetsWorthOfAIP;
            }
            return(result);
        }
        private static int SpendBudgetOnItemsInList(ArcenSimContext Context, CombatSide Side, ArcenPoint CenterLocation, int MinimumDistanceFromCenter, List <GameEntityTypeData> listToBuyFrom, int budget)
        {
            if (listToBuyFrom.Count <= 0)
            {
                return(0);
            }
            if (budget <= 0)
            {
                return(0);
            }

            int remainingBudget = budget;

            int budgetPerType = remainingBudget / listToBuyFrom.Count;

            ArcenPoint formationCenterPoint = CenterLocation;

            listToBuyFrom.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                int leftValue = 0;
                if (Left.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Left.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        leftValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                int rightValue = 0;
                if (Right.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Right.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        rightValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                return(rightValue.CompareTo(leftValue));
            });

            int innerRingDistance = MinimumDistanceFromCenter;
            int outerRingDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 100)).IntValue;

            int distanceBetweenRings = (outerRingDistance - innerRingDistance) / listToBuyFrom.Count;

            for (int i = 0; i < listToBuyFrom.Count; i++)
            {
                GameEntityTypeData entityType = listToBuyFrom[i];
                int numberToPlace             = budgetPerType / entityType.BalanceStats.SquadPowerConsumption;
                numberToPlace = Math.Min(Side.GetRemainingCap(entityType), numberToPlace);
                if (numberToPlace <= 0)
                {
                    continue;
                }
                int          ringDistance       = innerRingDistance + (distanceBetweenRings * i);
                AngleDegrees startingAngle      = AngleDegrees.Create((FInt)Context.QualityRandom.Next(0, AngleDegrees.MaxValue.IntValue));
                AngleDegrees angleChangePerItem = AngleDegrees.MaxAngle / numberToPlace;
                for (int j = 0; j < numberToPlace; j++)
                {
                    if (Side.GetCanBuildAnother(entityType) != ArcenRejectionReason.Unknown)
                    {
                        break;
                    }
                    AngleDegrees angle = startingAngle + (angleChangePerItem * j);
                    ArcenPoint   point = formationCenterPoint.GetPointAtAngleAndDistance(angle, ringDistance);
                    point = Side.Combat.GetSafePlacementPoint(Context, entityType, point, 0, distanceBetweenRings / 2);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(Side, entityType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)entityType.BalanceStats.SquadMetalCost;
                    remainingBudget -= entityType.BalanceStats.SquadPowerConsumption;
                }
            }

            // fill in the corners of the budget
            listToBuyFrom.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                return(Right.BalanceStats.SquadPowerConsumption.CompareTo(Left.BalanceStats.SquadPowerConsumption));
            });

            bool checkAgain = true;

            while (remainingBudget > 0 && checkAgain)
            {
                checkAgain = false;
                for (int i = 0; i < listToBuyFrom.Count; i++)
                {
                    GameEntityTypeData entityType = listToBuyFrom[i];
                    if (remainingBudget < entityType.BalanceStats.SquadPowerConsumption)
                    {
                        continue;
                    }
                    if (Side.GetCanBuildAnother(entityType) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    ArcenPoint point = Side.Combat.GetSafePlacementPoint(Context, entityType, formationCenterPoint, innerRingDistance, outerRingDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(Side, entityType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)entityType.BalanceStats.SquadMetalCost;
                    remainingBudget -= entityType.BalanceStats.SquadPowerConsumption;
                    checkAgain       = true;
                }
            }

            return(budget - remainingBudget);
        }
        public void Execute(ArcenSimContext Context, GameEntity BuildingEntity)
        {
            List <GameEntityTypeData> turretTypes = new List <GameEntityTypeData>();

            for (int menuIndex = 0; menuIndex < BuildingEntity.TypeData.BuildMenus.Count; menuIndex++)
            {
                BuildMenu menu = BuildingEntity.TypeData.BuildMenus[menuIndex];
                for (int i = 0; i < menu.List.Count; i++)
                {
                    GameEntityTypeData entityData = menu.List[i];
                    if (entityData.Balance_FuelCost.FuelMultiplier > 0)
                    {
                        continue;
                    }
                    if (entityData.Balance_PowerCost.PowerMultiplier <= 0)
                    {
                        continue;
                    }
                    if (!entityData.CapIsPerPlanet)
                    {
                        continue;
                    }
                    if (!EntityRollupType.Combatants.Matches(entityData))     //&& !EntityRollupType.ProjectsShield.Matches( entityData )
                    {
                        continue;
                    }
                    if (BuildingEntity.Side.GetCanBuildAnother(entityData) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    turretTypes.Add(entityData);
                }
            }

            if (turretTypes.Count <= 0)
            {
                return;
            }

            int powerBudget = BuildingEntity.Side.NetPower;

            int budgetPerType = powerBudget / turretTypes.Count;

            ArcenPoint formationCenterPoint = BuildingEntity.WorldLocation;

            turretTypes.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                int leftValue = 0;
                if (Left.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Left.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        leftValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                int rightValue = 0;
                if (Right.SystemEntries.Count > 0)
                {
                    SystemEntry systemEntry = Right.SystemEntries[0];
                    if (systemEntry.SubEntries.Count > 0)
                    {
                        rightValue = systemEntry.SubEntries[0].BalanceStats.Range;
                    }
                }
                return(rightValue.CompareTo(leftValue));
            });

            int innerRingDistance = BuildingEntity.TypeData.Radius * 2;
            int outerRingDistance = (ExternalConstants.Instance.Balance_AverageGravWellRadius * FInt.FromParts(0, 100)).IntValue;

            int distanceBetweenRings = (outerRingDistance - innerRingDistance) / turretTypes.Count;

            for (int i = 0; i < turretTypes.Count; i++)
            {
                GameEntityTypeData turretType = turretTypes[i];
                int numberToPlace             = budgetPerType / turretType.BalanceStats.SquadPowerConsumption;
                numberToPlace = Math.Min(BuildingEntity.Side.GetRemainingCap(turretType), numberToPlace);
                if (numberToPlace <= 0)
                {
                    continue;
                }
                int          ringDistance       = innerRingDistance + (distanceBetweenRings * i);
                AngleDegrees startingAngle      = AngleDegrees.Create((FInt)Context.QualityRandom.Next(0, AngleDegrees.MaxValue.IntValue));
                AngleDegrees angleChangePerItem = AngleDegrees.MaxAngle / numberToPlace;
                for (int j = 0; j < numberToPlace; j++)
                {
                    if (BuildingEntity.Side.GetCanBuildAnother(turretType) != ArcenRejectionReason.Unknown)
                    {
                        break;
                    }
                    AngleDegrees angle = startingAngle + (angleChangePerItem * j);
                    ArcenPoint   point = formationCenterPoint.GetPointAtAngleAndDistance(angle, ringDistance);
                    point = BuildingEntity.Combat.GetSafePlacementPoint(Context, turretType, point, 0, distanceBetweenRings / 2);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(BuildingEntity.Side, turretType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)turretType.BalanceStats.SquadMetalCost;
                    powerBudget -= turretType.BalanceStats.SquadPowerConsumption;
                }
            }

            // fill in the corners of the budget
            turretTypes.Sort(delegate(GameEntityTypeData Left, GameEntityTypeData Right)
            {
                return(Right.BalanceStats.SquadPowerConsumption.CompareTo(Left.BalanceStats.SquadPowerConsumption));
            });

            bool checkAgain = true;

            while (powerBudget > 0 && checkAgain)
            {
                checkAgain = false;
                for (int i = 0; i < turretTypes.Count; i++)
                {
                    GameEntityTypeData turretType = turretTypes[i];
                    if (powerBudget < turretType.BalanceStats.SquadPowerConsumption)
                    {
                        continue;
                    }
                    if (BuildingEntity.Side.GetCanBuildAnother(turretType) != ArcenRejectionReason.Unknown)
                    {
                        continue;
                    }
                    ArcenPoint point = BuildingEntity.Combat.GetSafePlacementPoint(Context, turretType, formationCenterPoint, innerRingDistance, outerRingDistance);
                    if (point == ArcenPoint.ZeroZeroPoint)
                    {
                        continue;
                    }
                    GameEntity newEntity = GameEntity.CreateNew(BuildingEntity.Side, turretType, point, Context);
                    newEntity.SelfBuildingMetalRemaining = (FInt)turretType.BalanceStats.SquadMetalCost;
                    powerBudget -= turretType.BalanceStats.SquadPowerConsumption;
                    checkAgain   = true;
                }
            }
        }