@inject IEconomyService economyService @inject IBuildOrderService buildOrderService @inject IJSRuntime jsRuntime; @implements IDisposable @if (lastRequestedRefreshIndex != requestedRefreshIndex) { } else {
@foreach (var chart in charts) {
@foreach (var point in chart.Points) {
}
}
@highestAlloyPoint @highestEtherPoint @highestEtherPoint @highestArmyPoint } @code { private readonly int width = 250; List valueList = new(); readonly List charts = new(); float highestAlloyPoint; float highestEtherPoint; float highestPyrePoint; float highestArmyPoint; private Timer ageTimer = null!; protected override void OnInitialized() { buildOrderService.Subscribe(OnBuilderOrderChanged); ageTimer = new Timer(3000); ageTimer.Elapsed += OnAge!; ageTimer.Enabled = true; GenerateChart(); } int lastRequestedRefreshIndex = 0; void OnAge(object? sender, ElapsedEventArgs elapsedEventArgs) { if (requestedRefreshIndex > 0) { if (requestedRefreshIndex == lastRequestedRefreshIndex) { GenerateChart(); requestedRefreshIndex = 0; lastRequestedRefreshIndex = 0; } lastRequestedRefreshIndex = requestedRefreshIndex; } ageTimer.Enabled = true; } void IDisposable.Dispose() { buildOrderService.Unsubscribe(OnBuilderOrderChanged); } int requestedRefreshIndex = 0; void OnBuilderOrderChanged() { requestedRefreshIndex++; StateHasChanged(); } protected override bool ShouldRender() { #if DEBUG jsRuntime.InvokeVoidAsync("console.time", "ChartComponent"); #endif return true; } protected override void OnAfterRender(bool firstRender) { #if DEBUG jsRuntime.InvokeVoidAsync("console.timeEnd", "ChartComponent"); #endif } void GenerateChart() { var economyOverTime = economyService.GetOverTime(); charts.Clear(); var alloyChart = new ChartModel { IntervalDisplayMax = width, ValueDisplayMax = 100, ChartColor = "Cyan" }; var etherChart = new ChartModel { Offset = width, IntervalDisplayMax = width, ValueDisplayMax = 100, ChartColor = "LightGreen" }; var pyreChart = new ChartModel { Offset = width * 2, IntervalDisplayMax = width, ValueDisplayMax = 100, ChartColor = "Red" }; var armyChart = new ChartModel { Offset = width * 3, IntervalDisplayMax = width, ValueDisplayMax = 100, ChartColor = "White" }; highestAlloyPoint = 0; highestEtherPoint = 0; highestPyrePoint = 0; highestArmyPoint = 0; for (var interval = 0; interval < economyOverTime.Count(); interval++) { var army = from unit in buildOrderService.GetCompletedBefore(interval) where unit.EntityType == EntityType.Army select unit; var armyValue = 0; foreach (var unit in army) { armyValue += unit.Production().Alloy + unit.Production().Ether; } highestArmyPoint = Math.Max(highestArmyPoint, armyValue); armyChart.Points.Add(new PointModel { Interval = interval, Value = armyValue }); } for (var interval = 0; interval < economyOverTime.Count(); interval++) { var alloyPoint = new PointModel { Interval = interval }; var etherPoint = new PointModel { Interval = interval }; var pyrePoint = new PointModel { Interval = interval }; var economyAtSecond = economyOverTime[interval]; var alloyWorkerHarvesters = from harvester in economyAtSecond.Harvesters where harvester.Harvest() != null where harvester.Harvest().RequiresWorker where harvester.Harvest().Resource == ResourceType.Alloy select harvester; var alloyAutomaticHarvesters = from harvester in economyAtSecond.Harvesters where harvester.Harvest() != null where harvester.Harvest().RequiresWorker == false where harvester.Harvest().Resource == ResourceType.Alloy select harvester; var etherAutomaticHarvesters = from harvester in economyAtSecond.Harvesters where harvester.Harvest() != null where harvester.Harvest().RequiresWorker == false where harvester.Harvest().Resource == ResourceType.Ether select harvester; float autoAlloy = 0; float workerSlots = 0; float workerAlloy = 0; float autoEther = 0; float economySpending = 0; foreach (var alloyAutoHarvester in alloyAutomaticHarvesters) { autoAlloy += alloyAutoHarvester.Harvest().Slots * alloyAutoHarvester.Harvest().HarvestedPerInterval; var production = alloyAutoHarvester.Production(); if (production != null) { economySpending += production.Alloy; } } foreach (var alloyWorkerHarvester in alloyWorkerHarvesters) { workerSlots += alloyWorkerHarvester.Harvest().Slots; var production = alloyWorkerHarvester.Production(); if (production != null) { economySpending += production.Alloy; } } foreach (var etherWorkerHarvester in etherAutomaticHarvesters) { autoEther += etherWorkerHarvester.Harvest().Slots * etherWorkerHarvester.Harvest().HarvestedPerInterval; var production = etherWorkerHarvester.Production(); if (production != null) { economySpending += production.Alloy; } } economySpending += (economyAtSecond.WorkerCount - 6) * 50; workerAlloy = Math.Min(economyAtSecond.WorkerCount - economyAtSecond.BusyWorkerCount, workerSlots); alloyPoint.TempValue = workerAlloy + autoAlloy; etherPoint.Value = autoEther; if (interval > 0) { alloyPoint.TempValue += alloyChart.Points.Last().TempValue; etherPoint.Value += etherChart.Points.Last().Value; pyrePoint.Value = pyreChart.Points.Last().Value + 1; } alloyPoint.Value = alloyPoint.TempValue - economySpending; highestAlloyPoint = Math.Max(highestAlloyPoint, alloyPoint.Value); highestEtherPoint = Math.Max(highestEtherPoint, etherPoint.Value); alloyChart.Points.Add(alloyPoint); etherChart.Points.Add(etherPoint); pyreChart.Points.Add(pyrePoint); } alloyChart.HighestValuePoint = (int)Math.Max(highestAlloyPoint, 5000.0f); etherChart.HighestValuePoint = (int)Math.Max(highestEtherPoint, 2000.0f); pyreChart.HighestValuePoint = (int)Math.Max(highestPyrePoint, 2000.0f); alloyChart.HighestIntervalPoint = economyOverTime.Count(); etherChart.HighestIntervalPoint = economyOverTime.Count(); pyreChart.HighestIntervalPoint = economyOverTime.Count(); armyChart.HighestValuePoint = (int)Math.Max(highestArmyPoint, 2000.0f); armyChart.HighestIntervalPoint = economyOverTime.Count(); charts.Add(alloyChart); charts.Add(etherChart); //TODO WIP //charts.Add(pyreChart); charts.Add(armyChart); StateHasChanged(); } }