Browse Source

feature(BuildCalc) Adding WIP wait button, and better styling

main
Jonathan McCaffrey 4 years ago
parent
commit
a0cd7d9b45
  1. 33
      Components/Form/FormNumberComponent.razor
  2. BIN
      IGP/Database.db
  3. 7
      IGP/Localizations.resx
  4. 30
      IGP/Pages/BuildCalculator/BuildCalculatorPage.razor
  5. 50
      IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor
  6. 5
      IGP/Pages/BuildCalculator/Parts/ChartComponent.razor
  7. 21
      IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor
  8. 47
      IGP/Pages/BuildCalculator/Parts/TimingComponent.razor
  9. 2
      IGP/wwwroot/generated/AgileTaskModels.json
  10. 6
      Services/IServices.cs
  11. 3
      Services/Immortal/BuildOrderService.cs
  12. 46
      Services/Immortal/EconomyService.cs
  13. 27
      Services/Immortal/TimingService.cs

33
Components/Form/FormNumberComponent.razor

@ -10,7 +10,7 @@
min="@Min" min="@Min"
max="@Max" max="@Max"
value="@Value" value="@Value"
@onchange="OnChange"/> @onchange="OnInputChanged"/>
</div> </div>
@if (FormInfoComponent != null) @if (FormInfoComponent != null)
{ {
@ -46,16 +46,39 @@
[Parameter] [Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; } public EventCallback<ChangeEventArgs> OnChange { get; set; }
void OnInputChanged(ChangeEventArgs changeEventArgs)
{
int valueWas = Value;
int newValue = int.Parse(changeEventArgs.Value!.ToString()!);
if (newValue > Max)
{
newValue = Max;
}
if (newValue < Min)
{
newValue = Min;
}
if (valueWas != newValue)
{
Value = newValue;
changeEventArgs.Value = newValue;
OnChange.InvokeAsync(changeEventArgs);
}
}
[Parameter] [Parameter]
public bool? ReadOnly { get; set; } public bool ReadOnly { get; set; } = false;
[Parameter] [Parameter]
public int? Value { get; set; } public int Value { get; set; } = 0;
[Parameter] [Parameter]
public int? Min { get; set; } public int Min { get; set; } = 0;
[Parameter] [Parameter]
public int? Max { get; set; } public int Max { get; set; } = 2048;
} }

BIN
IGP/Database.db

Binary file not shown.

7
IGP/Localizations.resx

@ -53,12 +53,7 @@ Affects entities you can build.</value>
<value>Some raw JSON data to represent your build order.</value> <value>Some raw JSON data to represent your build order.</value>
</data> </data>
<data name="Tooltip Timing Info" xml:space="preserve"> <data name="Tooltip Timing Info" xml:space="preserve">
<value>Enter build details. <value>Enter build details.</value>
&lt;b&gt;Timing Interval:&lt;/b&gt; set the max interval length for the build. &lt;i&gt;Ex. 240 (seconds) is 4 minutes, a possible timing for Thrum build order.&lt;/i&gt;
&lt;b&gt;Name:&lt;/b&gt; the name of the build for saving purposes. &lt;i&gt;Ex. 'Safe Thrum Opener'&lt;/i&gt;
&lt;b&gt;Notes:&lt;/b&gt; additional notes of the build for saving purposes. &lt;i&gt;Ex. 'Thrums are for harassing and defending against a ground Q'Rath army.'&lt;/i&gt;
&lt;b&gt;Color:&lt;/b&gt; value to color charts when comparing builds. Not currently implemented.</value>
</data> </data>
<data name="Tooltip Hotkey Info" xml:space="preserve"> <data name="Tooltip Hotkey Info" xml:space="preserve">
<value>Click on the desired entity to build it. &lt;i&gt;You cannot build entities you cannot afford, construct an ether extractor before spending ether.&lt;/i&gt; <value>Click on the desired entity to build it. &lt;i&gt;You cannot build entities you cannot afford, construct an ether extractor before spending ether.&lt;/i&gt;

30
IGP/Pages/BuildCalculator/BuildCalculatorPage.razor

