예제 #1
0
 public void AdjustModulesStatsForUndo(BuildOrderProcessorItem undoBoItem, BuildOrderProcessorItem newLastItem)
 {
     foreach (var stepModule in this)
     {
         stepModule.AdjustModuleStatsByUndoItem(undoBoItem, newLastItem);
     }
 }
예제 #2
0
 public void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
 {
     foreach (var buildStepModule in this)
     {
         buildStepModule.AdjustModuleStatsByStartedItem(boItem, item, stats);
     }
 }
예제 #3
0
        public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            if (item.Name == Consts.DefaultStateItemName)
            {
                int    energyGeneratorCount = stats.GetStatValueByName(this.BuildManagerConfiguration.RaceConstants.EnergyGeneratorBuildItemName);
                int    energyForNewBase     = this.BuildManagerConfiguration.RaceConstants.EnergyCastCountForNewEnergyGenerator;
                string energyGeneratorName  = this.BuildManagerConfiguration.RaceConstants.EnergyGeneratorBuildItemName;

                stats.ChangeItemCountForName("TotalCasts", energyGeneratorCount * energyForNewBase);

                for (int i = 0; i < energyGeneratorCount; i++)
                {
                    stats.ChangeItemCountForName(energyGeneratorName + (i + 1) + "CastCount", energyForNewBase);
                    stats.ChangeItemCountForName(energyGeneratorName + (i + 1) + "CastTimer", 0);
                }
            }

            var castRequirement = item.ProduceRequirements.FirstOrDefault(p => p is CastRequirement) as CastRequirement;

            if (castRequirement == null)
            {
                return;
            }

            this.UseCast(stats);
        }
예제 #4
0
        public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            var startIdle = stats.GetStatValueByName(StartIdle);

            if (startIdle == 0)
            {
                stats.SetItemCountForName(IdleTimer, 0);
            }
        }
예제 #5
0
        private void ProcessBoostPossibleItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            if (item.ItemType == BuildItemTypeEnum.Unit || item.ItemType == BuildItemTypeEnum.Upgrade)
            {
                var prodBuilding = this.GetProdBuildingNameForItem(stats, item);

                if (!string.IsNullOrEmpty(prodBuilding))
                {
                    this.ApplyBuzyTimers(boItem, item, stats, prodBuilding);

                    stats.SetItemCountForName("LastItemOrder", boItem.Order);
                    stats.SetItemCountForName("LastItemProdBuildingIndex", Convert.ToInt32(prodBuilding.Substring(item.ProductionBuildingName.Length)));
                }
            }
        }
예제 #6
0
        private void SetAvailableBoost(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            int boostLength    = this.BuildManagerConfiguration.BuildItemsDictionary.GetItem("Chronoboost").BuildTimeInSeconds;
            int boostProdIndex = stats.GetStatValueByName("LastItemProdBuildingIndex");

            int chronoTimer = stats.GetStatValueByName("ChronoTimer" + item.ProductionBuildingName + boostProdIndex);
            int buildTime   = boItem.FinishedSecond - boItem.SecondInTimeLine;

            int  availableCasts = buildTime <= chronoTimer ? 0 : (int)Math.Ceiling((double)(buildTime - chronoTimer) / boostLength);
            int  secondsToChronoboost;
            bool isEnoughEnergy = this.IsChronoboostPossibleWhileBuilding(buildTime, stats, out secondsToChronoboost);

            if (boItem.SecondInTimeLine + secondsToChronoboost >= boItem.FinishedSecond)
            {
                isEnoughEnergy = false;
            }
            stats.SetItemCountForName("ChronoboostAvailable", (availableCasts > 0 && isEnoughEnergy) ? 1 : 0);
        }
예제 #7
0
        private void ApplyBuzyTimers(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats, string prodBuilding)
        {
            int chronoTimer = stats.GetStatValueByName("ChronoTimer" + prodBuilding);

            if (chronoTimer != 0)
            {
                boItem.FinishedSecond = boItem.SecondInTimeLine + this.CalculateBuildTimeForItem(item.BuildTimeInSeconds, chronoTimer);

                int chronoBuzyTimer = (boItem.FinishedSecond - boItem.SecondInTimeLine) > chronoTimer
                          ? chronoTimer
                          : (boItem.FinishedSecond - boItem.SecondInTimeLine);

                stats.SetItemCountForName("ChronoBuzy" + prodBuilding, chronoBuzyTimer);
            }
            else
            {
                stats.SetItemCountForName("NormalBuzy" + prodBuilding, item.BuildTimeInSeconds);
            }
        }
