feat(BuildCalc) Optimized the build calculator
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
@using Microsoft.Extensions.Localization
|
@layout PageLayout
|
||||||
@implements IDisposable
|
|
||||||
|
|
||||||
@layout PageLayout
|
|
||||||
|
|
||||||
@inject IStringLocalizer<Localizations> locale
|
@inject IStringLocalizer<Localizations> locale
|
||||||
|
|
||||||
@@ -13,6 +10,9 @@
|
|||||||
@inject ITimingService timingService
|
@inject ITimingService timingService
|
||||||
|
|
||||||
@page "/build-calculator"
|
@page "/build-calculator"
|
||||||
|
@using Microsoft.Extensions.Localization
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<LayoutLargeContentComponent>
|
<LayoutLargeContentComponent>
|
||||||
<WebsiteTitleComponent>Build Calculator</WebsiteTitleComponent>
|
<WebsiteTitleComponent>Build Calculator</WebsiteTitleComponent>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<div class="calculatorGrid">
|
<div class="calculatorGrid">
|
||||||
|
|
||||||
<div style="grid-area: timing;" class="gridItem">
|
<div style="grid-area: timing;" class="gridItem">
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip Timing Info"]" >
|
<InfoTooltipComponent InfoText="@locale["Tooltip Timing Info"]">
|
||||||
|
|
||||||
<TimingComponent></TimingComponent>
|
<TimingComponent></TimingComponent>
|
||||||
</InfoTooltipComponent>
|
</InfoTooltipComponent>
|
||||||
@@ -52,27 +52,32 @@
|
|||||||
</InfoTooltipComponent>
|
</InfoTooltipComponent>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (true)
|
||||||
|
{
|
||||||
|
<div style="grid-area: view;" class="gridItem">
|
||||||
|
<InfoTooltipComponent InfoText="@locale["Tooltip Entity Info"]">
|
||||||
|
<EntityClickViewComponent/>
|
||||||
|
</InfoTooltipComponent>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div style="grid-area: view;" class="gridItem">
|
@if (true)
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip Entity Info"]">
|
{
|
||||||
<EntityClickViewComponent/>
|
<div style="grid-area: bank;" class="gridItem">
|
||||||
</InfoTooltipComponent>
|
<InfoTooltipComponent InfoText="@locale["Tooltip Bank Info"]">
|
||||||
</div>
|
<BankComponent></BankComponent>
|
||||||
|
</InfoTooltipComponent>
|
||||||
|
</div>
|
||||||
<div style="grid-area: bank;" class="gridItem">
|
}
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip Bank Info"]">
|
|
||||||
<BankComponent></BankComponent>
|
|
||||||
</InfoTooltipComponent>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style="grid-area: army;" class="gridItem">
|
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip Army Info"]">
|
|
||||||
<ArmyComponent></ArmyComponent>
|
|
||||||
</InfoTooltipComponent>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
@if (true)
|
||||||
|
{
|
||||||
|
<div style="grid-area: army;" class="gridItem">
|
||||||
|
<InfoTooltipComponent InfoText="@locale["Tooltip Army Info"]">
|
||||||
|
<ArmyComponent></ArmyComponent>
|
||||||
|
</InfoTooltipComponent>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<div class="gridItem gridKeys">
|
<div class="gridItem gridKeys">
|
||||||
|
|
||||||
@@ -82,25 +87,22 @@
|
|||||||
</InfoTooltipComponent>
|
</InfoTooltipComponent>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if (true)
|
||||||
@if (false)
|
|
||||||
{
|
{
|
||||||
<div style="grid-area: timeline;" class="gridItem">
|
<div style="grid-area: highlights;" class="gridItem">
|
||||||
<TimelineComponent></TimelineComponent>
|
<InfoTooltipComponent InfoText="@locale["Tooltip Highlights Info"]">
|
||||||
|
<HighlightsComponent></HighlightsComponent>
|
||||||
|
</InfoTooltipComponent>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
@if (true)
|
||||||
|
{
|
||||||
|
<div style="grid-area: buildorder;" class="gridItem">
|
||||||
|
<InfoTooltipComponent InfoText="@locale["Tooltip BuildOrder Info"]">
|
||||||
|
<BuildOrderComponent></BuildOrderComponent>
|
||||||
|
</InfoTooltipComponent>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div style="grid-area: highlights;" class="gridItem">
|
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip Highlights Info"]">
|
|
||||||
<HighlightsComponent></HighlightsComponent>
|
|
||||||
</InfoTooltipComponent>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="grid-area: buildorder;" class="gridItem">
|
|
||||||
<InfoTooltipComponent InfoText="@locale["Tooltip BuildOrder Info"]">
|
|
||||||
<BuildOrderComponent></BuildOrderComponent>
|
|
||||||
</InfoTooltipComponent>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ContentDividerComponent></ContentDividerComponent>
|
<ContentDividerComponent></ContentDividerComponent>
|
||||||
@@ -218,29 +220,19 @@
|
|||||||
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
keyService.Subscribe(HandleClick);
|
|
||||||
filterService.Subscribe(StateHasChanged);
|
|
||||||
economyService.Subscribe(StateHasChanged);
|
|
||||||
timingService.Subscribe(HandleTimingChanged);
|
|
||||||
economyService.Calculate(buildOrderService, timingService, 0);
|
economyService.Calculate(buildOrderService, timingService, 0);
|
||||||
|
|
||||||
|
keyService.Subscribe(HandleClick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
keyService.Unsubscribe(HandleClick);
|
keyService.Unsubscribe(HandleClick);
|
||||||
filterService.Unsubscribe(StateHasChanged);
|
|
||||||
timingService.Unsubscribe(StateHasChanged);
|
|
||||||
economyService.Unsubscribe(StateHasChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void HandleTimingChanged()
|
|
||||||
{
|
|
||||||
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void HandleClick()
|
private void HandleClick()
|
||||||
{
|
{
|
||||||
var hotkey = keyService.GetHotkey();
|
var hotkey = keyService.GetHotkey();
|
||||||
@@ -254,7 +246,6 @@
|
|||||||
{
|
{
|
||||||
buildOrderService.RemoveLast();
|
buildOrderService.RemoveLast();
|
||||||
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
||||||
StateHasChanged();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -275,5 +266,4 @@
|
|||||||
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
@inject IBuildOrderService BuildOrder
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<FormLayoutComponent>
|
<FormLayoutComponent>
|
||||||
<FormDisplayComponent Label="Army ready at">
|
<FormDisplayComponent Label="Army ready at">
|
||||||
@@ -22,8 +26,6 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IBuildOrderService BuildOrder { get; set; } = default!;
|
|
||||||
|
|
||||||
private int lastInterval;
|
private int lastInterval;
|
||||||
|
|
||||||
@@ -41,8 +43,29 @@
|
|||||||
BuildOrder.Unsubscribe(OnBuildOrderChanged);
|
BuildOrder.Unsubscribe(OnBuildOrderChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "ArmyComponent");
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "ArmyComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void OnBuildOrderChanged()
|
void OnBuildOrderChanged()
|
||||||
{
|
{
|
||||||
|
int armyCountWas = 0;
|
||||||
|
foreach (var army in armyCount)
|
||||||
|
{
|
||||||
|
armyCountWas += army.Value;
|
||||||
|
}
|
||||||
|
|
||||||
armyCount.Clear();
|
armyCount.Clear();
|
||||||
|
|
||||||
lastInterval = 0;
|
lastInterval = 0;
|
||||||
@@ -68,7 +91,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
//TODO Better
|
||||||
|
int armyCountIs = 0;
|
||||||
|
foreach (var army in armyCount)
|
||||||
|
{
|
||||||
|
armyCountIs += army.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (armyCountWas != armyCountIs)
|
||||||
|
{
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
@inject IEconomyService economyService
|
||||||
|
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<FormLayoutComponent>
|
<FormLayoutComponent>
|
||||||
<FormDisplayComponent Label="Time">
|
<FormDisplayComponent Label="Time">
|
||||||
@@ -10,11 +15,6 @@
|
|||||||
<FormDisplayComponent Label="Ether">
|
<FormDisplayComponent Label="Ether">
|
||||||
<Display>@economy.Ether</Display>
|
<Display>@economy.Ether</Display>
|
||||||
</FormDisplayComponent>
|
</FormDisplayComponent>
|
||||||
<DevOnlyComponent>
|
|
||||||
<FormDisplayComponent Label="Pyre">
|
|
||||||
<Display>@economy.Pyre</Display>
|
|
||||||
</FormDisplayComponent>
|
|
||||||
</DevOnlyComponent>
|
|
||||||
<FormDisplayComponent Label="Supply">
|
<FormDisplayComponent Label="Supply">
|
||||||
<Display>@supplyTaken / @supplyGranted (@(supplyGranted / 16)@(extraBuildings > 0 ? "+" + extraBuildings : ""))</Display>
|
<Display>@supplyTaken / @supplyGranted (@(supplyGranted / 16)@(extraBuildings > 0 ? "+" + extraBuildings : ""))</Display>
|
||||||
</FormDisplayComponent>
|
</FormDisplayComponent>
|
||||||
@@ -36,13 +36,27 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
BuildOrderService.Subscribe(OnBuildOrderChanged);
|
BuildOrderService.Subscribe(OnBuildOrderChanged);
|
||||||
EconomyService.Subscribe(OnBuildOrderChanged);
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "BankComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "BankComponent");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
BuildOrderService.Unsubscribe(OnBuildOrderChanged);
|
BuildOrderService.Unsubscribe(OnBuildOrderChanged);
|
||||||
EconomyService.Subscribe(OnBuildOrderChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnBuildOrderChanged()
|
void OnBuildOrderChanged()
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
@inject IBuildOrderService buildOrderService
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
|
||||||
|
@inject IBuildOrderService buildOrderService
|
||||||
|
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
|
|
||||||
@@ -21,4 +24,19 @@
|
|||||||
buildOrderService.Unsubscribe(StateHasChanged);
|
buildOrderService.Unsubscribe(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "BuildOrderComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "BuildOrderComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,38 @@
|
|||||||
@implements IDisposable
|
@inject IEconomyService economyService
|
||||||
|
@inject IBuildOrderService buildOrderService
|
||||||
|
@inject IJSRuntime jsRuntime;
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<div class="chartsContainer">
|
@if (lastRequestedRefreshIndex != requestedRefreshIndex)
|
||||||
@foreach (var chart in charts)
|
{
|
||||||
{
|
<LoadingComponent/>
|
||||||
<div style="width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
|
|
||||||
<div style="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)
|
else
|
||||||
{
|
{
|
||||||
<div style="position: absolute;
|
<div class="chartsContainer">
|
||||||
|
@foreach (var chart in charts)
|
||||||
|
{
|
||||||
|
<div style="width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
|
||||||
|
<div style="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)
|
||||||
|
{
|
||||||
|
<div style="position: absolute;
|
||||||
bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px;
|
bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px;
|
||||||
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
|
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
|
||||||
width: 0px;
|
width: 0px;
|
||||||
height: 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 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>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
}
|
||||||
}
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.chartsContainer {
|
.chartsContainer {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -30,34 +41,31 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<FormLayoutComponent>
|
<FormLayoutComponent>
|
||||||
<FormDisplayComponent Label="Highest Alloy">
|
<FormDisplayComponent Label="Highest Alloy">
|
||||||
<Display>@highestAlloyPoint</Display>
|
<Display>@highestAlloyPoint</Display>
|
||||||
</FormDisplayComponent>
|
</FormDisplayComponent>
|
||||||
<FormDisplayComponent Label="Highest Ether">
|
<FormDisplayComponent Label="Highest Ether">
|
||||||
<Display>@highestEtherPoint</Display>
|
|
||||||
</FormDisplayComponent>
|
|
||||||
<DevOnlyComponent>
|
|
||||||
<FormDisplayComponent Label="Highest Pyre">
|
|
||||||
<Display>@highestEtherPoint</Display>
|
<Display>@highestEtherPoint</Display>
|
||||||
</FormDisplayComponent>
|
</FormDisplayComponent>
|
||||||
</DevOnlyComponent>
|
<DevOnlyComponent>
|
||||||
<FormDisplayComponent Label="Highest Army">
|
<FormDisplayComponent Label="Highest Pyre">
|
||||||
<Display>@highestArmyPoint</Display>
|
<Display>@highestEtherPoint</Display>
|
||||||
</FormDisplayComponent>
|
</FormDisplayComponent>
|
||||||
</FormLayoutComponent>
|
</DevOnlyComponent>
|
||||||
|
<FormDisplayComponent Label="Highest Army">
|
||||||
|
<Display>@highestArmyPoint</Display>
|
||||||
|
</FormDisplayComponent>
|
||||||
|
</FormLayoutComponent>
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Inject]
|
|
||||||
IEconomyService EconomyService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
IBuildOrderService BuildOrderService { get; set; } = default!;
|
|
||||||
|
|
||||||
private readonly int width = 250;
|
private readonly int width = 250;
|
||||||
|
|
||||||
List<int> valueList = new();
|
List<int> valueList = new();
|
||||||
@@ -70,23 +78,75 @@
|
|||||||
float highestPyrePoint;
|
float highestPyrePoint;
|
||||||
float highestArmyPoint;
|
float highestArmyPoint;
|
||||||
|
|
||||||
|
private Timer ageTimer = null!;
|
||||||
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
EconomyService.Subscribe(GenerateChart);
|
buildOrderService.Subscribe(OnBuilderOrderChanged);
|
||||||
BuildOrderService.Subscribe(GenerateChart);
|
|
||||||
|
|
||||||
|
ageTimer = new Timer(3000);
|
||||||
|
ageTimer.Elapsed += OnAge!;
|
||||||
|
ageTimer.Enabled = true;
|
||||||
|
|
||||||
|
|
||||||
GenerateChart();
|
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()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
EconomyService.Unsubscribe(GenerateChart);
|
buildOrderService.Unsubscribe(OnBuilderOrderChanged);
|
||||||
BuildOrderService.Unsubscribe(GenerateChart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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()
|
void GenerateChart()
|
||||||
{
|
{
|
||||||
var economyOverTime = EconomyService.GetOverTime();
|
var economyOverTime = economyService.GetOverTime();
|
||||||
|
|
||||||
charts.Clear();
|
charts.Clear();
|
||||||
|
|
||||||
@@ -127,7 +187,7 @@
|
|||||||
|
|
||||||
for (var interval = 0; interval < economyOverTime.Count(); interval++)
|
for (var interval = 0; interval < economyOverTime.Count(); interval++)
|
||||||
{
|
{
|
||||||
var army = from unit in BuildOrderService.GetCompletedBefore(interval)
|
var army = from unit in buildOrderService.GetCompletedBefore(interval)
|
||||||
where unit.EntityType == EntityType.Army
|
where unit.EntityType == EntityType.Army
|
||||||
select unit;
|
select unit;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
|
||||||
|
@inject IKeyService keyService
|
||||||
|
@inject IImmortalSelectionService filterService
|
||||||
|
@inject IBuildOrderService buildOrderService
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
@if (entity != null)
|
@if (entity != null)
|
||||||
{
|
{
|
||||||
@@ -20,48 +27,45 @@
|
|||||||
private EntityModel? entity = default!;
|
private EntityModel? entity = default!;
|
||||||
private string viewType = "Detailed";
|
private string viewType = "Detailed";
|
||||||
|
|
||||||
[Inject]
|
|
||||||
IKeyService KeyService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
IImmortalSelectionService FilterService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
IBuildOrderService BuildOrderService { get; set; } = default!;
|
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
KeyService.Subscribe(HandleClick);
|
keyService.Subscribe(HandleClick);
|
||||||
BuildOrderService.Subscribe(OnBuildOrderChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
KeyService.Unsubscribe(HandleClick);
|
keyService.Unsubscribe(HandleClick);
|
||||||
BuildOrderService.Unsubscribe(OnBuildOrderChanged);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
protected void HandleClick()
|
|
||||||
{
|
{
|
||||||
var hotkey = KeyService.GetHotkey();
|
#if DEBUG
|
||||||
var hotkeyGroup = KeyService.GetHotkeyGroup();
|
jsRuntime.InvokeVoidAsync("console.time", "EntityClickViewComponent");
|
||||||
var isHoldSpace = KeyService.IsHoldingSpace();
|
#endif
|
||||||
var faction = FilterService.GetFactionType();
|
return true;
|
||||||
var immortal = FilterService.GetImmortalType();
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "EntityClickViewComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleClick()
|
||||||
|
{
|
||||||
|
var hotkey = keyService.GetHotkey();
|
||||||
|
var hotkeyGroup = keyService.GetHotkeyGroup();
|
||||||
|
var isHoldSpace = keyService.IsHoldingSpace();
|
||||||
|
var faction = filterService.GetFactionType();
|
||||||
|
var immortal = filterService.GetImmortalType();
|
||||||
|
|
||||||
var foundEntity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal);
|
var foundEntity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal);
|
||||||
|
|
||||||
if (foundEntity != null)
|
if (foundEntity != null && entity != foundEntity)
|
||||||
{
|
{
|
||||||
entity = foundEntity;
|
entity = foundEntity;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnBuildOrderChanged()
|
|
||||||
{
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
<FormLayoutComponent>
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
<FormLayoutComponent>
|
||||||
<FormSelectComponent OnChange="@OnFactionChanged">
|
<FormSelectComponent OnChange="@OnFactionChanged">
|
||||||
<FormLabelComponent>Faction</FormLabelComponent>
|
<FormLabelComponent>Faction</FormLabelComponent>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
@@ -39,4 +41,19 @@
|
|||||||
FilterService.SelectImmortalType(e.Value!.ToString()!);
|
FilterService.SelectImmortalType(e.Value!.ToString()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "FilterComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "FilterComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,40 +1,37 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<div class="highlightsContainer">
|
<div class="highlightsContainer">
|
||||||
<div>
|
<div>
|
||||||
<div>Requested</div>
|
<div>Requested</div>
|
||||||
|
|
||||||
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
|
@foreach (var ordersAtTime in BuildOrderService.StartedOrders.Reverse()) {
|
||||||
{
|
foreach (var order in ordersAtTime.Value)
|
||||||
@foreach (var order in BuildOrderService.GetOrdersAt(i))
|
{
|
||||||
{
|
<div>
|
||||||
if (order.EntityType == EntityType.Worker)
|
|
||||||
{
|
@ordersAtTime.Key | T @Interval.ToTime(ordersAtTime.Key)
|
||||||
continue;
|
</div>
|
||||||
|
<div>
|
||||||
|
@order.Info().Name
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<div>
|
|
||||||
@i | T @Interval.ToTime(i)
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
@order.Info().Name
|
|
||||||
</div>
|
|
||||||
<br/>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div>Finished</div>
|
<div>Finished</div>
|
||||||
|
|
||||||
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
|
@foreach (var ordersAtTime in BuildOrderService.CompletedOrders.Reverse())
|
||||||
{
|
{
|
||||||
@foreach (var order in BuildOrderService.GetCompletedAt(i))
|
foreach (var order in ordersAtTime.Value)
|
||||||
{
|
{
|
||||||
if (order.EntityType == EntityType.Worker)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
<div>
|
<div>
|
||||||
@i | T @Interval.ToTime(i)
|
|
||||||
|
@ordersAtTime.Key | T @Interval.ToTime(ordersAtTime.Key)
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@order.Info().Name
|
@order.Info().Name
|
||||||
@@ -79,5 +76,21 @@
|
|||||||
EconomyService.Unsubscribe(StateHasChanged);
|
EconomyService.Unsubscribe(StateHasChanged);
|
||||||
BuildOrderService.Unsubscribe(StateHasChanged);
|
BuildOrderService.Unsubscribe(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "HighlightsComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "HighlightsComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,14 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
@inject IKeyService keyService
|
||||||
|
@inject IBuildOrderService buildOrderService
|
||||||
|
@inject IImmortalSelectionService filterService
|
||||||
|
|
||||||
|
@inject IEconomyService economyService
|
||||||
|
@inject ITimingService timingService
|
||||||
|
@inject IToastService toastService
|
||||||
|
|
||||||
|
|
||||||
<InputPanelComponent>
|
<InputPanelComponent>
|
||||||
<div class="keyContainer">
|
<div class="keyContainer">
|
||||||
@@ -9,7 +19,7 @@
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var color = hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace() || KeyService.GetAllPressedKeys().Contains(hotkey.KeyText)
|
var color = hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace() || keyService.GetAllPressedKeys().Contains(hotkey.KeyText)
|
||||||
? "#0a0f12" : hotkey.GetColor();
|
? "#0a0f12" : hotkey.GetColor();
|
||||||
|
|
||||||
var x = hotkey.PositionX * Size;
|
var x = hotkey.PositionX * Size;
|
||||||
@@ -25,7 +35,7 @@
|
|||||||
border = "5px solid green";
|
border = "5px solid green";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace())
|
if (hotkey.KeyText.Equals("SPACE") && keyService.IsHoldingSpace())
|
||||||
{
|
{
|
||||||
border = "5px solid green";
|
border = "5px solid green";
|
||||||
}
|
}
|
||||||
@@ -37,7 +47,7 @@
|
|||||||
width: 0px;
|
width: 0px;
|
||||||
height: 0px;">
|
height: 0px;">
|
||||||
|
|
||||||
<div @onclick="x => { if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString())) { if (KeyService.IsHoldingSpace()) { KeyService.RemovePressedKey(hotkey.KeyText); } else { KeyService.AddPressedKey(hotkey.KeyText); } } else { KeyService.AddPressedKey(hotkey.KeyText); KeyService.RemovePressedKey(hotkey.KeyText); }}" style="background-color:@color;
|
<div @onclick="x => { if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString())) { if (keyService.IsHoldingSpace()) { keyService.RemovePressedKey(hotkey.KeyText); } else { keyService.AddPressedKey(hotkey.KeyText); } } else { keyService.AddPressedKey(hotkey.KeyText); keyService.RemovePressedKey(hotkey.KeyText); }}" style="background-color:@color;
|
||||||
border: @border;
|
border: @border;
|
||||||
width: @Size.ToString()px;
|
width: @Size.ToString()px;
|
||||||
height: @Size.ToString()px;
|
height: @Size.ToString()px;
|
||||||
@@ -46,7 +56,7 @@
|
|||||||
@hotkey.KeyText
|
@hotkey.KeyText
|
||||||
@foreach (var entity in data.Values)
|
@foreach (var entity in data.Values)
|
||||||
{
|
{
|
||||||
if (!BuildOrderService.MeetsRequirements(entity, 9000))
|
if (buildOrderService.WillMeetRequirements(entity) == null)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -97,15 +107,6 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public int Size { get; set; } = 100;
|
public int Size { get; set; } = 100;
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IKeyService KeyService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IBuildOrderService BuildOrderService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IImmortalSelectionService FilterService { get; set; } = default!;
|
|
||||||
|
|
||||||
readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary();
|
readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary();
|
||||||
readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll();
|
readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll();
|
||||||
|
|
||||||
@@ -116,20 +117,48 @@
|
|||||||
{
|
{
|
||||||
base.OnInitialized();
|
base.OnInitialized();
|
||||||
|
|
||||||
KeyService.Subscribe(OnKeyPressed);
|
keyService.Subscribe(OnKeyPressed);
|
||||||
FilterService.Subscribe(StateHasChanged);
|
filterService.Subscribe(StateHasChanged);
|
||||||
|
buildOrderService.Subscribe(OnBuilderOrderChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
{
|
{
|
||||||
KeyService.Unsubscribe(OnKeyPressed);
|
keyService.Unsubscribe(OnKeyPressed);
|
||||||
FilterService.Unsubscribe(StateHasChanged);
|
filterService.Unsubscribe(StateHasChanged);
|
||||||
|
buildOrderService.Unsubscribe(OnBuilderOrderChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
int completedTimeCount = 0;
|
||||||
|
void OnBuilderOrderChanged()
|
||||||
|
{
|
||||||
|
if (buildOrderService.UniqueCompletedTimes.Count != completedTimeCount)
|
||||||
|
{
|
||||||
|
completedTimeCount = buildOrderService.UniqueCompletedTimes.Count;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "HotKeyViewerComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "HotKeyViewerComponent");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move to Filter Service
|
// Move to Filter Service
|
||||||
bool InvalidFaction(EntityModel entity)
|
bool InvalidFaction(EntityModel entity)
|
||||||
{
|
{
|
||||||
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFactionType() && FilterService.GetFactionType() != FactionType.Any)
|
if (entity.Faction() != null && entity.Faction()?.Faction != filterService.GetFactionType() && filterService.GetFactionType() != FactionType.Any)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -140,7 +169,7 @@
|
|||||||
// Move to Filter Service
|
// Move to Filter Service
|
||||||
bool InvalidVanguard(EntityModel entity)
|
bool InvalidVanguard(EntityModel entity)
|
||||||
{
|
{
|
||||||
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortalType() && FilterService.GetImmortalType() != ImmortalType.Any)
|
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != filterService.GetImmortalType() && filterService.GetImmortalType() != ImmortalType.Any)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -156,7 +185,7 @@
|
|||||||
var isReplaced = false;
|
var isReplaced = false;
|
||||||
foreach (var replaced in entity.Replaceds())
|
foreach (var replaced in entity.Replaceds())
|
||||||
{
|
{
|
||||||
if (FilterService.GetImmortalType() == replaced.ImmortalId)
|
if (filterService.GetImmortalType() == replaced.ImmortalId)
|
||||||
{
|
{
|
||||||
isReplaced = true;
|
isReplaced = true;
|
||||||
break;
|
break;
|
||||||
@@ -171,11 +200,6 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InvalidRequirements(EntityModel entity)
|
|
||||||
{
|
|
||||||
return !BuildOrderService.MeetsRequirements(entity, 9000);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InvalidKey(EntityModel entity, HotkeyModel key)
|
bool InvalidKey(EntityModel entity, HotkeyModel key)
|
||||||
{
|
{
|
||||||
if (entity.Hotkey()?.Hotkey == key.KeyText)
|
if (entity.Hotkey()?.Hotkey == key.KeyText)
|
||||||
@@ -215,7 +239,7 @@
|
|||||||
|
|
||||||
bool InvalidHoldSpace(EntityModel entity)
|
bool InvalidHoldSpace(EntityModel entity)
|
||||||
{
|
{
|
||||||
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace())
|
if (entity.Hotkey()?.HoldSpace == keyService.IsHoldingSpace())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -224,47 +248,93 @@
|
|||||||
|
|
||||||
void OnKeyPressed()
|
void OnKeyPressed()
|
||||||
{
|
{
|
||||||
if (KeyService.GetAllPressedKeys().Contains("Z"))
|
|
||||||
|
string controlGroupWas = _controlGroup;
|
||||||
|
string keyWas = _key;
|
||||||
|
|
||||||
|
|
||||||
|
if (keyService.GetAllPressedKeys().Contains("Z"))
|
||||||
{
|
{
|
||||||
_controlGroup = "Z";
|
_controlGroup = "Z";
|
||||||
}
|
}
|
||||||
if (KeyService.GetAllPressedKeys().Contains("TAB"))
|
if (keyService.GetAllPressedKeys().Contains("TAB"))
|
||||||
{
|
{
|
||||||
_controlGroup = "TAB";
|
_controlGroup = "TAB";
|
||||||
}
|
}
|
||||||
if (KeyService.GetAllPressedKeys().Contains("C"))
|
if (keyService.GetAllPressedKeys().Contains("C"))
|
||||||
{
|
{
|
||||||
_controlGroup = "C";
|
_controlGroup = "C";
|
||||||
}
|
}
|
||||||
if (KeyService.GetAllPressedKeys().Contains("D"))
|
if (keyService.GetAllPressedKeys().Contains("D"))
|
||||||
{
|
{
|
||||||
_controlGroup = "D";
|
_controlGroup = "D";
|
||||||
}
|
}
|
||||||
if (KeyService.GetAllPressedKeys().Contains("1"))
|
if (keyService.GetAllPressedKeys().Contains("1"))
|
||||||
{
|
{
|
||||||
_controlGroup = "1";
|
_controlGroup = "1";
|
||||||
}
|
}
|
||||||
//TODO This could be better. Duplicated code
|
//TODO This could be better. Duplicated code
|
||||||
if (KeyService.GetAllPressedKeys().Contains("2"))
|
if (keyService.GetAllPressedKeys().Contains("2"))
|
||||||
{
|
{
|
||||||
_controlGroup = "2";
|
_controlGroup = "2";
|
||||||
}
|
}
|
||||||
if (KeyService.GetAllPressedKeys().Contains("SHIFT"))
|
if (keyService.GetAllPressedKeys().Contains("SHIFT"))
|
||||||
{
|
{
|
||||||
_controlGroup = "SHIFT";
|
_controlGroup = "SHIFT";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyService.GetAllPressedKeys().Contains("CONTROL"))
|
if (keyService.GetAllPressedKeys().Contains("CONTROL"))
|
||||||
{
|
{
|
||||||
_controlGroup = "CONTROL";
|
_controlGroup = "CONTROL";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (KeyService.GetAllPressedKeys().Count > 0)
|
if (keyService.GetAllPressedKeys().Count > 0)
|
||||||
{
|
{
|
||||||
_key = KeyService.GetAllPressedKeys().First();
|
_key = keyService.GetAllPressedKeys().First();
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
// HandleClick();
|
||||||
}
|
|
||||||
|
|
||||||
|
if (controlGroupWas != _controlGroup || keyWas != _key)
|
||||||
|
{
|
||||||
|
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void HandleClick()
|
||||||
|
{
|
||||||
|
var hotkey = keyService.GetHotkey();
|
||||||
|
|
||||||
|
if (hotkey == "")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hotkey == "`")
|
||||||
|
{
|
||||||
|
buildOrderService.RemoveLast();
|
||||||
|
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var hotkeyGroup = keyService.GetHotkeyGroup();
|
||||||
|
var isHoldSpace = keyService.IsHoldingSpace();
|
||||||
|
var faction = filterService.GetFactionType();
|
||||||
|
var immortal = filterService.GetImmortalType();
|
||||||
|
|
||||||
|
EntityModel? entity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal);
|
||||||
|
|
||||||
|
if (entity == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buildOrderService.Add(entity, economyService, toastService))
|
||||||
|
{
|
||||||
|
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
<div tabindex="0"
|
@inject IKeyService keyService
|
||||||
|
|
||||||
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
|
||||||
|
<div tabindex="0"
|
||||||
style="margin: auto;"
|
style="margin: auto;"
|
||||||
@onkeydown="HandleKeyDown"
|
@onkeydown="HandleKeyDown"
|
||||||
@onkeyup="HandleKeyUp"
|
@onkeyup="HandleKeyUp"
|
||||||
@@ -8,21 +13,32 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment ChildContent { get; set; } = default!;
|
public RenderFragment ChildContent { get; set; } = default!;
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IKeyService KeyService { get; set; } = default!;
|
|
||||||
|
|
||||||
private void HandleKeyDown(KeyboardEventArgs e)
|
private void HandleKeyDown(KeyboardEventArgs e)
|
||||||
{
|
{
|
||||||
KeyService.AddPressedKey(e.Key);
|
keyService.AddPressedKey(e.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleKeyUp(KeyboardEventArgs e)
|
private void HandleKeyUp(KeyboardEventArgs e)
|
||||||
{
|
{
|
||||||
KeyService.RemovePressedKey(e.Key);
|
keyService.RemovePressedKey(e.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "InputPanelComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "InputPanelComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
@implements IDisposable
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
|
||||||
|
@implements IDisposable
|
||||||
|
|
||||||
<Virtualize Items="@EconomyService.GetOverTime()" Context="economyAtSecond" ItemSize="400" OverscanCount="4">
|
<Virtualize Items="@EconomyService.GetOverTime()" Context="economyAtSecond" ItemSize="400" OverscanCount="4">
|
||||||
<div style="display: grid; gap: 8px; grid-template-columns: 1fr 1fr;">
|
<div style="display: grid; gap: 8px; grid-template-columns: 1fr 1fr;">
|
||||||
@@ -24,17 +27,26 @@
|
|||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@foreach (var order in BuildOrderService.GetOrdersAt(economyAtSecond.Interval))
|
|
||||||
|
@if (BuildOrderService.StartedOrders.TryGetValue(economyAtSecond.Interval, out var ordersAtTime))
|
||||||
{
|
{
|
||||||
<div>
|
@foreach (var order in ordersAtTime)
|
||||||
Requested: @order.Info().Name
|
{
|
||||||
</div>
|
<div>
|
||||||
|
Requested: @order.Info().Name
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@foreach (var order in BuildOrderService.GetCompletedAt(economyAtSecond.Interval))
|
|
||||||
|
|
||||||
|
@if (BuildOrderService.CompletedOrders.TryGetValue(economyAtSecond.Interval, out var ordersCompletedAtTime))
|
||||||
{
|
{
|
||||||
<div>
|
@foreach (var order in ordersCompletedAtTime)
|
||||||
New: @order.Info().Name
|
{
|
||||||
</div>
|
<div>
|
||||||
|
New: @order.Info().Name
|
||||||
|
</div>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,5 +72,21 @@
|
|||||||
EconomyService.Unsubscribe(StateHasChanged);
|
EconomyService.Unsubscribe(StateHasChanged);
|
||||||
BuildOrderService.Unsubscribe(StateHasChanged);
|
BuildOrderService.Unsubscribe(StateHasChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "TimelineComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "TimelineComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,55 +1,69 @@
|
|||||||
<FormLayoutComponent>
|
@inject IJSRuntime jsRuntime;
|
||||||
|
|
||||||
|
@inject IBuildOrderService buildOrderService
|
||||||
|
@inject IEconomyService economyService
|
||||||
|
@inject IToastService toastService
|
||||||
|
@inject ITimingService timingService
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<FormLayoutComponent>
|
||||||
<FormNumberComponent ReadOnly="true"
|
<FormNumberComponent ReadOnly="true"
|
||||||
Max="600"
|
Max="600"
|
||||||
Min="0"
|
Min="0"
|
||||||
Value="@TimingService.GetTiming()"
|
Value="@timingService.GetTiming()"
|
||||||
OnChange="@OnTimingChanged">
|
OnChange="@OnTimingChanged">
|
||||||
<FormLabelComponent>Timing interval</FormLabelComponent>
|
<FormLabelComponent>Timing interval</FormLabelComponent>
|
||||||
<FormInfoComponent>Altering the time interval is currently disabled.</FormInfoComponent>
|
<FormInfoComponent>Altering the time interval is currently disabled.</FormInfoComponent>
|
||||||
</FormNumberComponent>
|
</FormNumberComponent>
|
||||||
|
|
||||||
<FormTextComponent Label="Name" Placeholder="Fast Thrones..." Value="@BuildOrderService.GetName()" OnChange="OnNameChanged"/>
|
<FormTextComponent Label="Name" Placeholder="Fast Thrones..." Value="@buildOrderService.GetName()" OnChange="OnNameChanged"/>
|
||||||
|
|
||||||
<FormTextAreaComponent Label="Notes"
|
<FormTextAreaComponent Label="Notes"
|
||||||
Value="@BuildOrderService.GetNotes()"
|
Value="@buildOrderService.GetNotes()"
|
||||||
OnChange="@OnNotesChanged">
|
OnChange="@OnNotesChanged">
|
||||||
</FormTextAreaComponent>
|
</FormTextAreaComponent>
|
||||||
<FormTextComponent Label="Color" Placeholder="red..." Value="@BuildOrderService.GetColor()" OnChange="OnColorChanged"/>
|
<FormTextComponent Label="Color" Placeholder="red..." Value="@buildOrderService.GetColor()" OnChange="OnColorChanged"/>
|
||||||
</FormLayoutComponent>
|
</FormLayoutComponent>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public ITimingService TimingService { get; set; } = default!;
|
|
||||||
|
|
||||||
[Inject]
|
|
||||||
public IBuildOrderService BuildOrderService { get; set; } = default!;
|
|
||||||
|
|
||||||
|
|
||||||
void OnTimingChanged(ChangeEventArgs changeEventArgs)
|
void OnTimingChanged(ChangeEventArgs changeEventArgs)
|
||||||
{
|
{
|
||||||
TimingService.SetTiming(int.Parse(changeEventArgs.Value!.ToString()!));
|
timingService.SetTiming(int.Parse(changeEventArgs.Value!.ToString()!));
|
||||||
}
|
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
|
||||||
|
|
||||||
void OnTimingChanged(int value)
|
|
||||||
{
|
|
||||||
TimingService.SetTiming(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnNameChanged(ChangeEventArgs changeEventArgs)
|
void OnNameChanged(ChangeEventArgs changeEventArgs)
|
||||||
{
|
{
|
||||||
BuildOrderService.SetName(changeEventArgs.Value!.ToString()!);
|
buildOrderService.SetName(changeEventArgs.Value!.ToString()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnColorChanged(ChangeEventArgs changeEventArgs)
|
void OnColorChanged(ChangeEventArgs changeEventArgs)
|
||||||
{
|
{
|
||||||
BuildOrderService.SetColor(changeEventArgs.Value!.ToString()!);
|
buildOrderService.SetColor(changeEventArgs.Value!.ToString()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OnNotesChanged(ChangeEventArgs changeEventArgs)
|
void OnNotesChanged(ChangeEventArgs changeEventArgs)
|
||||||
{
|
{
|
||||||
BuildOrderService.SetNotes(changeEventArgs.Value!.ToString()!);
|
buildOrderService.SetNotes(changeEventArgs.Value!.ToString()!);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldRender()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.time", "TimingComponent");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
jsRuntime.InvokeVoidAsync("console.timeEnd", "TimingComponent");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,6 @@ builder.Services.AddSingleton<IEconomyService, EconomyService>();
|
|||||||
builder.Services.AddSingleton<ITimingService, TimingService>();
|
builder.Services.AddSingleton<ITimingService, TimingService>();
|
||||||
builder.Services.AddSingleton<IMemoryTesterService, MemoryTesterService>();
|
builder.Services.AddSingleton<IMemoryTesterService, MemoryTesterService>();
|
||||||
builder.Services.AddSingleton<IEntityFilterService, EntityFilterService>();
|
builder.Services.AddSingleton<IEntityFilterService, EntityFilterService>();
|
||||||
builder.Services.AddSingleton<IGameLogicService, GameLogicService>();
|
|
||||||
builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>();
|
builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>();
|
||||||
builder.Services.AddSingleton<IEntityDialogService, EntityDialogService>();
|
builder.Services.AddSingleton<IEntityDialogService, EntityDialogService>();
|
||||||
builder.Services.AddSingleton<IToastService, ToastService>();
|
builder.Services.AddSingleton<IToastService, ToastService>();
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ public class BuildOrderModel
|
|||||||
{
|
{
|
||||||
public string Name { get; set; } = "";
|
public string Name { get; set; } = "";
|
||||||
public string Color { get; set; } = "red";
|
public string Color { get; set; } = "red";
|
||||||
|
|
||||||
|
public int CurrentSupplyUsed { get; set; } = 0;
|
||||||
|
|
||||||
public Dictionary<int, List<EntityModel>> StartedOrders { get; set; } = new()
|
public Dictionary<int, List<EntityModel>> StartedOrders { get; set; } = new()
|
||||||
{
|
{
|
||||||
@@ -33,28 +35,28 @@ public class BuildOrderModel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public Dictionary<string, int> UniqueCompletedTimes { get; set; } = new()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
DataType.STARTING_Bastion, 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Dictionary<int, int> SupplyCountTimes { get; set; } = new()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
0, 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public string Notes { get; set; } = @"";
|
public string Notes { get; set; } = @"";
|
||||||
|
|
||||||
public List<string> BuildTypes { get; set; } = new();
|
public List<string> BuildTypes { get; set; } = new();
|
||||||
|
|
||||||
|
|
||||||
public List<EntityModel> GetOrdersAt(int interval)
|
|
||||||
{
|
|
||||||
return (from ordersAtTime in StartedOrders
|
|
||||||
from orders in ordersAtTime.Value
|
|
||||||
where ordersAtTime.Key == interval
|
|
||||||
select orders).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EntityModel> GetCompletedAt(int interval)
|
|
||||||
{
|
|
||||||
return (from ordersAtTime in StartedOrders
|
|
||||||
from orders in ordersAtTime.Value
|
|
||||||
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) == interval
|
|
||||||
select orders).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EntityModel> GetCompletedBefore(int interval)
|
public List<EntityModel> GetCompletedBefore(int interval)
|
||||||
{
|
{
|
||||||
return (from ordersAtTime in StartedOrders
|
return (from ordersAtTime in StartedOrders
|
||||||
|
|||||||
@@ -99,8 +99,8 @@ public class EconomyOverTimeModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove Funds from Build Order
|
// Remove Funds from Build Order
|
||||||
var ordersAtTime = buildOrder.GetOrdersAt(interval);
|
if (buildOrder.StartedOrders.TryGetValue(interval, out var ordersAtTime))
|
||||||
|
{
|
||||||
foreach (var order in ordersAtTime)
|
foreach (var order in ordersAtTime)
|
||||||
{
|
{
|
||||||
var foundEntity = EntityModel.GetDictionary()[order.DataType];
|
var foundEntity = EntityModel.GetDictionary()[order.DataType];
|
||||||
@@ -115,16 +115,20 @@ public class EconomyOverTimeModel
|
|||||||
if (production.RequiresWorker) economyAtSecond.BusyWorkerCount += 1;
|
if (production.RequiresWorker) economyAtSecond.BusyWorkerCount += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Handle new entities
|
// Handle new entities
|
||||||
var completedAtInterval = buildOrder.GetCompletedAt(interval);
|
if (buildOrder.StartedOrders.TryGetValue(interval, out var ordersCompletedAtTime))
|
||||||
foreach (var newEntity in completedAtInterval)
|
|
||||||
{
|
{
|
||||||
var harvest = newEntity;
|
foreach (var newEntity in ordersCompletedAtTime)
|
||||||
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
|
{
|
||||||
|
var harvest = newEntity;
|
||||||
|
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
|
||||||
|
|
||||||
var production = newEntity.Production();
|
var production = newEntity.Production();
|
||||||
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
|
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-16
@@ -1435,10 +1435,7 @@ public class DATA
|
|||||||
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB" })
|
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB" })
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 100 })
|
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 100 })
|
||||||
.AddPart(new EntityRequirementModel
|
|
||||||
{
|
|
||||||
Requirement = RequirementType.Production_Building
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -1465,10 +1462,7 @@ public class DATA
|
|||||||
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB", HoldSpace = true})
|
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB", HoldSpace = true})
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 43 })
|
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 43 })
|
||||||
.AddPart(new EntityRequirementModel
|
|
||||||
{
|
|
||||||
Requirement = RequirementType.Production_Building
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -1482,10 +1476,7 @@ public class DATA
|
|||||||
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB" })
|
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "TAB" })
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 50, Ether = 100, BuildTime = 60 })
|
.AddPart(new EntityProductionModel { Alloy = 50, Ether = 100, BuildTime = 60 })
|
||||||
.AddPart(new EntityRequirementModel
|
|
||||||
{
|
|
||||||
Requirement = RequirementType.Production_Building
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
DataType.UPGRADE_RelicOfTheWrathfulGaze,
|
DataType.UPGRADE_RelicOfTheWrathfulGaze,
|
||||||
@@ -1512,7 +1503,7 @@ public class DATA
|
|||||||
.AddPart(new EntityHotkeyModel { Hotkey = "W", HotkeyGroup = "TAB" })
|
.AddPart(new EntityHotkeyModel { Hotkey = "W", HotkeyGroup = "TAB" })
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 50, Ether = 75, BuildTime = 55 })
|
.AddPart(new EntityProductionModel { Alloy = 50, Ether = 75, BuildTime = 55 })
|
||||||
.AddPart(new EntityRequirementModel { Requirement = RequirementType.Production_Building })
|
.AddPart(new EntityRequirementModel { Id = DataType.BUILDING_Reliquary, Requirement = RequirementType.Production_Building })
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
DataType.UPGRADE_ZephyrRange,
|
DataType.UPGRADE_ZephyrRange,
|
||||||
@@ -1525,7 +1516,7 @@ public class DATA
|
|||||||
.AddPart(new EntityHotkeyModel { Hotkey = "E", HotkeyGroup = "TAB" })
|
.AddPart(new EntityHotkeyModel { Hotkey = "E", HotkeyGroup = "TAB" })
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 150, Ether = 100, BuildTime = 43 })
|
.AddPart(new EntityProductionModel { Alloy = 150, Ether = 100, BuildTime = 43 })
|
||||||
.AddPart(new EntityRequirementModel { Requirement = RequirementType.Production_Building })
|
.AddPart(new EntityRequirementModel { Id = DataType.UPGRADE_ZephyrRange, Requirement = RequirementType.Production_Building })
|
||||||
.AddPart(new EntityIdUpgradeModel { Id = DataType.UPGRADE_WindStep })
|
.AddPart(new EntityIdUpgradeModel { Id = DataType.UPGRADE_WindStep })
|
||||||
.AddPart(new EntityIdUpgradeModel { Id = DataType.UPGRADE_ZephyrRange })
|
.AddPart(new EntityIdUpgradeModel { Id = DataType.UPGRADE_ZephyrRange })
|
||||||
},
|
},
|
||||||
@@ -1559,6 +1550,7 @@ public class DATA
|
|||||||
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 43 })
|
.AddPart(new EntityProductionModel { Alloy = 100, Ether = 100, BuildTime = 43 })
|
||||||
.AddPart(new EntityRequirementModel
|
.AddPart(new EntityRequirementModel
|
||||||
{
|
{
|
||||||
|
Id = DataType.BUILDING_EyeOfAros,
|
||||||
Requirement = RequirementType.Production_Building
|
Requirement = RequirementType.Production_Building
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@@ -2632,7 +2624,7 @@ public class DATA
|
|||||||
.AddPart(new EntityFactionModel { Faction = FactionType.Aru })
|
.AddPart(new EntityFactionModel { Faction = FactionType.Aru })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 100, BuildTime = 25 })
|
.AddPart(new EntityProductionModel { Alloy = 100, BuildTime = 25 })
|
||||||
.AddPart(new EntitySupplyModel { Takes = 6 })
|
.AddPart(new EntitySupplyModel { Takes = 6 })
|
||||||
.AddPart(new EntityRequirementModel { Requirement = RequirementType.Morph })
|
.AddPart(new EntityRequirementModel { Id = DataType.UNIT_RedSeer, Requirement = RequirementType.Morph })
|
||||||
.AddPart(new EntityVitalityModel { Health = 200, DefenseLayer = 60, Armor = ArmorType.Heavy })
|
.AddPart(new EntityVitalityModel { Health = 200, DefenseLayer = 60, Armor = ArmorType.Heavy })
|
||||||
.AddPart(new EntityMovementModel { Speed = 210, Movement = MovementType.Ground })
|
.AddPart(new EntityMovementModel { Speed = 210, Movement = MovementType.Ground })
|
||||||
.AddPart(new EntityWeaponModel
|
.AddPart(new EntityWeaponModel
|
||||||
@@ -2853,6 +2845,7 @@ public class DATA
|
|||||||
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
.AddPart(new EntityFactionModel { Faction = FactionType.QRath })
|
||||||
.AddPart(new EntityRequirementModel
|
.AddPart(new EntityRequirementModel
|
||||||
{
|
{
|
||||||
|
Id = DataType.BUILDING_Acropolis,
|
||||||
Requirement = RequirementType.Morph
|
Requirement = RequirementType.Morph
|
||||||
})
|
})
|
||||||
.AddPart(new EntityProductionModel { Alloy = 75, BuildTime = 20, RequiresWorker = false })
|
.AddPart(new EntityProductionModel { Alloy = 75, BuildTime = 20, RequiresWorker = false })
|
||||||
@@ -3245,7 +3238,9 @@ public class DATA
|
|||||||
.AddPart(new EntityInfoModel { Name = "Omnivore", Descriptive = DescriptiveType.Upgrade })
|
.AddPart(new EntityInfoModel { Name = "Omnivore", Descriptive = DescriptiveType.Upgrade })
|
||||||
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "SHIFT" })
|
.AddPart(new EntityHotkeyModel { Hotkey = "Q", HotkeyGroup = "SHIFT" })
|
||||||
.AddPart(new EntityFactionModel { Faction = FactionType.Aru })
|
.AddPart(new EntityFactionModel { Faction = FactionType.Aru })
|
||||||
.AddPart(new EntityRequirementModel { Requirement = RequirementType.Morph })
|
.AddPart(new EntityRequirementModel {
|
||||||
|
Id = DataType.DEFENSE_Aerovore,
|
||||||
|
Requirement = RequirementType.Morph })
|
||||||
.AddPart(new EntityProductionModel { Alloy = 50, BuildTime = 18, RequiresWorker = false })
|
.AddPart(new EntityProductionModel { Alloy = 50, BuildTime = 18, RequiresWorker = false })
|
||||||
.AddPart(new EntityVitalityModel
|
.AddPart(new EntityVitalityModel
|
||||||
{ Health = 400, DefenseLayer = 50, Armor = ArmorType.Heavy, IsStructure = true })
|
{ Health = 400, DefenseLayer = 50, Armor = ArmorType.Heavy, IsStructure = true })
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class EntityModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public EntitySupplyModel Supply()
|
public EntitySupplyModel? Supply()
|
||||||
{
|
{
|
||||||
return ((EntitySupplyModel)EntityParts.Find(x => x.GetType() == typeof(EntitySupplyModel))!)!;
|
return ((EntitySupplyModel)EntityParts.Find(x => x.GetType() == typeof(EntitySupplyModel))!)!;
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-14
@@ -244,18 +244,15 @@ public interface IMemoryTesterService {
|
|||||||
public void Unsubscribe(MemoryAction memoryAction);
|
public void Unsubscribe(MemoryAction memoryAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IGameLogicService
|
|
||||||
{
|
|
||||||
public bool Add(EntityModel entity, int atInterval);
|
|
||||||
public int MeetsRequirements(EntityModel entity, int interval);
|
|
||||||
public int MeetsAlloy(EntityModel entity, int interval);
|
|
||||||
public int MeetsEther(EntityModel entity, int interval);
|
|
||||||
public int MeetsPyre(EntityModel entity, int interval);
|
|
||||||
public int MeetsSupply(EntityModel entity, int interval);
|
|
||||||
public int MeetsTrainingQueue(EntityModel entity, int interval);
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IBuildOrderService {
|
public interface IBuildOrderService {
|
||||||
|
|
||||||
|
public Dictionary<int, List<EntityModel>> StartedOrders { get; }
|
||||||
|
public Dictionary<int, List<EntityModel>> CompletedOrders { get; }
|
||||||
|
public Dictionary<string, int> UniqueCompletedTimes { get; }
|
||||||
|
|
||||||
|
public Dictionary<int, int> SupplyCountTimes { get; }
|
||||||
|
|
||||||
|
|
||||||
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService toastService);
|
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService toastService);
|
||||||
public void Add(EntityModel entity, int atInterval);
|
public void Add(EntityModel entity, int atInterval);
|
||||||
|
|
||||||
@@ -268,10 +265,9 @@ public interface IBuildOrderService {
|
|||||||
public void SetColor(string Color);
|
public void SetColor(string Color);
|
||||||
public string GetColor();
|
public string GetColor();
|
||||||
|
|
||||||
public bool MeetsRequirements(EntityModel entity, int interval);
|
public int? WillMeetRequirements(EntityModel entity);
|
||||||
|
public int? WillMeetSupply(EntityModel entity);
|
||||||
public Dictionary<int, List<EntityModel>> GetOrders();
|
public Dictionary<int, List<EntityModel>> GetOrders();
|
||||||
public List<EntityModel> GetOrdersAt(int interval);
|
|
||||||
public List<EntityModel> GetCompletedAt(int interval);
|
|
||||||
public List<EntityModel> GetCompletedBefore(int interval);
|
public List<EntityModel> GetCompletedBefore(int interval);
|
||||||
public List<EntityModel> GetHarvestersCompletedBefore(int interval);
|
public List<EntityModel> GetHarvestersCompletedBefore(int interval);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Text.Json;
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Model.BuildOrders;
|
using Model.BuildOrders;
|
||||||
using Model.Entity;
|
using Model.Entity;
|
||||||
|
using Model.Entity.Data;
|
||||||
using Model.Feedback;
|
using Model.Feedback;
|
||||||
using Model.Types;
|
using Model.Types;
|
||||||
using YamlDotNet.Serialization;
|
using YamlDotNet.Serialization;
|
||||||
@@ -15,6 +16,11 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
private readonly int HumanMicro = 2;
|
private readonly int HumanMicro = 2;
|
||||||
private int lastInterval;
|
private int lastInterval;
|
||||||
|
|
||||||
|
public Dictionary<int, List<EntityModel>> StartedOrders => buildOrder.StartedOrders;
|
||||||
|
public Dictionary<int, List<EntityModel>> CompletedOrders => buildOrder.CompletedOrders;
|
||||||
|
public Dictionary<string, int> UniqueCompletedTimes => buildOrder.UniqueCompletedTimes;
|
||||||
|
public Dictionary<int, int> SupplyCountTimes => buildOrder.SupplyCountTimes;
|
||||||
|
|
||||||
public int GetLastRequestInterval()
|
public int GetLastRequestInterval()
|
||||||
{
|
{
|
||||||
return lastInterval;
|
return lastInterval;
|
||||||
@@ -38,111 +44,123 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
public void Add(EntityModel entity, int atInterval)
|
public void Add(EntityModel entity, int atInterval)
|
||||||
{
|
{
|
||||||
if (!buildOrder.StartedOrders.ContainsKey(atInterval))
|
if (!buildOrder.StartedOrders.ContainsKey(atInterval))
|
||||||
{
|
buildOrder.StartedOrders.Add(atInterval, new List<EntityModel>());
|
||||||
buildOrder.StartedOrders.Add(atInterval, new List<EntityModel> { });
|
|
||||||
}
|
|
||||||
|
|
||||||
var production = entity.Production();
|
var production = entity.Production();
|
||||||
|
|
||||||
var completedTime = atInterval;
|
var completedTime = atInterval;
|
||||||
if (production != null)
|
if (production != null) completedTime += production.BuildTime;
|
||||||
{
|
|
||||||
completedTime += production.BuildTime;
|
if (!buildOrder.CompletedOrders.ContainsKey(completedTime))
|
||||||
}
|
buildOrder.CompletedOrders.Add(completedTime, new List<EntityModel>());
|
||||||
|
|
||||||
if (!buildOrder.CompletedOrders.ContainsKey(atInterval))
|
var supply = entity.Supply();
|
||||||
{
|
|
||||||
buildOrder.CompletedOrders.Add(completedTime, new List<EntityModel> { });
|
|
||||||
}
|
|
||||||
|
|
||||||
buildOrder.StartedOrders[atInterval].Add(entity.Clone());
|
buildOrder.StartedOrders[atInterval].Add(entity.Clone());
|
||||||
buildOrder.CompletedOrders[completedTime].Add(entity.Clone());
|
buildOrder.CompletedOrders[completedTime].Add(entity.Clone());
|
||||||
|
|
||||||
|
if (!buildOrder.UniqueCompletedTimes.ContainsKey(entity.DataType))
|
||||||
|
buildOrder.UniqueCompletedTimes.Add(entity.DataType, atInterval);
|
||||||
|
|
||||||
|
if (supply != null)
|
||||||
|
{
|
||||||
|
if (!supply.Takes.Equals(0)) buildOrder.CurrentSupplyUsed += supply.Takes;
|
||||||
|
if (!supply.Grants.Equals(0))
|
||||||
|
buildOrder.SupplyCountTimes.Add(buildOrder.SupplyCountTimes.Last().Key + supply.Grants, completedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (atInterval > lastInterval) lastInterval = atInterval;
|
if (atInterval > lastInterval) lastInterval = atInterval;
|
||||||
|
|
||||||
|
NotifyDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int? WillMeetRequirements(EntityModel entity)
|
||||||
|
{
|
||||||
|
var requirements = entity.Requirements();
|
||||||
|
|
||||||
|
if (requirements.Count == 0) return 0;
|
||||||
|
|
||||||
|
var metTime = 0;
|
||||||
|
foreach (var requiredEntity in requirements)
|
||||||
|
{
|
||||||
|
if (buildOrder.UniqueCompletedTimes.TryGetValue(requiredEntity.Id, out var completedTime))
|
||||||
|
{
|
||||||
|
if (completedTime > metTime) metTime = completedTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return metTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int? WillMeetSupply(EntityModel entity)
|
||||||
|
{
|
||||||
|
var supply = entity.Supply();
|
||||||
|
|
||||||
|
if (supply == null || supply.Takes.Equals(0)) return 0;
|
||||||
|
|
||||||
|
foreach (var supplyAtTime in buildOrder.SupplyCountTimes)
|
||||||
|
if (supply.Takes + buildOrder.CurrentSupplyUsed < supplyAtTime.Key)
|
||||||
|
return supplyAtTime.Value;
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService withToasts)
|
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService withToasts)
|
||||||
{
|
{
|
||||||
var production = entity.Production();
|
var atInterval = lastInterval;
|
||||||
|
|
||||||
if (production != null)
|
if (!HandleSupply(entity, withToasts, ref atInterval)) return false;
|
||||||
{
|
if (!HandleRequirements(entity, withToasts, ref atInterval)) return false;
|
||||||
for (var interval = lastInterval; interval < withEconomy.GetOverTime().Count; interval++)
|
if (!HandleEconomy(entity, withEconomy, withToasts, ref atInterval)) return false;
|
||||||
{
|
|
||||||
var economyAtSecond = withEconomy.GetOverTime()[interval];
|
|
||||||
if (economyAtSecond.Alloy >= production.Alloy && economyAtSecond.Ether >= production.Ether &&
|
|
||||||
economyAtSecond.Pyre >= production.Pyre)
|
|
||||||
{
|
|
||||||
if (!MeetsSupply(entity))
|
|
||||||
{
|
|
||||||
withToasts.AddToast(new ToastModel
|
|
||||||
{
|
|
||||||
Title = "Supply Cap Reached", Message = "Build more supply!",
|
|
||||||
SeverityType = SeverityType.Error
|
|
||||||
});
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!MeetsRequirements(entity, interval)) continue;
|
Add(entity, atInterval);
|
||||||
|
|
||||||
//Account for human Micro delay
|
return true;
|
||||||
interval += HumanMicro;
|
|
||||||
|
|
||||||
if (!buildOrder.StartedOrders.ContainsKey(interval))
|
|
||||||
buildOrder.StartedOrders.Add(interval, new List<EntityModel> { entity.Clone() });
|
|
||||||
else
|
|
||||||
buildOrder.StartedOrders[interval].Add(entity.Clone());
|
|
||||||
|
|
||||||
lastInterval = interval;
|
|
||||||
|
|
||||||
NotifyDataChanged();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (interval + 1 == withEconomy.GetOverTime().Count)
|
|
||||||
{
|
|
||||||
if (economyAtSecond.Ether < production.Ether)
|
|
||||||
withToasts.AddToast(new ToastModel
|
|
||||||
{
|
|
||||||
Title = "Not Enough Ether", Message = "Build more ether extractors!",
|
|
||||||
SeverityType = SeverityType.Error
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Add(entity, 0);
|
|
||||||
NotifyDataChanged();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveLast()
|
public void RemoveLast()
|
||||||
{
|
{
|
||||||
EntityModel entityRemoved = null!;
|
|
||||||
|
|
||||||
|
|
||||||
if (buildOrder.StartedOrders.Keys.Count > 1)
|
if (buildOrder.StartedOrders.Keys.Count > 1)
|
||||||
{
|
{
|
||||||
var last = buildOrder.StartedOrders.Keys.Last();
|
var lastStarted = buildOrder.StartedOrders.Keys.Last();
|
||||||
|
var lastCompleted = buildOrder.CompletedOrders.Keys.Last();
|
||||||
|
|
||||||
if (buildOrder.StartedOrders[last].Count > 0)
|
EntityModel entityRemoved = default!;
|
||||||
|
|
||||||
|
if (buildOrder.StartedOrders[lastStarted].Count > 0)
|
||||||
{
|
{
|
||||||
entityRemoved = buildOrder.StartedOrders[last].Last();
|
entityRemoved = buildOrder.StartedOrders[lastStarted].Last();
|
||||||
buildOrder.StartedOrders[last].Remove(buildOrder.StartedOrders[last].Last());
|
buildOrder.StartedOrders[lastStarted].Remove(buildOrder.StartedOrders[lastStarted].Last());
|
||||||
|
buildOrder.CompletedOrders[lastCompleted].Remove(buildOrder.CompletedOrders[lastCompleted].Last());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buildOrder.StartedOrders[last].Count == 0) buildOrder.StartedOrders.Remove(last);
|
if (buildOrder.StartedOrders[lastStarted].Count == 0) buildOrder.StartedOrders.Remove(lastStarted);
|
||||||
|
if (buildOrder.CompletedOrders[lastCompleted].Count == 0) buildOrder.CompletedOrders.Remove(lastCompleted);
|
||||||
|
|
||||||
if (buildOrder.StartedOrders.Keys.Count > 0)
|
if (buildOrder.StartedOrders.Keys.Count > 0)
|
||||||
lastInterval = buildOrder.StartedOrders.Keys.Last() + 1;
|
lastInterval = buildOrder.StartedOrders.Keys.Last();
|
||||||
else
|
else
|
||||||
lastInterval = 1;
|
lastInterval = 0;
|
||||||
|
|
||||||
if (entityRemoved?.Info()?.Descriptive == DescriptiveType.Worker)
|
if (entityRemoved.Supply()?.Grants > 0)
|
||||||
|
SupplyCountTimes.Remove(SupplyCountTimes.Last().Key);
|
||||||
|
|
||||||
|
if (entityRemoved.Supply()?.Takes > 0)
|
||||||
|
buildOrder.CurrentSupplyUsed -= entityRemoved.Supply()!.Takes;
|
||||||
|
|
||||||
|
if (UniqueCompletedTimes[entityRemoved!.DataType].Equals(lastInterval + entityRemoved.Production()!.BuildTime))
|
||||||
|
UniqueCompletedTimes.Remove(entityRemoved.DataType);
|
||||||
|
|
||||||
|
if (entityRemoved.Info().Descriptive == DescriptiveType.Worker)
|
||||||
{
|
{
|
||||||
RemoveLast();
|
RemoveLast();
|
||||||
return;
|
return;
|
||||||
@@ -172,28 +190,9 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
return buildOrderText;
|
return buildOrderText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<EntityModel> GetOrdersAt(int interval)
|
|
||||||
{
|
|
||||||
if (!buildOrder.StartedOrders.ContainsKey(interval))
|
|
||||||
{
|
|
||||||
return new List<EntityModel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildOrder.StartedOrders[interval].ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EntityModel> GetCompletedAt(int interval)
|
|
||||||
{
|
|
||||||
if (!buildOrder.CompletedOrders.ContainsKey(interval))
|
|
||||||
{
|
|
||||||
return new List<EntityModel>();
|
|
||||||
}
|
|
||||||
|
|
||||||
return buildOrder.CompletedOrders[interval].ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<EntityModel> GetCompletedBefore(int interval)
|
public List<EntityModel> GetCompletedBefore(int interval)
|
||||||
{
|
{
|
||||||
return (from ordersAtTime in buildOrder.StartedOrders
|
return (from ordersAtTime in buildOrder.StartedOrders
|
||||||
from orders in ordersAtTime.Value
|
from orders in ordersAtTime.Value
|
||||||
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval
|
||||||
@@ -209,52 +208,10 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
select orders).ToList();
|
select orders).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MeetsRequirements(EntityModel entity, int requestedInterval)
|
|
||||||
|
public void SetName(string name)
|
||||||
{
|
{
|
||||||
var requirements = entity.Requirements();
|
buildOrder.Name = name;
|
||||||
if (requirements.Count == 0) return true;
|
|
||||||
|
|
||||||
foreach (var requirement in requirements)
|
|
||||||
if (requirement.Requirement == RequirementType.Morph)
|
|
||||||
{
|
|
||||||
var entitiesNeeded = from entitiesAtInterval in buildOrder.StartedOrders
|
|
||||||
from requiredEntity in entitiesAtInterval.Value
|
|
||||||
where requestedInterval > entitiesAtInterval.Key +
|
|
||||||
(requiredEntity.Production() == null ? 0 : requiredEntity.Production().BuildTime)
|
|
||||||
where requiredEntity.DataType == requirement.Id
|
|
||||||
select requiredEntity;
|
|
||||||
|
|
||||||
var entitiesAlreadyMorphed = from entitiesAtInterval in buildOrder.StartedOrders
|
|
||||||
from existingEntity in entitiesAtInterval.Value
|
|
||||||
where existingEntity.DataType == entity.DataType
|
|
||||||
select existingEntity;
|
|
||||||
|
|
||||||
if (entitiesAlreadyMorphed.Count() >= entitiesNeeded.Count())
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var entitiesNeeded = from entitiesAtInterval in buildOrder.StartedOrders
|
|
||||||
from requiredEntity in entitiesAtInterval.Value
|
|
||||||
where requestedInterval > entitiesAtInterval.Key +
|
|
||||||
(requiredEntity.Production() == null ? 0 : requiredEntity.Production().BuildTime)
|
|
||||||
where requiredEntity.DataType == requirement.Id
|
|
||||||
select requiredEntity;
|
|
||||||
|
|
||||||
|
|
||||||
if (!entitiesNeeded.Any()) return false;
|
|
||||||
|
|
||||||
|
|
||||||
if (entitiesNeeded.Any() == false)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetName(string Name)
|
|
||||||
{
|
|
||||||
buildOrder.Name = Name;
|
|
||||||
NotifyDataChanged();
|
NotifyDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,9 +220,9 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
return buildOrder.Name;
|
return buildOrder.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetNotes(string Notes)
|
public void SetNotes(string notes)
|
||||||
{
|
{
|
||||||
buildOrder.Notes = Notes;
|
buildOrder.Notes = notes;
|
||||||
NotifyDataChanged();
|
NotifyDataChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,37 +242,90 @@ public class BuildOrderService : IBuildOrderService
|
|||||||
return buildOrder.Color;
|
return buildOrder.Color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool HandleEconomy(EntityModel entity, IEconomyService withEconomy, IToastService withToasts,
|
||||||
|
ref int atInterval)
|
||||||
|
{
|
||||||
|
var production = entity.Production();
|
||||||
|
|
||||||
|
if (production == null) return true;
|
||||||
|
|
||||||
|
for (var interval = atInterval; interval < withEconomy.GetOverTime().Count; interval++)
|
||||||
|
{
|
||||||
|
var economyAtSecond = withEconomy.GetOverTime()[interval];
|
||||||
|
if (economyAtSecond.Alloy >= production.Alloy && economyAtSecond.Ether >= production.Ether &&
|
||||||
|
economyAtSecond.Pyre >= production.Pyre)
|
||||||
|
{
|
||||||
|
atInterval = interval;
|
||||||
|
|
||||||
|
if (entity.EntityType != EntityType.Army)
|
||||||
|
{
|
||||||
|
atInterval += HumanMicro;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (withEconomy.GetOverTime().Last().Ether < production.Ether)
|
||||||
|
withToasts.AddToast(new ToastModel
|
||||||
|
{
|
||||||
|
Title = "Not Enough Ether", Message = "Build more ether extractors!",
|
||||||
|
SeverityType = SeverityType.Error
|
||||||
|
});
|
||||||
|
|
||||||
|
if (withEconomy.GetOverTime().Last().Alloy < production.Alloy)
|
||||||
|
withToasts.AddToast(new ToastModel
|
||||||
|
{
|
||||||
|
Title = "Not Enough Alloy", Message = "Build more bases!",
|
||||||
|
SeverityType = SeverityType.Error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleSupply(EntityModel entity, IToastService withToasts, ref int atInterval)
|
||||||
|
{
|
||||||
|
var minSupplyInterval = WillMeetSupply(entity);
|
||||||
|
if (minSupplyInterval == null)
|
||||||
|
{
|
||||||
|
withToasts.AddToast(new ToastModel
|
||||||
|
{
|
||||||
|
Title = "Supply Cap Reached", Message = "Build more supply!",
|
||||||
|
SeverityType = SeverityType.Error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minSupplyInterval > atInterval) atInterval = (int)minSupplyInterval;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HandleRequirements(EntityModel entity, IToastService withToasts, ref int atInterval)
|
||||||
|
{
|
||||||
|
var minRequirementInterval = WillMeetRequirements(entity);
|
||||||
|
if (minRequirementInterval == null)
|
||||||
|
{
|
||||||
|
withToasts.AddToast(new ToastModel
|
||||||
|
{
|
||||||
|
Title = "Missing Requirements", Message = "You don't have what's needed for this unit.",
|
||||||
|
SeverityType = SeverityType.Error
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minRequirementInterval > atInterval) atInterval = (int)minRequirementInterval;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private event Action OnChange = null!;
|
private event Action OnChange = null!;
|
||||||
|
|
||||||
private void NotifyDataChanged()
|
private void NotifyDataChanged()
|
||||||
{
|
{
|
||||||
OnChange?.Invoke();
|
OnChange?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MeetsSupply(EntityModel entity)
|
|
||||||
{
|
|
||||||
var supply = entity.Supply();
|
|
||||||
if (supply == null || supply.Takes == 0) return true;
|
|
||||||
|
|
||||||
|
|
||||||
var supplyTakenTotal = 0;
|
|
||||||
var supplyTakens = from entitiesAtInterval in buildOrder.StartedOrders
|
|
||||||
from supplyTakingEntity in entitiesAtInterval.Value
|
|
||||||
where supplyTakingEntity.Supply()?.Takes > 0
|
|
||||||
select supplyTakingEntity.Supply().Takes;
|
|
||||||
foreach (var supplyTaken in supplyTakens) supplyTakenTotal += supplyTaken;
|
|
||||||
|
|
||||||
var supplyGrantedTotal = 0;
|
|
||||||
var supplyGranteds = from entitiesAtInterval in buildOrder.StartedOrders
|
|
||||||
from supplyGrantingEntity in entitiesAtInterval.Value
|
|
||||||
where supplyGrantingEntity.Supply()?.Grants > 0
|
|
||||||
select supplyGrantingEntity.Supply().Grants;
|
|
||||||
foreach (var supplyGranted in supplyGranteds) supplyGrantedTotal += supplyGranted;
|
|
||||||
|
|
||||||
if (supplyGrantedTotal > 160) supplyGrantedTotal = 160;
|
|
||||||
|
|
||||||
if (supplyTakenTotal + supply.Takes > supplyGrantedTotal) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,16 +7,20 @@ namespace Services.Immortal;
|
|||||||
public class EconomyService : IEconomyService {
|
public class EconomyService : IEconomyService {
|
||||||
private List<EconomyModel> _economyOverTime = null!;
|
private List<EconomyModel> _economyOverTime = null!;
|
||||||
|
|
||||||
|
|
||||||
|
private event Action OnChange = null!;
|
||||||
|
|
||||||
|
|
||||||
public List<EconomyModel> GetOverTime() {
|
public List<EconomyModel> GetOverTime() {
|
||||||
return _economyOverTime;
|
return _economyOverTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Subscribe(Action action) {
|
public void Subscribe(Action action) {
|
||||||
onChange += action;
|
OnChange += action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unsubscribe(Action action) {
|
public void Unsubscribe(Action action) {
|
||||||
onChange -= action;
|
OnChange -= action;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval) {
|
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval) {
|
||||||
@@ -35,9 +39,11 @@ public class EconomyService : IEconomyService {
|
|||||||
|
|
||||||
while (_economyOverTime.Count < timing.GetTiming()) _economyOverTime.Add(new EconomyModel { Interval = _economyOverTime.Count - 1 });
|
while (_economyOverTime.Count < timing.GetTiming()) _economyOverTime.Add(new EconomyModel { Interval = _economyOverTime.Count - 1 });
|
||||||
|
|
||||||
for (var interval = fromInterval; interval < timing.GetTiming(); interval++) {
|
for (var interval = fromInterval; interval < timing.GetTiming(); interval++)
|
||||||
|
{
|
||||||
var economyAtSecond = _economyOverTime[interval];
|
var economyAtSecond = _economyOverTime[interval];
|
||||||
if (interval > 0) {
|
if (interval > 0)
|
||||||
|
{
|
||||||
economyAtSecond.Alloy = _economyOverTime[interval - 1].Alloy;
|
economyAtSecond.Alloy = _economyOverTime[interval - 1].Alloy;
|
||||||
economyAtSecond.Ether = _economyOverTime[interval - 1].Ether;
|
economyAtSecond.Ether = _economyOverTime[interval - 1].Ether;
|
||||||
economyAtSecond.Pyre = _economyOverTime[interval - 1].Pyre;
|
economyAtSecond.Pyre = _economyOverTime[interval - 1].Pyre;
|
||||||
@@ -62,10 +68,12 @@ public class EconomyService : IEconomyService {
|
|||||||
economyAtSecond.Pyre += 1;
|
economyAtSecond.Pyre += 1;
|
||||||
|
|
||||||
// Add funds
|
// Add funds
|
||||||
foreach (var entity in economyAtSecond.Harvesters) {
|
foreach (var entity in economyAtSecond.Harvesters)
|
||||||
|
{
|
||||||
var harvester = entity.Harvest();
|
var harvester = entity.Harvest();
|
||||||
if (harvester.RequiresWorker)
|
if (harvester.RequiresWorker)
|
||||||
if (harvester.Resource == ResourceType.Alloy) {
|
if (harvester.Resource == ResourceType.Alloy)
|
||||||
|
{
|
||||||
var usedWorkers = Math.Min(harvester.Slots, freeWorkers);
|
var usedWorkers = Math.Min(harvester.Slots, freeWorkers);
|
||||||
economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers;
|
economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers;
|
||||||
freeWorkers -= usedWorkers;
|
freeWorkers -= usedWorkers;
|
||||||
@@ -73,7 +81,8 @@ public class EconomyService : IEconomyService {
|
|||||||
if (usedWorkers < harvester.Slots) workersNeeded += 1;
|
if (usedWorkers < harvester.Slots) workersNeeded += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (harvester.RequiresWorker == false) {
|
if (harvester.RequiresWorker == false)
|
||||||
|
{
|
||||||
if (harvester.Resource == ResourceType.Ether)
|
if (harvester.Resource == ResourceType.Ether)
|
||||||
economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots;
|
economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots;
|
||||||
|
|
||||||
@@ -85,46 +94,57 @@ public class EconomyService : IEconomyService {
|
|||||||
// Create new worker
|
// Create new worker
|
||||||
if (economyAtSecond.CreatingWorkerCount > 0)
|
if (economyAtSecond.CreatingWorkerCount > 0)
|
||||||
for (var i = 0; i < economyAtSecond.CreatingWorkerDelays.Count; i++)
|
for (var i = 0; i < economyAtSecond.CreatingWorkerDelays.Count; i++)
|
||||||
if (economyAtSecond.CreatingWorkerDelays[i] > 0) {
|
if (economyAtSecond.CreatingWorkerDelays[i] > 0)
|
||||||
if (economyAtSecond.Alloy > 2.5f) {
|
{
|
||||||
|
if (economyAtSecond.Alloy > 2.5f)
|
||||||
|
{
|
||||||
economyAtSecond.Alloy -= 2.5f;
|
economyAtSecond.Alloy -= 2.5f;
|
||||||
economyAtSecond.CreatingWorkerDelays[i]--;
|
economyAtSecond.CreatingWorkerDelays[i]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
economyAtSecond.CreatingWorkerCount -= 1;
|
economyAtSecond.CreatingWorkerCount -= 1;
|
||||||
economyAtSecond.WorkerCount += 1;
|
economyAtSecond.WorkerCount += 1;
|
||||||
economyAtSecond.CreatingWorkerDelays.Remove(i);
|
economyAtSecond.CreatingWorkerDelays.Remove(i);
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workersNeeded > economyAtSecond.CreatingWorkerCount) {
|
if (workersNeeded > economyAtSecond.CreatingWorkerCount)
|
||||||
|
{
|
||||||
economyAtSecond.CreatingWorkerCount += 1;
|
economyAtSecond.CreatingWorkerCount += 1;
|
||||||
economyAtSecond.CreatingWorkerDelays.Add(50);
|
economyAtSecond.CreatingWorkerDelays.Add(50);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove Funds from Build Order
|
// Remove Funds from Build Order
|
||||||
var ordersAtTime = buildOrder.GetOrdersAt(interval);
|
|
||||||
|
|
||||||
foreach (var order in ordersAtTime) {
|
if (buildOrder.StartedOrders.TryGetValue(interval, out var ordersAtTime))
|
||||||
var foundEntity = EntityModel.GetDictionary()[order.DataType];
|
{
|
||||||
var production = foundEntity.Production();
|
|
||||||
|
|
||||||
if (production != null) {
|
foreach (var order in ordersAtTime)
|
||||||
economyAtSecond.Alloy -= production.Alloy;
|
{
|
||||||
economyAtSecond.Ether -= production.Ether;
|
var foundEntity = EntityModel.GetDictionary()[order.DataType];
|
||||||
economyAtSecond.Pyre -= production.Pyre;
|
var production = foundEntity.Production();
|
||||||
var finishedAt = interval + production.BuildTime;
|
|
||||||
|
|
||||||
if (production.RequiresWorker) economyAtSecond.BusyWorkerCount += 1;
|
if (production != null)
|
||||||
|
{
|
||||||
|
economyAtSecond.Alloy -= production.Alloy;
|
||||||
|
economyAtSecond.Ether -= production.Ether;
|
||||||
|
economyAtSecond.Pyre -= production.Pyre;
|
||||||
|
var finishedAt = interval + production.BuildTime;
|
||||||
|
|
||||||
if (production.ConsumesWorker) economyAtSecond.WorkerCount -= 1;
|
if (production.RequiresWorker) economyAtSecond.BusyWorkerCount += 1;
|
||||||
|
|
||||||
|
if (production.ConsumesWorker) economyAtSecond.WorkerCount -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle new entities
|
// Handle new entities
|
||||||
var completedAtInterval = buildOrder.GetCompletedAt(interval);
|
if (buildOrder.CompletedOrders.TryGetValue(interval, out var completedAtInterval))
|
||||||
foreach (var newEntity in completedAtInterval) {
|
{
|
||||||
|
foreach (var newEntity in completedAtInterval)
|
||||||
|
{
|
||||||
var harvest = newEntity;
|
var harvest = newEntity;
|
||||||
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
|
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
|
||||||
|
|
||||||
@@ -132,6 +152,7 @@ public class EconomyService : IEconomyService {
|
|||||||
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
|
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
NotifyDataChanged();
|
NotifyDataChanged();
|
||||||
}
|
}
|
||||||
@@ -141,13 +162,7 @@ public class EconomyService : IEconomyService {
|
|||||||
return _economyOverTime[atInterval];
|
return _economyOverTime[atInterval];
|
||||||
}
|
}
|
||||||
|
|
||||||
private event Action onChange = null!;
|
|
||||||
|
|
||||||
private void NotifyDataChanged() {
|
private void NotifyDataChanged() {
|
||||||
onChange?.Invoke();
|
OnChange?.Invoke();
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnChange() {
|
|
||||||
return onChange;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
using Model.Entity;
|
|
||||||
using Model.Types;
|
|
||||||
|
|
||||||
namespace Services.Immortal;
|
|
||||||
|
|
||||||
public class GameLogicService : IGameLogicService
|
|
||||||
{
|
|
||||||
private ITimingService timingService;
|
|
||||||
private IEconomyService economyService;
|
|
||||||
private IBuildOrderService buildOrderService;
|
|
||||||
|
|
||||||
public GameLogicService(ITimingService timingService, IEconomyService economyService, IBuildOrderService buildOrderService)
|
|
||||||
{
|
|
||||||
this.timingService = timingService;
|
|
||||||
this.economyService = economyService;
|
|
||||||
this.buildOrderService = buildOrderService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Add(EntityModel entity, int atInterval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsRequirements(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
var buildOrders = buildOrderService.GetCompletedBefore(interval);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsAlloy(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsEther(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsPyre(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsSupply(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MeetsTrainingQueue(EntityModel entity, int interval)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
namespace Services.Immortal;
|
namespace Services.Immortal;
|
||||||
|
|
||||||
public class TimingService : ITimingService {
|
public class TimingService : ITimingService {
|
||||||
private int _timing = 360;
|
private int _timing = 1500;
|
||||||
|
|
||||||
public void Subscribe(Action? action) {
|
public void Subscribe(Action? action) {
|
||||||
_onChange += action;
|
_onChange += action;
|
||||||
|
|||||||
Reference in New Issue
Block a user