@ -27,12 +27,23 @@
<div class="calculatorGrid"> <div class="calculatorGrid">
<div class="gridItem" style="grid-area: timing;"> <div class="gridItem" style="grid-area: timing;">
<ButtonComponent OnClick="OnResetClicked">Clear Build Order</ButtonComponent> <ButtonComponent ButtonType="ButtonType.Secondary" OnClick="OnResetClicked">Clear Build Order</ButtonComponent>
<PanelComponent> <PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Timing Info"]"> <InfoTooltipComponent InfoText="@locale["Tooltip Timing Info"]">
<TimingComponent></TimingComponent> <TimingComponent></TimingComponent>
</InfoTooltipComponent> </InfoTooltipComponent>
</PanelComponent> </PanelComponent>
<PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Filter Info"]">
<FilterComponent></FilterComponent>
</InfoTooltipComponent>
</PanelComponent>
<PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Options Info"]">
<OptionsComponent></OptionsComponent>
</InfoTooltipComponent>
</PanelComponent>
</div> </div>
@ -44,20 +55,6 @@
</PanelComponent> </PanelComponent>
</div> </div>
<div class="gridItem" style="grid-area: filter;">
<PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Filter Info"]">
<FilterComponent></FilterComponent>
</InfoTooltipComponent>
</PanelComponent>
<PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Options Info"]">
<OptionsComponent></OptionsComponent>
</InfoTooltipComponent>
</PanelComponent>
</div>
<div class="gridItem" style="grid-area: view;"> <div class="gridItem" style="grid-area: view;">
<PanelComponent> <PanelComponent>
<InfoTooltipComponent InfoText="@locale["Tooltip Entity Info"]"> <InfoTooltipComponent InfoText="@locale["Tooltip Entity Info"]">
@ -182,7 +179,7 @@
grid-template-rows: 600px 400px 450px; grid-template-rows: 600px 400px 450px;
grid-template-areas: grid-template-areas:
'timing view view view' 'timing view view view'
'filter bank army army' 'timing bank army army'
'keys keys highlights buildorder' 'keys keys highlights buildorder'
'chart chart chart chart'; 'chart chart chart chart';
} }
@ -202,7 +199,6 @@
grid-template-areas: grid-template-areas:
'timing' 'timing'
'view' 'view'
'filter'
'keys' 'keys'
'bank' 'bank'
'army' 'army'

50
IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor

