feat(EconomyComparison) Added new WIP Feature
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
@inject IEconomyComparisonService economyComparisonService
|
||||
@inject IJSRuntime jsRuntime;
|
||||
@using Model.BuildOrders
|
||||
@implements IDisposable
|
||||
|
||||
<div class="chartsContainer">
|
||||
|
||||
@{
|
||||
var index = 0;
|
||||
}
|
||||
@foreach (var chart in charts)
|
||||
{
|
||||
index++;
|
||||
|
||||
<div style="width: 0; height: @chart.ValueDisplayMax.ToString()px">
|
||||
<div style="left: calc(-@width.ToString()px / 2); position: relative; border: 2px solid gray; border-radius:2px; width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
|
||||
@foreach (var point in chart.Points)
|
||||
{
|
||||
var xCoord = point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax);
|
||||
|
||||
var show = int.Parse(xCoord) / 6 % 2;
|
||||
var player = index - 1;
|
||||
|
||||
if (show == player)
|
||||
{
|
||||
<div style="position: absolute;
|
||||
bottom:@point.GetValue(highestAlloyPoint, chart.ValueDisplayMax)px;
|
||||
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
|
||||
width: 0px;
|
||||
height: 0px;">
|
||||
<div style="width:1px; height: 1px; border-top-right-radius:10px; border-top-left-radius:10px; border: 2px solid @chart.ChartColor; background-color:@chart.ChartColor">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.chartsContainer {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@code {
|
||||
|
||||
private readonly int width = 800;
|
||||
private readonly int height = 700;
|
||||
|
||||
private List<ChartModel> charts = new();
|
||||
|
||||
|
||||
float highestAlloyPoint = 0;
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
economyComparisonService.Subscribe(OnBuilderOrderChanged);
|
||||
|
||||
OnBuilderOrderChanged();
|
||||
}
|
||||
|
||||
|
||||
int lastRequestedRefreshIndex;
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
economyComparisonService.Unsubscribe(OnBuilderOrderChanged);
|
||||
}
|
||||
|
||||
|
||||
void OnBuilderOrderChanged()
|
||||
{
|
||||
|
||||
charts = new List<ChartModel>();
|
||||
var index = 0;
|
||||
|
||||
|
||||
highestAlloyPoint = 0;
|
||||
|
||||
foreach (var buildToCompare in economyComparisonService.BuildsToCompare)
|
||||
{
|
||||
GenerateChart(index++, buildToCompare);
|
||||
}
|
||||
|
||||
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(int index, BuildToCompareModel buildToCompareModel)
|
||||
{
|
||||
var economyOverTime = buildToCompareModel.EconomyOverTimeModel;
|
||||
|
||||
|
||||
var alloyChart = new ChartModel
|
||||
{
|
||||
IntervalDisplayMax = width,
|
||||
ValueDisplayMax = height,
|
||||
ChartColor = buildToCompareModel.ChartColor
|
||||
};
|
||||
|
||||
|
||||
|
||||
for (var interval = 0; interval < economyOverTime.Count(); interval++)
|
||||
{
|
||||
var alloyPoint = 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;
|
||||
|
||||
|
||||
float autoAlloy = 0;
|
||||
float workerSlots = 0;
|
||||
float workerAlloy = 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;
|
||||
}
|
||||
}
|
||||
|
||||
economySpending += (economyAtSecond.WorkerCount - 6) * 50;
|
||||
|
||||
workerAlloy = Math.Min(economyAtSecond.WorkerCount - economyAtSecond.BusyWorkerCount, workerSlots);
|
||||
|
||||
|
||||
alloyPoint.TempValue = workerAlloy + autoAlloy;
|
||||
|
||||
|
||||
if (interval > 0)
|
||||
{
|
||||
alloyPoint.TempValue += alloyChart.Points.Last().TempValue;
|
||||
}
|
||||
|
||||
alloyPoint.Value = alloyPoint.TempValue - economySpending;
|
||||
|
||||
highestAlloyPoint = Math.Max(highestAlloyPoint, alloyPoint.Value);
|
||||
|
||||
alloyChart.Points.Add(alloyPoint);
|
||||
}
|
||||
|
||||
alloyChart.HighestValuePoint = highestAlloyPoint;
|
||||
|
||||
alloyChart.HighestIntervalPoint = economyOverTime.Count();
|
||||
|
||||
charts.Add(alloyChart);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
@inject IEconomyComparisonService economyComparisonService
|
||||
@implements IDisposable
|
||||
|
||||
<div class="differences">
|
||||
<div class="differenceContainer">
|
||||
<div class="differenceTitle">
|
||||
Starting Advantage
|
||||
</div>
|
||||
<div>
|
||||
At Time: @StartingAdvantageAtTime | T @Interval.ToTime(StartingAdvantageAtTime)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="differenceContainer">
|
||||
<div class="differenceTitle">
|
||||
Peak Advantage
|
||||
</div>
|
||||
<div>
|
||||
By Alloy: @PeakAdvantageByAlloy
|
||||
</div>
|
||||
<div>
|
||||
At Time: @PeakAdvantageAtTime | T @Interval.ToTime(PeakAdvantageAtTime)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="differenceContainer">
|
||||
<div class="differenceTitle">
|
||||
Worsening Time
|
||||
</div>
|
||||
<div>
|
||||
At Time: @WorseningTime | T @Interval.ToTime(WorseningTime)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="differenceContainer">
|
||||
<div class="differenceTitle">
|
||||
Miracle Time
|
||||
</div>
|
||||
<div>
|
||||
At Time: @MiracleTime | T @Interval.ToTime(MiracleTime)
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.differences {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.differenceTitle {
|
||||
font-size: 1.2em;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.differenceContainer {
|
||||
|
||||
}
|
||||
</style>
|
||||
|
||||
@code {
|
||||
private int StartingAdvantageAtTime = 0;
|
||||
|
||||
private int PeakAdvantageByAlloy = 0;
|
||||
private int PeakAdvantageAtTime = 0;
|
||||
|
||||
private int WorseningTime = 0;
|
||||
private int MiracleTime = 0;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
economyComparisonService.Subscribe(CalculateDifferences);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
economyComparisonService.Unsubscribe(CalculateDifferences);
|
||||
}
|
||||
|
||||
void CalculateDifferences()
|
||||
{
|
||||
PeakAdvantageByAlloy = 0;
|
||||
StartingAdvantageAtTime = 0;
|
||||
WorseningTime = 0;
|
||||
|
||||
for (int interval = 0; interval < economyComparisonService.BuildsToCompare[0].EconomyOverTimeModel.Count; interval++)
|
||||
{
|
||||
var yourEconomy = economyComparisonService.BuildsToCompare[0].EconomyOverTimeModel[interval];
|
||||
var theirEconomy = economyComparisonService.BuildsToCompare[1].EconomyOverTimeModel[interval];
|
||||
|
||||
var deltaEconomy = yourEconomy.Alloy - theirEconomy.Alloy;
|
||||
if (deltaEconomy >= 0)
|
||||
{
|
||||
if (deltaEconomy > PeakAdvantageByAlloy)
|
||||
{
|
||||
if (StartingAdvantageAtTime == 0)
|
||||
{
|
||||
StartingAdvantageAtTime = interval;
|
||||
}
|
||||
|
||||
PeakAdvantageByAlloy = (int)deltaEconomy;
|
||||
PeakAdvantageAtTime = interval;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (PeakAdvantageByAlloy > 0 && WorseningTime == 0)
|
||||
{
|
||||
WorseningTime = interval;
|
||||
}
|
||||
|
||||
if (deltaEconomy < 1000 && MiracleTime != 0)
|
||||
{
|
||||
MiracleTime = interval;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
@inject IEconomyComparisonService economyComparisonService
|
||||
@implements IDisposable
|
||||
|
||||
<FormLayoutComponent>
|
||||
<FormSelectComponent OnChange="@OnFactionChanged">
|
||||
<FormLabelComponent>Faction</FormLabelComponent>
|
||||
<ChildContent>
|
||||
<option value="@DataType.FACTION_Aru" selected="@IsSelected(DataType.FACTION_Aru)">Aru</option>
|
||||
<option value="@DataType.FACTION_QRath" selected="@IsSelected(DataType.FACTION_QRath)">Q'Rath</option>
|
||||
</ChildContent>
|
||||
</FormSelectComponent>
|
||||
<ContentDividerComponent/>
|
||||
<FormNumberComponent Value="@TownHallCount" OnChange="ChangeTownHallNumber">
|
||||
<FormLabelComponent>Number of TownHall Expansions</FormLabelComponent>
|
||||
</FormNumberComponent>
|
||||
<ContentDividerComponent/>
|
||||
|
||||
@{
|
||||
var index = 0;
|
||||
}
|
||||
@foreach (var timing in TownHallTimings)
|
||||
{
|
||||
index++;
|
||||
|
||||
<FormNumberComponent Value="@timing" OnChange="(e)=> ChangeBuildTime(e, index - 1)">
|
||||
<FormLabelComponent>
|
||||
TownHall build time
|
||||
</FormLabelComponent>
|
||||
</FormNumberComponent>
|
||||
}
|
||||
<ContentDividerComponent/>
|
||||
<FormTextComponent Label="Chart Color" Value="@ChartColor" OnChange="ChangeColor" />
|
||||
</FormLayoutComponent>
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public int ForPlayer { get; set; }
|
||||
|
||||
private int TownHallCount => economyComparisonService.GetTownHallCount(ForPlayer);
|
||||
private string ChartColor => economyComparisonService.GetColor(ForPlayer);
|
||||
private string Faction => economyComparisonService.GetFaction(ForPlayer);
|
||||
private List<int> TownHallTimings => economyComparisonService.GetTownHallBuildTimes(ForPlayer);
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
economyComparisonService.Subscribe(StateHasChanged);
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
economyComparisonService.Unsubscribe(StateHasChanged);
|
||||
}
|
||||
|
||||
private void OnFactionChanged(ChangeEventArgs obj)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private bool IsSelected(string factionType)
|
||||
{
|
||||
return Faction.Equals(factionType);
|
||||
}
|
||||
|
||||
private void ChangeColor(ChangeEventArgs obj)
|
||||
{
|
||||
economyComparisonService.ChangeColor(ForPlayer, obj.Value!.ToString()!);
|
||||
}
|
||||
|
||||
private void ChangeTownHallNumber(ChangeEventArgs obj)
|
||||
{
|
||||
economyComparisonService.ChangeNumberOfTownHalls(ForPlayer, (int)obj.Value!);
|
||||
}
|
||||
|
||||
private void ChangeBuildTime(ChangeEventArgs obj, int index)
|
||||
{
|
||||
economyComparisonService.ChangeTownHallTiming(ForPlayer, index, (int)obj.Value!);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user