Auto formatting

This commit is contained in:
2022-05-02 02:04:40 -04:00
parent f103dc7bed
commit b2516fc80a
64 changed files with 683 additions and 548 deletions
+5 -6
View File
@@ -1,5 +1,4 @@
@using Services.Website
@inject IDataCollectionService DataCollectionService
@inject NavigationManager NavigationManager
@@ -12,26 +11,26 @@
CollectLoadedPage();
}
private void CollectLoadedPage()
{
var skipBaseUri = NavigationManager.Uri.Substring(NavigationManager.BaseUri.Length,
NavigationManager.Uri.Length - NavigationManager.BaseUri.Length);
var splitData = skipBaseUri.Split("/");
var rootUrl = splitData.First();
if (rootUrl.Trim().Equals(""))
{
rootUrl = "home";
}
var eventData = new Dictionary<string, string> { { "page", rootUrl }};
var eventData = new Dictionary<string, string> { { "page", rootUrl } };
if (splitData.Length > 1)
{
eventData["inner-page"] = splitData.Last();
}
DataCollectionService.SendEvent(DataCollectionKeys.PageInitialized, eventData);
}
@@ -13,7 +13,6 @@
@inject IDataCollectionService DataCollectionService
@page "/build-calculator"
@using Services.Website
@implements IDisposable
@@ -221,14 +220,14 @@
protected override void OnInitialized()
{
base.OnInitialized();
EconomyService.Calculate(BuildOrderService, TimingService, 0);
KeyService.Subscribe(HandleClick);
DataCollectionService.SendEvent(
DataCollectionKeys.PageInitialized,
new Dictionary<string, string> {{"page", "build-calculator"}}
DataCollectionKeys.PageInitialized,
new Dictionary<string, string> { { "page", "build-calculator" } }
);
}
@@ -19,7 +19,8 @@
<FormDisplayComponent Label="Army units built">
<Display>
<div class="armyCardsContainer">
@foreach (var unit in armyCount) {
@foreach (var unit in armyCount)
{
<div class="armyCard">
<div class="armyCountPosition">
<div class="armyCount">@unit.Value.ToString()x</div>
@@ -72,33 +73,39 @@
List<EntityModel> army = new();
protected override void OnInitialized() {
protected override void OnInitialized()
{
base.OnInitialized();
buildOrder.Subscribe(OnBuildOrderChanged);
timingService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
buildOrder.Unsubscribe(OnBuildOrderChanged);
timingService.Unsubscribe(StateHasChanged);
}
protected override bool ShouldRender() {
protected override bool ShouldRender()
{
#if DEBUG
jsRuntime.InvokeVoidAsync("console.time", "ArmyComponent");
#endif
return true;
}
protected override void OnAfterRender(bool firstRender) {
protected override void OnAfterRender(bool firstRender)
{
#if DEBUG
jsRuntime.InvokeVoidAsync("console.timeEnd", "ArmyComponent");
#endif
}
void OnBuildOrderChanged() {
void OnBuildOrderChanged()
{
var armyCountWas = 0;
foreach (var army in armyCount) {
foreach (var army in armyCount)
{
armyCountWas += army.Value;
}
@@ -108,14 +115,19 @@
var entitiesOverTime = buildOrder.GetOrders();
foreach (var entitiesAtTime in entitiesOverTime) {
foreach (var entity in entitiesAtTime.Value) {
if (entity.EntityType == EntityType.Army) {
if (!armyCount.TryAdd(entity.Info().Name, 1)) {
foreach (var entitiesAtTime in entitiesOverTime)
{
foreach (var entity in entitiesAtTime.Value)
{
if (entity.EntityType == EntityType.Army)
{
if (!armyCount.TryAdd(entity.Info().Name, 1))
{
armyCount[entity.Info().Name]++;
}
if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > lastInterval) {
if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > lastInterval)
{
lastInterval = entity.Production().BuildTime + entitiesAtTime.Key;
}
}
@@ -124,12 +136,14 @@
//TODO Better
var armyCountIs = 0;
foreach (var army in armyCount) {
foreach (var army in armyCount)
{
armyCountIs += army.Value;
}
if (armyCountWas != armyCountIs) {
if (armyCountWas != armyCountIs)
{
StateHasChanged();
}
}
@@ -13,20 +13,19 @@ else
<div class="chartsContainer">
@foreach (var chart in charts)
{
Dictionary<int, bool> takenPixels = new Dictionary<int, bool>();
var takenPixels = new Dictionary<int, bool>();
<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)
{
var x = int.Parse(point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax));
var x = int.Parse(point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax));
if (takenPixels.ContainsKey(x)) continue;
takenPixels.Add(x, true);
<div style="position: absolute;
bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px;
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
@@ -3,7 +3,6 @@
@inject IImmortalSelectionService FilterService
@inject IBuildOrderService BuildOrderService
@inject IStorageService StorageService
@using Services.Website
@implements IDisposable
@@ -39,10 +38,10 @@
void IDisposable.Dispose()
{
KeyService.Unsubscribe(HandleClick);
StorageService.Unsubscribe(RefreshDefaults);
}
void RefreshDefaults()
{
@@ -5,10 +5,14 @@
<FormSelectComponent OnChange="@OnFactionChanged">
<FormLabelComponent>Faction</FormLabelComponent>
<ChildContent>
<option value="@DataType.FACTION_Aru"
selected="@(FilterService.GetFaction().Equals(DataType.FACTION_Aru))">Aru</option>
<option value="@DataType.FACTION_QRath"
selected="@(FilterService.GetFaction().Equals(DataType.FACTION_QRath))">Q'Rath</option>
<option value="@DataType.FACTION_Aru"
selected="@(FilterService.GetFaction().Equals(DataType.FACTION_Aru))">
Aru
</option>
<option value="@DataType.FACTION_QRath"
selected="@(FilterService.GetFaction().Equals(DataType.FACTION_QRath))">
Q'Rath
</option>
</ChildContent>
</FormSelectComponent>
@@ -17,17 +21,25 @@
<ChildContent>
@if (FilterService.GetFaction() == DataType.FACTION_QRath)
{
<option value="@DataType.IMMORTAL_Orzum"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Orzum))">Orzum</option>
<option value="@DataType.IMMORTAL_Orzum"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Orzum))">
Orzum
</option>
<option value="@DataType.IMMORTAL_Ajari"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Ajari))">Ajari</option>
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Ajari))">
Ajari
</option>
}
@if (FilterService.GetFaction() == DataType.FACTION_Aru)
{
<option value="@DataType.IMMORTAL_Mala"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Mala))">Mala</option>
<option value="@DataType.IMMORTAL_Mala"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Mala))">
Mala
</option>
<option value="@DataType.IMMORTAL_Xol"
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Xol))">Xol</option>
selected="@(FilterService.GetImmortal().Equals(DataType.IMMORTAL_Xol))">
Xol
</option>
}
</ChildContent>
</FormSelectComponent>
@@ -8,7 +8,7 @@
<div class="highlightsContainer">
<div>
<div>Requested</div>
@foreach (var ordersAtTime in buildOrderService.StartedOrders.Reverse())
{
foreach (var order in ordersAtTime.Value)
@@ -13,8 +13,10 @@
<InputPanelComponent>
<div class="keyContainer">
@foreach (var hotkey in hotkeys) {
if (hotkey.IsHidden) {
@foreach (var hotkey in hotkeys)
{
if (hotkey.IsHidden)
{
continue;
}
@@ -31,14 +33,17 @@
var borderRadius = hotkey.PositionY == 0 ? 12 : 0;
var border = "1px solid black";
if (hotkey.KeyText.Equals(key)) {
if (hotkey.KeyText.Equals(key))
{
border = "5px solid black";
}
if (hotkey.KeyText.Equals(controlGroup)) {
if (hotkey.KeyText.Equals(controlGroup))
{
color = "#257525";
}
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace()) {
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace())
{
border = "5px solid green";
}
@@ -77,23 +82,28 @@
<div @onclick="e => ButtonClicked(e, hotkey)" style="@usedStyle">
@keyText
@foreach (var entity in data.Values) {
if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity)) {
@foreach (var entity in data.Values)
{
if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity))
{
continue;
}
if (InvalidFaction(entity)) {
if (InvalidFaction(entity))
{
continue;
}
if (InvalidVanguard(entity) || InvalidNonVanguard(entity)) {
if (InvalidVanguard(entity) || InvalidNonVanguard(entity))
{
continue;
}
var isVanguard = entity.VanguardAdded() != null;
var style = isVanguard ? "font-weight: bold;" : "";
if (BuildOrderService.WillMeetRequirements(entity) == null) {
if (BuildOrderService.WillMeetRequirements(entity) == null)
{
style += "color:gray; font-style: italic;";
}
@@ -137,7 +147,8 @@
private string controlGroup = "C";
private string key = "";
protected override void OnInitialized() {
protected override void OnInitialized()
{
base.OnInitialized();
KeyService.Subscribe(OnKeyPressed);
@@ -145,7 +156,8 @@
BuildOrderService.Subscribe(OnBuilderOrderChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
KeyService.Unsubscribe(OnKeyPressed);
FilterService.Unsubscribe(StateHasChanged);
BuildOrderService.Unsubscribe(OnBuilderOrderChanged);
@@ -153,14 +165,17 @@
int completedTimeCount = 0;
void OnBuilderOrderChanged() {
if (BuildOrderService.UniqueCompletedTimes.Count != completedTimeCount) {
void OnBuilderOrderChanged()
{
if (BuildOrderService.UniqueCompletedTimes.Count != completedTimeCount)
{
completedTimeCount = BuildOrderService.UniqueCompletedTimes.Count;
StateHasChanged();
}
}
protected override bool ShouldRender() {
protected override bool ShouldRender()
{
#if DEBUG
JsRuntime.InvokeVoidAsync("console.time", "HotKeyViewerComponent");
#endif
@@ -168,15 +183,18 @@
return true;
}
protected override void OnAfterRender(bool firstRender) {
protected override void OnAfterRender(bool firstRender)
{
#if DEBUG
JsRuntime.InvokeVoidAsync("console.timeEnd", "HotKeyViewerComponent");
#endif
}
// Move to Filter Service
bool InvalidFaction(EntityModel entity) {
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFaction() && FilterService.GetFaction() != DataType.Any) {
bool InvalidFaction(EntityModel entity)
{
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFaction() && FilterService.GetFaction() != DataType.Any)
{
return true;
}
@@ -184,10 +202,12 @@
}
// Move to Filter Service
bool InvalidVanguard(EntityModel entity) {
bool InvalidVanguard(EntityModel entity)
{
if (entity.VanguardAdded() != null
&& entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortal()
&& FilterService.GetImmortal() != DataType.Any) {
&& FilterService.GetImmortal() != DataType.Any)
{
return true;
}
@@ -195,10 +215,14 @@
}
// Move to Filter Service
bool InvalidNonVanguard(EntityModel entity) {
if (entity.Replaceds().Count > 0) {
foreach (var replaced in entity.Replaceds()) {
if (FilterService.GetImmortal() == replaced.ImmortalId) {
bool InvalidNonVanguard(EntityModel entity)
{
if (entity.Replaceds().Count > 0)
{
foreach (var replaced in entity.Replaceds())
{
if (FilterService.GetImmortal() == replaced.ImmortalId)
{
return true;
}
}
@@ -207,90 +231,114 @@
return false;
}
bool InvalidKey(EntityModel entity, HotkeyModel key) {
if (entity.Hotkey()?.Hotkey == key.KeyText) {
bool InvalidKey(EntityModel entity, HotkeyModel key)
{
if (entity.Hotkey()?.Hotkey == key.KeyText)
{
return false;
}
return true;
}
bool InvalidKeyGroup(EntityModel entity, HotkeyModel key) {
if (entity.Hotkey()?.HotkeyGroup == controlGroup) {
bool InvalidKeyGroup(EntityModel entity, HotkeyModel key)
{
if (entity.Hotkey()?.HotkeyGroup == controlGroup)
{
return false;
}
return true;
}
bool InvalidKey(EntityModel entity) {
if (entity.Hotkey()?.Hotkey == key) {
bool InvalidKey(EntityModel entity)
{
if (entity.Hotkey()?.Hotkey == key)
{
return false;
}
return true;
}
bool InvalidKeyGroup(EntityModel entity) {
if (entity.Hotkey()?.HotkeyGroup == controlGroup) {
bool InvalidKeyGroup(EntityModel entity)
{
if (entity.Hotkey()?.HotkeyGroup == controlGroup)
{
return false;
}
return true;
}
bool InvalidHoldSpace(EntityModel entity) {
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace()) {
bool InvalidHoldSpace(EntityModel entity)
{
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace())
{
return false;
}
return true;
}
void OnKeyPressed() {
void OnKeyPressed()
{
var controlGroupWas = controlGroup;
var keyWas = key;
if (KeyService.GetAllPressedKeys().Contains("Z")) {
if (KeyService.GetAllPressedKeys().Contains("Z"))
{
controlGroup = "Z";
}
if (KeyService.GetAllPressedKeys().Contains("TAB")) {
if (KeyService.GetAllPressedKeys().Contains("TAB"))
{
controlGroup = "TAB";
}
if (KeyService.GetAllPressedKeys().Contains("C")) {
if (KeyService.GetAllPressedKeys().Contains("C"))
{
controlGroup = "C";
}
if (KeyService.GetAllPressedKeys().Contains("D")) {
if (KeyService.GetAllPressedKeys().Contains("D"))
{
controlGroup = "D";
}
if (KeyService.GetAllPressedKeys().Contains("V")) {
if (KeyService.GetAllPressedKeys().Contains("V"))
{
controlGroup = "V";
}
if (KeyService.GetAllPressedKeys().Contains("ALT")) {
if (KeyService.GetAllPressedKeys().Contains("ALT"))
{
controlGroup = "ALT";
}
if (KeyService.GetAllPressedKeys().Contains("SHIFT")) {
if (KeyService.GetAllPressedKeys().Contains("SHIFT"))
{
controlGroup = "SHIFT";
}
if (KeyService.GetAllPressedKeys().Contains("CONTROL")) {
if (KeyService.GetAllPressedKeys().Contains("CONTROL"))
{
controlGroup = "CONTROL";
}
if (KeyService.GetAllPressedKeys().Count > 0) {
if (KeyService.GetAllPressedKeys().Count > 0)
{
key = KeyService.GetAllPressedKeys().First();
}
if (controlGroupWas != controlGroup || keyWas != key) {
if (controlGroupWas != controlGroup || keyWas != key)
{
StateHasChanged();
}
}
private void HandleClick() {
private void HandleClick()
{
var hotkey = KeyService.GetHotkey();
if (hotkey == "") {
if (hotkey == "")
{
return;
}
if (hotkey == "`") {
if (hotkey == "`")
{
BuildOrderService.RemoveLast();
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
return;
@@ -303,31 +351,38 @@
var entity = EntityModel.GetFrom(hotkey!, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) {
if (entity == null)
{
return;
}
if (BuildOrderService.Add(entity, EconomyService)) {
if (BuildOrderService.Add(entity, EconomyService))
{
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
}
}
private void ButtonClicked(MouseEventArgs mouseEventArgs, HotkeyModel hotkey) {
private void ButtonClicked(MouseEventArgs mouseEventArgs, HotkeyModel hotkey)
{
DataCollectionService.SendEvent(
DataCollectionKeys.BuildCalcInput,
new Dictionary<string, string> { { "key", hotkey.KeyText.ToLower() }, { "input-source", "mouse" } }
);
if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString())) {
if (KeyService.IsHoldingSpace()) {
if (hotkey.KeyText.Equals(HotKeyType.SPACE.ToString()))
{
if (KeyService.IsHoldingSpace())
{
KeyService.RemovePressedKey(hotkey.KeyText);
}
else {
else
{
KeyService.AddPressedKey(hotkey.KeyText);
}
}
else {
else
{
KeyService.AddPressedKey(hotkey.KeyText);
KeyService.RemovePressedKey(hotkey.KeyText);
}
@@ -22,10 +22,10 @@
private void HandleKeyDown(KeyboardEventArgs e)
{
DataCollectionService.SendEvent(
DataCollectionKeys.BuildCalcInput,
new Dictionary<string, string> {{"key", e.Key.ToLower()}, {"input-source", "keyboard"}}
DataCollectionKeys.BuildCalcInput,
new Dictionary<string, string> { { "key", e.Key.ToLower() }, { "input-source", "keyboard" } }
);
KeyService.AddPressedKey(e.Key);
}
@@ -4,8 +4,6 @@
@inject IEconomyService EconomyService
@inject IToastService ToastService
@inject ITimingService TimingService
@using System.Data
@implements IDisposable
<FormLayoutComponent>
@@ -57,7 +55,7 @@
RefreshDefaults();
}
void IDisposable.Dispose()
{
TimingService.Unsubscribe(RefreshDefaults);
@@ -70,7 +68,6 @@
WaitTo = TimingService.WaitTo;
StateHasChanged();
}
void OnBuildingInputDelayChanged(ChangeEventArgs changeEventArgs)
@@ -83,7 +80,7 @@
TimingService.WaitTime = (int)changeEventArgs.Value!;
WaitTime = (int)changeEventArgs.Value!;
}
void OnWaitToChanged(ChangeEventArgs changeEventArgs)
{
TimingService.WaitTo = (int)changeEventArgs.Value!;
@@ -36,7 +36,7 @@
base.OnInitialized();
timingService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose()
{
timingService.Unsubscribe(StateHasChanged);
+2 -2
View File
@@ -75,10 +75,10 @@
{
base.OnParametersSet();
base.OnInitialized();
FocusEntity();
}
private void FocusEntity()
{
foreach (var e in DATA.Get().Values)
@@ -9,11 +9,12 @@
{
styleClass = "selected";
}
<button @onclick="@(e => OnChangeFaction(choice))"
class="choiceButton @styleClass">@(choice == DataType.Any
? DataType.Any
: DATA.Get()[choice].Info().Name)
</button>
<button @onclick="@(e => OnChangeFaction(choice))"
class="choiceButton @styleClass">
@(choice == DataType.Any
? DataType.Any
: DATA.Get()[choice].Info().Name)
</button>
}
</div>
@@ -18,7 +18,7 @@ else
<div class="docFooter">
<LinkButtonComponent Href="@GitUrl">
Edit on GitHub <i class="fa-brands fa-github" style="font-size: 24px; margin-left: 5px;"></i>
</LinkButtonComponent>
</LinkButtonComponent>
</div>
</div>
}
@@ -59,7 +59,7 @@ else
public DocContentModel DocContentModel { get; set; } = default!;
DocFrontMatterModel docFrontMatter = null!;
private string? content = null;
private string? content;
private string Filepath => $"content/docs/{DocContentModel.Content}.md";
private string GitUrl => $"{Project.GitResourcesUrl}/{Filepath}";
@@ -8,7 +8,7 @@
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Economy Comparision</WebsiteTitleComponent>
<PaperComponent>
<div>You</div>
<EconomyInputComponent ForPlayer="0"/>
@@ -42,6 +42,7 @@
</LayoutMediumContentComponent>
@code {
protected override void OnInitialized()
{
base.OnInitialized();
@@ -52,4 +53,5 @@
{
EconomyComparisonService.Unsubscribe(StateHasChanged);
}
}
@@ -17,7 +17,7 @@
@foreach (var point in chart.Points)
{
var xCoord = point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax);
var show = int.Parse(xCoord) / 6 % 2;
var player = index - 1;
@@ -79,18 +79,17 @@
void OnBuilderOrderChanged()
{
charts = new List<ChartModel>();
var index = 0;
highestAlloyPoint = 0;
foreach (var buildToCompare in economyComparisonService.BuildsToCompare)
{
GenerateChart(index++, buildToCompare);
}
StateHasChanged();
}
@@ -124,7 +123,6 @@
};
for (var interval = 0; interval < economyOverTime.Count(); interval++)
{
var alloyPoint = new PointModel { Interval = interval };
@@ -63,13 +63,13 @@
@code {
private int StartingAdvantageAtTime = 0;
private int PeakAdvantageByAlloy = 0;
private int PeakAdvantageAtTime = 0;
private int WorseningTime = 0;
private int MiracleTime = 0;
protected override void OnInitialized()
{
base.OnInitialized();
@@ -87,8 +87,8 @@
StartingAdvantageAtTime = 0;
WorseningTime = 0;
MiracleTime = 0;
for (int interval = 0; interval < economyComparisonService.BuildsToCompare[0].EconomyOverTimeModel.Count; interval++)
for (var interval = 0; interval < economyComparisonService.BuildsToCompare[0].EconomyOverTimeModel.Count; interval++)
{
var yourEconomy = economyComparisonService.BuildsToCompare[0].EconomyOverTimeModel[interval];
var theirEconomy = economyComparisonService.BuildsToCompare[1].EconomyOverTimeModel[interval];
@@ -109,16 +109,15 @@
}
else
{
if (PeakAdvantageByAlloy > 0 && WorseningTime == 0)
{
WorseningTime = interval;
}
}
if (deltaEconomy < -1000 && MiracleTime == 0)
{
MiracleTime = interval;
}
}
}
}
@@ -14,22 +14,22 @@
<FormLabelComponent>Number of TownHall Expansions</FormLabelComponent>
</FormNumberComponent>
<ContentDividerComponent/>
@{
var index = 0;
}
@foreach (var timing in TownHallTimings)
{
index++;
<FormNumberComponent Value="@timing" OnChange="(e)=> ChangeBuildTime(e, index - 1)">
<FormLabelComponent>
TownHall build time
</FormLabelComponent>
</FormNumberComponent>
}
<FormNumberComponent Value="@timing" OnChange="e => ChangeBuildTime(e, index - 1)">
<FormLabelComponent>
TownHall build time
</FormLabelComponent>
</FormNumberComponent>
}
<ContentDividerComponent/>
<FormTextComponent Label="Chart Color" Value="@ChartColor" OnChange="ChangeColor" />
<FormTextComponent Label="Chart Color" Value="@ChartColor" OnChange="ChangeColor"/>
</FormLayoutComponent>
@@ -46,7 +46,7 @@
private string ChartColor => economyComparisonService.GetColor(ForPlayer);
private string Faction => economyComparisonService.GetFaction(ForPlayer);
private List<int> TownHallTimings => economyComparisonService.GetTownHallBuildTimes(ForPlayer);
protected override void OnInitialized()
{
base.OnInitialized();
+108 -80
View File
@@ -12,7 +12,7 @@
<PaperComponent>
Credit to Zard for deriving the formula.
</PaperComponent>
<PaperComponent>
<LayoutRowComponent>
<LayoutColumnComponent>
@@ -41,29 +41,31 @@
</FormNumberComponent>
<FormNumberComponent Min="1"
Id="numberOfTownHallsExisting"
Id="numberOfTownHallsExisting"
Value="@((int)NumberOfTownHallsExisting)"
OnChange="OnTownHallsChanged">
<FormLabelComponent>Number of townhalls you have</FormLabelComponent>
</FormNumberComponent>
<div id="numberOfTownHallTravelTimes">
@{
var index = 0;
}
@foreach (var travelTime in TravelTimes) {
index++;
if (index == 1) {
continue;
@{
var index = 0;
}
@foreach (var travelTime in TravelTimes)
{
index++;
if (index == 1)
{
continue;
}
var id = $"numberOfTownHallsExisting_{index}";
<FormNumberComponent Min="0"
Id="@id"
Value="@((int)travelTime.Value)"
OnChange="e => { OnTownHallTravelTimeChanged(e, travelTime); }">
<FormLabelComponent>Worker travel time from other base @(travelTime.Index + 1)</FormLabelComponent>
</FormNumberComponent>
}
var id = $"numberOfTownHallsExisting_{index}";
<FormNumberComponent Min="0"
Id="@id"
Value="@((int)travelTime.Value)"
OnChange="e => { OnTownHallTravelTimeChanged(e, travelTime); }">
<FormLabelComponent>Worker travel time from other base @(travelTime.Index + 1)</FormLabelComponent>
</FormNumberComponent>
}
</div>
@@ -71,7 +73,7 @@
<Display>
<div style="font-size: 1.5rem; font-weight: 800;">
<span id="totalAlloyHarassment">
@TotalAlloyHarassment
@TotalAlloyHarassment
</span>
</div>
</Display>
@@ -90,7 +92,7 @@
<div>
(<b>Average travel time:</b> <span id="getAverageTravelTime">@GetAverageTravelTime()</span>)
</div>
</LayoutColumnComponent>
</LayoutRowComponent>
</PaperComponent>
@@ -104,9 +106,12 @@
</InfoQuestionComponent>
<InfoAnswerComponent>
The Harass Calculator allows you to calculate damage done to an enemy alloy line. For example, if you
were to attack with Ichors, and kill 6 enemy workers, you can set the <b>Number of workers lost to
harass</b> to 6. This would determine a loss of <span id="exampleTotalAlloyLoss">@ExampleTotalAlloyLoss</span> alloy. Quite
the large number.
were to attack with Ichors, and kill 6 enemy workers, you can set the
<b>
Number of workers lost to
harass
</b> to 6. This would determine a loss of <span id="exampleTotalAlloyLoss">@ExampleTotalAlloyLoss</span> alloy. Quite
the large number.
</InfoAnswerComponent>
</InfoBodyComponent>
@@ -115,21 +120,27 @@
What can I learn from this?
</InfoQuestionComponent>
<InfoAnswerComponent>
Well, let's assume you lost a full alloy line of workers, and have to take that
@ExampleTotalAlloyLoss alloy cost (<span id="exampleWorkerCost">@ExampleWorkerCost</span>
to rebuy the workers, and <span id="exampleMiningTimeCost">@ExampleMiningTimeCost</span> in lost mining
Well, let's assume you lost a full alloy line of workers, and have to take that
@ExampleTotalAlloyLoss alloy cost (<span id="exampleWorkerCost">@ExampleWorkerCost</span>
to rebuy the workers, and <span id="exampleMiningTimeCost">@ExampleMiningTimeCost</span> in lost mining
time.)
<br/><br/>
If you were to set the <b>Number of townhalls you have</b> to 2, the calculator will consider worker
transfer micro. Allowing you to cut the total cost by roughly
<span id="exampleTotalAlloyLossDifference">@ExampleTotalAlloyLossDifference</span> alloy. However, that number isn't
If you were to set the <b>Number of townhalls you have</b> to 2, the calculator will consider worker
transfer micro. Allowing you to cut the total cost by roughly
<span id="exampleTotalAlloyLossDifference">@ExampleTotalAlloyLossDifference</span> alloy. However, that number isn't
entirely accurate, you are also going to have to bump up the <b>Worker travel time to alloy</b> to account for the time it takes the transferred workers to arrive at the decimated alloy line.
<br/><br/>
Let's say it takes 10 seconds for workers to transfer from your second base. Let's enter that for the
second base travel time for the more accurate loss of <span
id="exampleTotalAlloyLossAccurate">@ExampleTotalAlloyLossAccurate</span> alloy
(saving you <span id="exampleTotalAlloyLossAccurateDifference">@ExampleTotalAlloyLossAccurateDifference</span> alloy.) <i>Which is
much better than not transferring workers!</i>
second base travel time for the more accurate loss of
<span
id="exampleTotalAlloyLossAccurate">
@ExampleTotalAlloyLossAccurate
</span> alloy
(saving you <span id="exampleTotalAlloyLossAccurateDifference">@ExampleTotalAlloyLossAccurateDifference</span> alloy.)
<i>
Which is
much better than not transferring workers!
</i>
</InfoAnswerComponent>
</InfoBodyComponent>
@@ -213,30 +224,30 @@
@code {
// Example calcs
float ExampleTotalAlloyLoss => Calculate(
WorkerReplacementCost(6),
SimultaneousProductionFloor(1,6),
6,
WorkerReplacementCost(6),
SimultaneousProductionFloor(1, 6),
6,
new List<float> { 0 });
float ExampleWorkerCost => WorkerReplacementCost(6);
float ExampleMiningTimeCost => ExampleTotalAlloyLoss - ExampleWorkerCost;
float ExampleTotalAlloyLossDifference => ExampleTotalAlloyLoss - Calculate(
WorkerReplacementCost(6),
SimultaneousProductionFloor(2,6),
6,
WorkerReplacementCost(6),
SimultaneousProductionFloor(2, 6),
6,
new List<float> { 0, 0 });
float ExampleTotalAlloyLossAccurate => Calculate(
WorkerReplacementCost(6),
SimultaneousProductionFloor(2,6),
6,
WorkerReplacementCost(6),
SimultaneousProductionFloor(2, 6),
6,
new List<float> { 0, 10 });
float ExampleTotalAlloyLossAccurateDifference => ExampleTotalAlloyLoss - ExampleTotalAlloyLossAccurate;
float TotalAlloyHarassment = 0;
float TotalAlloyHarassment;
readonly float CostOfWorker = 50;
readonly float AlloyMinedPerSecondByWorker = 1;
@@ -244,14 +255,17 @@
float NumberOfWorkersLostToHarass = 1;
float NumberOfTownHallsExisting = 1;
float GetAverageTravelTime() {
if (TravelTimes.Count == 0) {
float GetAverageTravelTime()
{
if (TravelTimes.Count == 0)
{
return 0;
}
float sum = 0;
foreach (var travelTime in TravelTimes) {
foreach (var travelTime in TravelTimes)
{
sum += travelTime.Value;
}
@@ -259,62 +273,73 @@
}
float SimultaneousProductionFloor() {
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0) {
float SimultaneousProductionFloor()
{
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0)
{
return 0;
}
return NumberOfWorkersLostToHarass / Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass);
}
float SimultaneousProductionFloor(float existingTownHalls, float numberOfWorkersLost) {
if (existingTownHalls <= 0 || numberOfWorkersLost <= 0) {
float SimultaneousProductionFloor(float existingTownHalls, float numberOfWorkersLost)
{
if (existingTownHalls <= 0 || numberOfWorkersLost <= 0)
{
return 0;
}
return numberOfWorkersLost / Math.Min(existingTownHalls, numberOfWorkersLost);
}
float WorkerReplacementCost() {
float WorkerReplacementCost()
{
return CostOfWorker * NumberOfWorkersLostToHarass;
}
float WorkerReplacementCost(int numberOfWorkersLostToHarass) {
float WorkerReplacementCost(int numberOfWorkersLostToHarass)
{
return CostOfWorker * numberOfWorkersLostToHarass;
}
float DelayedMiningCost() {
float DelayedMiningCost()
{
return TotalAlloyHarassment - WorkerReplacementCost();
}
void Calculate() {
TotalAlloyHarassment = Calculate(WorkerReplacementCost(),
SimultaneousProductionFloor(),
NumberOfWorkersLostToHarass,
void Calculate()
{
TotalAlloyHarassment = Calculate(WorkerReplacementCost(),
SimultaneousProductionFloor(),
NumberOfWorkersLostToHarass,
TravelTimes.Select(x => x.Value).ToList(),
TimeToProduceWorker,
TimeToProduceWorker,
AlloyMinedPerSecondByWorker);
}
float Calculate(float workerReplacementCost,
float simultaneousProductionFloor,
float numberOfWorkersLostToHarass,
IList<float> travelTimes,
float timeToProduceWorker = 20,
float alloyMinedPerSecondByWorker = 1) {
float totalAlloyHarassment = workerReplacementCost;
for (var workerProductionIndex = 0; workerProductionIndex < simultaneousProductionFloor; workerProductionIndex++) {
float Calculate(float workerReplacementCost,
float simultaneousProductionFloor,
float numberOfWorkersLostToHarass,
IList<float> travelTimes,
float timeToProduceWorker = 20,
float alloyMinedPerSecondByWorker = 1)
{
var totalAlloyHarassment = workerReplacementCost;
for (var workerProductionIndex = 0; workerProductionIndex < simultaneousProductionFloor; workerProductionIndex++)
{
totalAlloyHarassment += alloyMinedPerSecondByWorker * timeToProduceWorker * (workerProductionIndex + 1);
}
var remainder = (int)(numberOfWorkersLostToHarass % simultaneousProductionFloor);
for (var remainderIndex = 0; remainderIndex < remainder; remainderIndex++) {
for (var remainderIndex = 0; remainderIndex < remainder; remainderIndex++)
{
totalAlloyHarassment += alloyMinedPerSecondByWorker * timeToProduceWorker * (simultaneousProductionFloor + 1);
}
for (var travelTimeIndex = 0; travelTimeIndex < numberOfWorkersLostToHarass; travelTimeIndex++) {
for (var travelTimeIndex = 0; travelTimeIndex < numberOfWorkersLostToHarass; travelTimeIndex++)
{
var townHallIndex = travelTimeIndex % travelTimes.Count;
totalAlloyHarassment += alloyMinedPerSecondByWorker * travelTimes[townHallIndex];
}
@@ -322,7 +347,8 @@
return totalAlloyHarassment;
}
protected override void OnInitialized() {
protected override void OnInitialized()
{
base.OnInitialized();
Calculate();
}
@@ -330,18 +356,20 @@
public List<TravelTime> TravelTimes { get; set; } = new() { new TravelTime(0, 0) };
private void OnTownHallsChanged(ChangeEventArgs obj) {
private void OnTownHallsChanged(ChangeEventArgs obj)
{
NumberOfTownHallsExisting = int.Parse(obj.Value!.ToString()!);
while (TravelTimes.Count > NumberOfTownHallsExisting)
TravelTimes.Remove(TravelTimes.Last());
while (TravelTimes.Count < NumberOfTownHallsExisting)
TravelTimes.Add(new TravelTime(TravelTimes.Count, 10 * (TravelTimes.Count)));
TravelTimes.Add(new TravelTime(TravelTimes.Count, 10 * TravelTimes.Count));
Calculate();
}
private void OnTownHallTravelTimeChanged(ChangeEventArgs obj, TravelTime travelTime) {
private void OnTownHallTravelTimeChanged(ChangeEventArgs obj, TravelTime travelTime)
{
travelTime.Value = (int)obj.Value!;
Calculate();
+1 -1
View File
@@ -17,7 +17,7 @@
else
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Notes</WebsiteTitleComponent>
<PaperComponent>
-2
View File
@@ -16,8 +16,6 @@
}
else
{
<LayoutWithSidebarComponent>
<Sidebar>
<NoteNavComponent
+5 -4
View File
@@ -47,10 +47,11 @@
<InfoBodyComponent>
<InfoQuestionComponent>What data does this website collect?</InfoQuestionComponent>
<InfoAnswerComponent>This website usages Google Analytics to collect data on usage of this website.
<InfoAnswerComponent>
This website usages Google Analytics to collect data on usage of this website.
<br/><br/>
Items include: if people use keyboard or mouse in build calculator, what pages people visit, and other usages.
</InfoAnswerComponent>
</InfoAnswerComponent>
</InfoBodyComponent>
<InfoBodyComponent>
@@ -62,8 +63,8 @@
@code {
private bool _storageEnabled = false;
private bool _dataCollectionEnabled = false;
private bool _storageEnabled;
private bool _dataCollectionEnabled;
protected override void OnInitialized()
{
+12 -12
View File
@@ -28,14 +28,14 @@
<DevOnlyComponent>
<FormLayoutComponent>
<FormToggleComponent
Label="Is Dynamic Formatting"
Info="Should [Attacks Per Second/Seconds Between Attack] match in-game values?"
Value="@_isDynamicFormatting"
OnChange="DynamicFormattingChanged"/>
</FormLayoutComponent>
<FormToggleComponent
Label="Is Dynamic Formatting"
Info="Should [Attacks Per Second/Seconds Between Attack] match in-game values?"
Value="@_isDynamicFormatting"
OnChange="DynamicFormattingChanged"/>
</FormLayoutComponent>
</DevOnlyComponent>
</PaperComponent>
<PaperComponent>
@@ -148,7 +148,7 @@
protected override void OnInitialized()
{
base.OnInitialized();
_enabledPermissions = StorageService.GetValue<bool>(StorageKeys.EnabledStorage);
RefreshDefaults();
@@ -161,11 +161,11 @@
StorageService.Unsubscribe(RefreshDefaults);
}
private int? _attackTime = null;
private int? _travelTime = null;
private int? _attackTime;
private int? _travelTime;
private string? _faction = null;
private string? _immortal = null;
private string? _faction;
private string? _immortal;
private string? Faction => _faction == null ? DataType.FACTION_QRath : _faction;
private string? Immortal => _immortal == null ? DataType.IMMORTAL_Orzum : _immortal;
+13 -9
View File
@@ -14,21 +14,25 @@
</InfoBodyComponent>
<InfoBodyComponent>
<InfoQuestionComponent>What exactly are you streaming?</InfoQuestionComponent>
<InfoAnswerComponent>The plan will be sprint planning and general development of this website.
<InfoAnswerComponent>
The plan will be sprint planning and general development of this website.
<br/><br/>
Feel free to jump into the stream to ask questions or make feature requests for the website.</InfoAnswerComponent>
Feel free to jump into the stream to ask questions or make feature requests for the website.
</InfoAnswerComponent>
</InfoBodyComponent>
<InfoBodyComponent>
<InfoQuestionComponent>Why should you watch these streams?</InfoQuestionComponent>
<InfoAnswerComponent>You shouldn't. By nature of being live coding streams, I think they will have little entertainment and educational value.
<InfoAnswerComponent>
You shouldn't. By nature of being live coding streams, I think they will have little entertainment and educational value.
<br/><br/>
The most reason (that comes to mind) is to see a coding day of one software developer. Although please note that I stream content that I think is easy (to look smart), so it's not a "truly random" coding day. For example, you won't find any vods of the five-week sprint where I (figuratively) bash my head against the table trying to get SQL working in Blazor WASM before giving up and moving on. </InfoAnswerComponent>
The most reason (that comes to mind) is to see a coding day of one software developer. Although please note that I stream content that I think is easy (to look smart), so it's not a "truly random" coding day. For example, you won't find any vods of the five-week sprint where I (figuratively) bash my head against the table trying to get SQL working in Blazor WASM before giving up and moving on.
</InfoAnswerComponent>
</InfoBodyComponent>
<InfoBodyComponent>
<InfoQuestionComponent>Anything else I should know?</InfoQuestionComponent>
<InfoAnswerComponent>I'll be streaming under the "<a href="https://www.twitch.tv/directory/game/Software%20and%20Game%20Development" target="_blank">Twitch, Software and Game Development</a>" category. If you are looking to see some actual IGP gameplay, there are better and more focused streamers to provide said content. Check out the "<a href="https://www.twitch.tv/directory/game/IMMORTAL%3A%20Gates%20of%20Pyre/videos/all" target="_blank">Twitch, IMMORTAL: Gates of Pyre</a>" category for some examples.</InfoAnswerComponent>
</InfoBodyComponent>
<InfoQuestionComponent>Anything else I should know?</InfoQuestionComponent>
<InfoAnswerComponent>I'll be streaming under the "<a href="https://www.twitch.tv/directory/game/Software%20and%20Game%20Development" target="_blank">Twitch, Software and Game Development</a>" category. If you are looking to see some actual IGP gameplay, there are better and more focused streamers to provide said content. Check out the "<a href="https://www.twitch.tv/directory/game/IMMORTAL%3A%20Gates%20of%20Pyre/videos/all" target="_blank">Twitch, IMMORTAL: Gates of Pyre</a>" category for some examples.</InfoAnswerComponent>
</InfoBodyComponent>
</PaperComponent>
</LayoutMediumContentComponent>