예제 #8
0
        public override void AdjustModuleStatsByUndoItem(BuildOrderProcessorItem undoBoItem, BuildOrderProcessorItem newLastItem)
        {
            if (undoBoItem.ItemName == "Chronoboost")
            {
                // Recalculate boosted item finish time
                int boostItemOrder = newLastItem.StatisticsProvider.GetStatValueByName("LastItemOrder");
                int boostProdIndex = newLastItem.StatisticsProvider.GetStatValueByName("LastItemProdBuildingIndex");

                if (boostItemOrder == 0)
                {
                    return;
                }

                BuildOrderProcessorItem boostBoItem = this.BuildOrder.GetBuildOrderItemsClone().First(p => p.Order == boostItemOrder);
                BuildItemEntity         boostItem   = this.BuildManagerConfiguration.BuildItemsDictionary.GetItem(boostBoItem.ItemName);

                int previousChronoTimer = newLastItem.StatisticsProvider.GetStatValueByName("ChronoTimer" + boostItem.ProductionBuildingName + boostProdIndex);

                boostBoItem.FinishedSecond = boostBoItem.SecondInTimeLine + this.CalculateBuildTimeForItem(boostItem.BuildTimeInSeconds, previousChronoTimer);
            }
        }
        public override void AdjustModuleStatsByUndoItem(BuildOrderProcessorItem undoBoItem, BuildOrderProcessorItem newLastItem)
        {
            if (undoBoItem.ItemName == "Chronoboost")
            {
                if (undoBoItem.SecondInTimeLine == undoBoItem.FinishedSecond)
                {
                    return;
                }

                // Recalculate boosted item finish time
                int boostItemOrder = newLastItem.StatisticsProvider.GetStatValueByName("LastItemOrder");

                if (boostItemOrder == 0)
                {
                    return;
                }

                BuildItemEntity boostItem = BuildManagerConfiguration.BuildItemsDictionary.GetItem(newLastItem.ItemName);

                newLastItem.FinishedSecond = newLastItem.SecondInTimeLine + boostItem.BuildTimeInSeconds;
            }
        }
