@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();
}
}