@ -1,20 +1,28 @@
@inject IJSRuntime jsRuntime @inject IJSRuntime jsRuntime
@inject IBuildOrderService buildOrder @inject IBuildOrderService buildOrder
@inject ITimingService timingService
@implements IDisposable @implements IDisposable
<FormLayoutComponent> <FormLayoutComponent>
<FormDisplayComponent Label="Army ready at"> <div style="display: flex; gap: 24px;">
<Display>@lastInterval | T @Interval.ToTime(lastInterval)</Display> <FormDisplayComponent Label="Army Completed At">
</FormDisplayComponent> <Display>@lastInterval | T @Interval.ToTime(lastInterval)</Display>
</FormDisplayComponent>
<FormDisplayComponent Label="Army Attacking At">
<Display>@(lastInterval + timingService.GetTravelTime()) | T @Interval.ToTime(lastInterval + timingService.GetTravelTime())</Display>
</FormDisplayComponent>
</div>
<FormDisplayComponent Label="Army units built"> <FormDisplayComponent Label="Army units built">
<Display> <Display>
<div style="display: flex; width: 100%; gap: 12px; flex-wrap: wrap;"> <div class="armyCardsContainer">
@foreach (var unit in armyCount) @foreach (var unit in armyCount)
{ {
<div style="width:90px; height: 60px; border: 1px solid gray; padding: 8px;"> <div class="armyCard">
<div>@unit.Value.ToString()x</div> <div class="armyCountPosition">
<div class="armyCount">@unit.Value.ToString()x</div>
</div>
<div>@unit.Key</div> <div>@unit.Key</div>
</div> </div>
} }
@ -24,9 +32,33 @@
</FormLayoutComponent> </FormLayoutComponent>
@code { <style>
.armyCardsContainer {
display: flex;
width: 100%;
gap: 16px;
flex-wrap: wrap;
}
.armyCard {
width:100px;
height: 80px;
padding: 16px;
}
.armyCountPosition {
height: 0;
top: -20px;
left: -16px;
position: relative;
}
.armyCount {
font-weight: bolder;
}
</style>
@code {
private int lastInterval; private int lastInterval;
readonly Dictionary<string, int> armyCount = new(); readonly Dictionary<string, int> armyCount = new();
@ -36,11 +68,13 @@
protected override void OnInitialized() protected override void OnInitialized()
{ {
buildOrder.Subscribe(OnBuildOrderChanged); buildOrder.Subscribe(OnBuildOrderChanged);
timingService.Subscribe(StateHasChanged);
} }
void IDisposable.Dispose() void IDisposable.Dispose()
{ {
buildOrder.Unsubscribe(OnBuildOrderChanged); buildOrder.Unsubscribe(OnBuildOrderChanged);
timingService.Unsubscribe(StateHasChanged);
} }
protected override bool ShouldRender() protected override bool ShouldRender()

5
IGP/Pages/BuildCalculator/Parts/ChartComponent.razor

@ -1,5 +1,6 @@
@inject IEconomyService economyService @inject IEconomyService economyService
@inject IBuildOrderService buildOrderService @inject IBuildOrderService buildOrderService
@inject ITimingService timingService
@inject IJSRuntime jsRuntime; @inject IJSRuntime jsRuntime;
@implements IDisposable @implements IDisposable
@ -81,8 +82,9 @@ else
protected override void OnInitialized() protected override void OnInitialized()
{ {
buildOrderService.Subscribe(OnBuilderOrderChanged); buildOrderService.Subscribe(OnBuilderOrderChanged);
timingService.Subscribe(OnBuilderOrderChanged);
ageTimer = new Timer(3000); ageTimer = new Timer(1000);
ageTimer.Elapsed += OnAge!; ageTimer.Elapsed += OnAge!;
ageTimer.Enabled = true; ageTimer.Enabled = true;
@ -114,6 +116,7 @@ else
void IDisposable.Dispose() void IDisposable.Dispose()
{ {
buildOrderService.Unsubscribe(OnBuilderOrderChanged); buildOrderService.Unsubscribe(OnBuilderOrderChanged);
timingService.Unsubscribe(OnBuilderOrderChanged);
} }

21
IGP/Pages/BuildCalculator/Parts/OptionsComponent.razor

@ -13,6 +13,17 @@
<FormLabelComponent>Building Input Delay</FormLabelComponent> <FormLabelComponent>Building Input Delay</FormLabelComponent>
<FormInfoComponent>Add a input delay to constructing buildings for simulating worker movement and player micro.</FormInfoComponent> <FormInfoComponent>Add a input delay to constructing buildings for simulating worker movement and player micro.</FormInfoComponent>
</FormNumberComponent> </FormNumberComponent>
<FormNumberComponent Max="600"
Min="0"
Value="30"
OnChange="@OnWaitTimeChanged">
<FormLabelComponent>Wait Time</FormLabelComponent>
<FormInfoComponent>Not implemented</FormInfoComponent>
</FormNumberComponent>
<ButtonComponent OnClick="OnWaitClicked">Add Wait</ButtonComponent>
</FormLayoutComponent> </FormLayoutComponent>
@ -22,6 +33,16 @@
{ {
buildOrderService.BuildingInputDelay = int.Parse(changeEventArgs.Value!.ToString()!); buildOrderService.BuildingInputDelay = int.Parse(changeEventArgs.Value!.ToString()!);
} }
void OnWaitTimeChanged(ChangeEventArgs changeEventArgs)
{
toastService.AddToast(new ToastModel(){Title = "Not Implemented", SeverityType = SeverityType.Warning, Message = "The ability to wait for X seconds in a build order hasn't been implemented yet."});
}
public void OnWaitClicked()
{
toastService.AddToast(new ToastModel(){Title = "Not Implemented", SeverityType = SeverityType.Warning, Message = "The ability to wait for X seconds in a build order hasn't been implemented yet."});
}
protected override bool ShouldRender() protected override bool ShouldRender()
{ {

47
IGP/Pages/BuildCalculator/Parts/TimingComponent.razor

@ -8,33 +8,50 @@
<FormLayoutComponent> <FormLayoutComponent>
<FormNumberComponent Max="2048" <FormNumberComponent Max="2048"
Min="0" Min="0"
Value="@timingService.GetTiming()" Value="@timingService.GetAttackTime()"
OnChange="@OnTimingChanged"> OnChange="@OnAttackTimeChanged">
<FormLabelComponent>Timing interval</FormLabelComponent> <FormLabelComponent>Attack Time</FormLabelComponent>
<FormInfoComponent>Altering the time interval is currently disabled.</FormInfoComponent> <FormInfoComponent><i>&emsp; T @Interval.ToTime(timingService.GetAttackTime())</i></FormInfoComponent>
</FormNumberComponent> </FormNumberComponent>
<FormTextComponent Label="Name" Placeholder="Fast Thrones..." Value="@buildOrderService.GetName()" OnChange="OnNameChanged"/> <FormNumberComponent Max="2048"
Min="0"
Value="@timingService.GetTravelTime()"
OnChange="@OnTravelTimeChanged">
<FormLabelComponent>Travel Time</FormLabelComponent>
<FormInfoComponent><i>&emsp; T @Interval.ToTime(timingService.GetTravelTime())</i></FormInfoComponent>
</FormNumberComponent>
<FormTextAreaComponent Label="Notes"
Value="@buildOrderService.GetNotes()"
OnChange="@OnNotesChanged">
</FormTextAreaComponent>
<FormTextComponent Label="Color" Placeholder="red..." Value="@buildOrderService.GetColor()" OnChange="OnColorChanged"/>
</FormLayoutComponent> </FormLayoutComponent>
@code { @code {
void OnTimingChanged(ChangeEventArgs changeEventArgs) void OnAttackTimeChanged(ChangeEventArgs changeEventArgs)
{
timingService.SetAttackTime(int.Parse(changeEventArgs.Value!.ToString()!));
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
toastService.AddToast(new ToastModel
{
Title = "Attack Time",
Message = "Attack Time has changed.",
SeverityType = SeverityType.Success
});
StateHasChanged();
}
void OnTravelTimeChanged(ChangeEventArgs changeEventArgs)
{ {
timingService.SetTiming(int.Parse(changeEventArgs.Value!.ToString()!)); timingService.SetTravelTime(int.Parse(changeEventArgs.Value!.ToString()!));
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval()); economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
toastService.AddToast(new ToastModel() toastService.AddToast(new ToastModel
{ {
Title = "Timing Interval", Title = "Travel Time",
Message = "Timing interval has changed.", Message = "Travel Time has changed.",
SeverityType = SeverityType.Success SeverityType = SeverityType.Success
}); });
StateHasChanged();
} }
void OnNameChanged(ChangeEventArgs changeEventArgs) void OnNameChanged(ChangeEventArgs changeEventArgs)

2
IGP/wwwroot/generated/AgileTaskModels.json

File diff suppressed because one or more lines are too long

6
Services/IServices.cs

@ -155,8 +155,10 @@ public interface IBuildComparisonService
public interface ITimingService public interface ITimingService
{ {
public int GetTiming(); public int GetAttackTime();
public void SetTiming(int timing); public void SetAttackTime(int timing);
public int GetTravelTime();
public void SetTravelTime(int timing);
public void Subscribe(Action? action); public void Subscribe(Action? action);
public void Unsubscribe(Action? action); public void Unsubscribe(Action? action);
} }

3
Services/Immortal/BuildOrderService.cs

@ -326,8 +326,7 @@ public class BuildOrderService : IBuildOrderService
atInterval = interval; atInterval = interval;
if (entity.EntityType != EntityType.Army) atInterval += BuildingInputDelay; if (entity.EntityType != EntityType.Army) atInterval += BuildingInputDelay;
return true; return true;
} }
} }

46
Services/Immortal/EconomyService.cs

@ -8,12 +8,12 @@ namespace Services.Immortal;
public class EconomyService : IEconomyService public class EconomyService : IEconomyService
{ {
private List<EconomyModel> _economyOverTime = null!; private List<EconomyModel> economyOverTime = null!;
public List<EconomyModel> GetOverTime() public List<EconomyModel> GetOverTime()
{ {
return _economyOverTime; return economyOverTime;
} }
public void Subscribe(Action action) public void Subscribe(Action action)
@ -29,33 +29,33 @@ public class EconomyService : IEconomyService
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval) public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval)
{ {
//TODO Break all this up //TODO Break all this up
if (_economyOverTime == null) if (economyOverTime == null)
{ {
_economyOverTime = new List<EconomyModel>(); economyOverTime = new List<EconomyModel>();
for (var interval = 0; interval < timing.GetTiming(); interval++) for (var interval = 0; interval < timing.GetAttackTime(); interval++)
_economyOverTime.Add(new EconomyModel { Interval = interval }); economyOverTime.Add(new EconomyModel { Interval = interval });
} }
if (_economyOverTime.Count > timing.GetTiming()) if (economyOverTime.Count > timing.GetAttackTime())
_economyOverTime.RemoveRange(timing.GetTiming(), _economyOverTime.Count - timing.GetTiming()); economyOverTime.RemoveRange(timing.GetAttackTime(), economyOverTime.Count - timing.GetAttackTime());
while (_economyOverTime.Count < timing.GetTiming()) while (economyOverTime.Count < timing.GetAttackTime())
_economyOverTime.Add(new EconomyModel { Interval = _economyOverTime.Count - 1 }); economyOverTime.Add(new EconomyModel { Interval = economyOverTime.Count - 1 });
for (var interval = fromInterval; interval < timing.GetTiming(); interval++) for (var interval = fromInterval; interval < timing.GetAttackTime(); 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;
economyAtSecond.WorkerCount = _economyOverTime[interval - 1].WorkerCount; economyAtSecond.WorkerCount = economyOverTime[interval - 1].WorkerCount;
economyAtSecond.BusyWorkerCount = _economyOverTime[interval - 1].BusyWorkerCount; economyAtSecond.BusyWorkerCount = economyOverTime[interval - 1].BusyWorkerCount;
economyAtSecond.CreatingWorkerCount = _economyOverTime[interval - 1].CreatingWorkerCount; economyAtSecond.CreatingWorkerCount = economyOverTime[interval - 1].CreatingWorkerCount;
economyAtSecond.Harvesters = _economyOverTime[interval - 1].Harvesters.ToList(); economyAtSecond.Harvesters = economyOverTime[interval - 1].Harvesters.ToList();
economyAtSecond.CreatingWorkerDelays = _economyOverTime[interval - 1].CreatingWorkerDelays.ToList(); economyAtSecond.CreatingWorkerDelays = economyOverTime[interval - 1].CreatingWorkerDelays.ToList();
} }
economyAtSecond.Interval = interval; economyAtSecond.Interval = interval;
@ -159,12 +159,12 @@ public class EconomyService : IEconomyService
public EconomyModel GetEconomy(int atInterval) public EconomyModel GetEconomy(int atInterval)
{ {
if (atInterval >= _economyOverTime.Count) if (atInterval >= economyOverTime.Count)
{ {
return _economyOverTime.Last(); return economyOverTime.Last();
} }
return _economyOverTime[atInterval]; return economyOverTime[atInterval];
} }

27
Services/Immortal/TimingService.cs

@ -2,7 +2,8 @@
public class TimingService : ITimingService public class TimingService : ITimingService
{ {
private int _timing = 1500; private int attackTime = 1500;
private int travelTime = 30;
public void Subscribe(Action? action) public void Subscribe(Action? action)
{ {
@ -14,16 +15,30 @@ public class TimingService : ITimingService
OnChange -= action; OnChange -= action;
} }
public int GetTiming() public int GetAttackTime()
{ {
return _timing; return attackTime;
} }
public void SetTiming(int timing) public void SetAttackTime(int timing)
{ {
if (_timing != timing) if (attackTime != timing)
{ {
_timing = timing; attackTime = timing;
NotifyDataChanged();
}
}
public int GetTravelTime()
{
return travelTime;
}
public void SetTravelTime(int timing)
{
if (travelTime != timing)
{
travelTime = timing;
NotifyDataChanged(); NotifyDataChanged();
} }
} }

Loading…
Cancel
Save