예제 #10
0
        private void AdjustAvailableBoost(BuildOrderProcessorItem lastAddedBoItem, BuildItemEntity lastAddedItem, BuildItemStatistics stats)
        {
            if (lastAddedItem.Name == Consts.DefaultStateItemName)
            {
                return;
            }

            BuildOrderProcessorItem boBoostedItem;
            BuildItemEntity         boostedItem;

            if (lastAddedItem.ItemType == BuildItemTypeEnum.Unit || lastAddedItem.ItemType == BuildItemTypeEnum.Upgrade)
            {
                boBoostedItem = lastAddedBoItem;
                boostedItem   = lastAddedItem;
            }
            else
            {
                int boostItemOrder = stats.GetStatValueByName("LastItemOrder");
                boBoostedItem = this.BuildOrder.GetBuildOrderItemsClone().First(p => p.Order == boostItemOrder);
                boostedItem   = this.BuildManagerConfiguration.BuildItemsDictionary.GetItem(boBoostedItem.ItemName);
            }

            this.SetAvailableBoost(boBoostedItem, boostedItem, stats);
        }
        public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            if (item.Name == "DefaultItem")
            {
                stats.ChangeItemCountForName("BoostedNexusCount", 1);
                return;
            }

            if (item.ProductionBuildingName == "Nexus")
            {
                stats.SetItemCountForName("ChronoboostAvailable", 0);

                int boostedNexus     = stats.GetStatValueByName("BoostedNexusCount");
                int boostedNexusBuzy = stats.GetStatValueByName("NexusBoostedBuzy");

                if (boostedNexus > boostedNexusBuzy)
                {
                    stats.ChangeItemCountForName("NexusBoostedBuzy", 1);
                    int secondsToCompleteBuilding  = boItem.FinishedSecond - boItem.SecondInTimeLine;
                    int secondsToCompleteWithBoost = (int)Math.Round(secondsToCompleteBuilding - secondsToCompleteBuilding * 0.15);

                    boItem.FinishedSecond = boItem.SecondInTimeLine + secondsToCompleteWithBoost;
                }
                else
                {
                    // We should try to find a moment in the build when chronoboost would be released if any of timers is in progress
                    var chronoTimers = stats.GetStatsWithKeyContains("ChronoTimer");
                    if (chronoTimers.Count > 0)
                    {
                        int fastestChronoRelease = chronoTimers.Min(p => p.Value);
                        if (item.BuildTimeInSeconds > fastestChronoRelease)
                        {
                            int boostedTime          = boItem.FinishedSecond - boItem.SecondInTimeLine - fastestChronoRelease;
                            int boostedTimeWithBoost = (int)Math.Round(boostedTime - boostedTime * 0.15);
                            //var boostedTimeWithBoost = boostedTime / 1.5;

                            boItem.FinishedSecond = boItem.SecondInTimeLine + fastestChronoRelease + boostedTimeWithBoost;

                            stats.SetItemCountForName("ChronoBuzyTimer" + boItem.Order, fastestChronoRelease);
                        }
                    }
                }

                return;
            }

            if (item.Name == "Chronoboost")
            {
                stats.SetItemCountForName("ChronoboostAvailable", 0);

                int boostItemOrder = stats.GetStatValueByName("LastItemOrder");

                BuildOrderProcessorItem boItemToBeBoosted = null;
                BuildItemEntity         entityToBeBoosted = null;

                for (int i = boostItemOrder; i > 0; i--)
                {
                    boItemToBeBoosted = BuildOrder.GetBuildOrderItemsClone().First(p => p.Order == i);
                    entityToBeBoosted = BuildManagerConfiguration.BuildItemsDictionary.GetItem(boItemToBeBoosted.ItemName);

                    if (boItemToBeBoosted.FinishedSecond < boItem.SecondInTimeLine)
                    {
                        return;
                    }

                    if (entityToBeBoosted.ProductionBuildingName == "Nexus")
                    {
                        continue;
                    }

                    if (entityToBeBoosted.ItemType == BuildItemTypeEnum.Unit || entityToBeBoosted.ItemType == BuildItemTypeEnum.Upgrade)
                    {
                        break;
                    }

                    boItemToBeBoosted = null;
                    entityToBeBoosted = null;
                }

                if (boItemToBeBoosted == null || entityToBeBoosted == null)
                {
                    throw new ApplicationException("Build processor were unable to find item to be boosted");
                }

                int unbooStedTime = 0;

                if (boItem.SecondInTimeLine > boItemToBeBoosted.SecondInTimeLine)
                {
                    unbooStedTime = boItem.SecondInTimeLine - boItemToBeBoosted.SecondInTimeLine;
                }

                int boostedTime = boItemToBeBoosted.FinishedSecond - boItem.SecondInTimeLine;

                int boostedTimeWithBoost = (int)Math.Round(boostedTime - boostedTime * 0.15);

                boItemToBeBoosted.FinishedSecond = boItemToBeBoosted.SecondInTimeLine + unbooStedTime + boostedTimeWithBoost;

                boItem.FinishedSecond = boItemToBeBoosted.FinishedSecond;

                stats.ChangeItemCountForName("BoostedNexusCount", -1);

                stats.SetItemCountForName("ChronoTimer" + boostItemOrder, boItemToBeBoosted.FinishedSecond - boItem.SecondInTimeLine);

                return;
            }

            if (item.ItemType == BuildItemTypeEnum.Unit || item.ItemType == BuildItemTypeEnum.Upgrade)
            {
                stats.SetItemCountForName("LastItemOrder", boItem.Order);

                stats.SetItemCountForName("ChronoboostAvailable", 1);
            }
        }
예제 #12
0
        public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            if (item.Name == "InjectLarva")
            {
                // TODO:
                var injectedHatcheries = stats.GetStatsWithKeyContains("InjectedTimer");
                int totalHatcheries    = stats.GetStatValueByName("Hatchery");

                if (injectedHatcheries.Count >= totalHatcheries)
                {
                    throw new ApplicationException("All hatcheries are buzy");
                }

                var    injectedHatchList = stats.GetStatsWithKeyContains("InjectedTimer").Select(p => p.Key.Substring(0, p.Key.Length - "InjectedTimer".Length)).ToList();
                string hatchToInject     = string.Empty;

                for (int i = 1; i <= totalHatcheries; i++)
                {
                    var hatchName = "Hatchery" + i;
                    if (!injectedHatchList.Contains(hatchName))
                    {
                        hatchToInject = hatchName;
                        break;
                    }
                }

                if (string.IsNullOrEmpty(hatchToInject))
                {
                    throw new ApplicationException("All hatcheries are buzy");
                }

                stats.SetItemCountForName(hatchToInject + "InjectedTimer", 1);

                return;
            }

            var larvaRequirement = item.ProduceRequirements.FirstOrDefault(p => p is LarvaRequirement) as LarvaRequirement;

            if (larvaRequirement == null)
            {
                return;
            }

            int requiredLarva = larvaRequirement.RequiredValue;

            var larvaCounts = stats.GetStatsWithKeyContains("LarvaCount");

            foreach (var larvaCount in larvaCounts)
            {
                if (larvaCount.Value >= requiredLarva)
                {
                    stats.SetItemCountForName(larvaCount.Key, larvaCount.Value - requiredLarva);
                    break;
                }

                requiredLarva = requiredLarva - larvaCount.Value;
                stats.SetItemCountForName(larvaCount.Key, 0);
            }

            this.ResetTotalLarva(stats);
        }
예제 #13
0
        private void ProcessChronoboostItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
        {
            if (item.ItemType == BuildItemTypeEnum.Special && item.Name == "Chronoboost")
            {
                if (stats.GetStatValueByName("ChronoboostAvailable") == 0)
                {
                    throw new ApplicationException("It is not possible to apply chronoboost at this moment!");
                }

                // Apply chronoboost calculations
                int boostItemOrder = stats.GetStatValueByName("LastItemOrder");
                int boostProdIndex = stats.GetStatValueByName("LastItemProdBuildingIndex");

                if (boostItemOrder == 0)
                {
                    return;
                }

                int boostLength = this.BuildManagerConfiguration.BuildItemsDictionary.GetItem("Chronoboost").BuildTimeInSeconds;

                BuildOrderProcessorItem boostBoItem = this.BuildOrder.GetBuildOrderItemsClone().First(p => p.Order == boostItemOrder);
                BuildItemEntity         boostItem   = this.BuildManagerConfiguration.BuildItemsDictionary.GetItem(boostBoItem.ItemName);

                int previousChronoTimer = stats.GetStatValueByName("ChronoTimer" + boostItem.ProductionBuildingName + boostProdIndex);

                //int boostApplyPoint = boostBoItem.SecondInTimeLine + previousChronoTimer;

                int buildTime = boostBoItem.FinishedSecond - (boostBoItem.SecondInTimeLine + previousChronoTimer);

                int  secondsToChronoboost;
                bool isEnoughEnergy = this.IsChronoboostPossibleWhileBuilding(boostBoItem.FinishedSecond - boostBoItem.SecondInTimeLine, stats, out secondsToChronoboost);
                if (!isEnoughEnergy)
                {
                    throw new ApplicationException("Chronoboost is unavailable");
                }

                if (previousChronoTimer < secondsToChronoboost)
                {
                    buildTime -= (secondsToChronoboost - previousChronoTimer);
                }

                int boostAmount = (buildTime - this.CalculateBuildTimeForItem(buildTime, boostLength));
                boostBoItem.FinishedSecond -= boostAmount;

                int normalBuzy = stats.GetStatValueByName("NormalBuzy" + boostItem.ProductionBuildingName + boostProdIndex);

                if (normalBuzy - (boostLength + boostAmount) > 0)
                {
                    stats.SetItemCountForName("NormalBuzy" + boostItem.ProductionBuildingName + boostProdIndex, normalBuzy - (boostLength + boostAmount));
                }
                else
                {
                    stats.RemoveStat("NormalBuzy" + boostItem.ProductionBuildingName + boostProdIndex);
                }

                stats.SetItemCountForName("ChronoTimer" + boostItem.ProductionBuildingName + boostProdIndex, boostLength + previousChronoTimer);

                int chronoBuzyTimer = (boostBoItem.FinishedSecond - boItem.SecondInTimeLine) > (boostLength + previousChronoTimer)
                                          ? (boostLength + previousChronoTimer)
                                          : (boostBoItem.FinishedSecond - boItem.SecondInTimeLine);
                stats.SetItemCountForName("ChronoBuzy" + boostItem.ProductionBuildingName + boostProdIndex, chronoBuzyTimer);

                var castModule = this.BuildManagerConfiguration.BuildManagerModules.First(p => p is CastModule) as CastModule;
                castModule.UseCast(stats);
            }
        }
예제 #14
0
 public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
 {
     this.ProcessBoostPossibleItem(boItem, item, stats);
     this.ProcessChronoboostItem(boItem, item, stats);
     this.AdjustAvailableBoost(boItem, item, stats);
 }
예제 #15
0
 public override void AdjustModuleStatsByStartedItem(BuildOrderProcessorItem boItem, BuildItemEntity item, BuildItemStatistics stats)
 {
     stats.Gas      -= item.CostGas;
     stats.Minerals -= item.CostMinerals;
 }