feature(BuildCalc) Added reset button, can change micro delay, and can alter timing interval again

This commit is contained in:
2022-04-14 22:28:14 -04:00
parent 4cef578cd0
commit 04c1718259
115 changed files with 1561 additions and 1308 deletions
+33 -20
View File
@@ -3,48 +3,51 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using Model.BuildOrders;
using Model.Entity;
using Model.Entity.Data;
using YamlDotNet.Serialization;
namespace Services.Immortal;
public class BuildComparisionService : IBuildComparisonService {
private event Action OnChange = default!;
public class BuildComparisionService : IBuildComparisonService
{
private BuildComparisonModel buildComparison = new();
public void Subscribe(Action action) {
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action) {
public void Unsubscribe(Action action)
{
OnChange -= action;
}
private void NotifyDataChanged() {
OnChange?.Invoke();
}
public void SetBuilds(BuildComparisonModel buildComparisonModel) {
public void SetBuilds(BuildComparisonModel buildComparisonModel)
{
buildComparison = buildComparisonModel;
NotifyDataChanged();
}
public BuildComparisonModel Get() {
public BuildComparisonModel Get()
{
return buildComparison;
}
public string AsJson() {
var options = new JsonSerializerOptions {
public string AsJson()
{
var options = new JsonSerializerOptions
{
WriteIndented = true
};
options.Converters.Add(new JsonStringEnumConverter());
return JsonSerializer.Serialize(buildComparison, options);
}
public bool LoadJson(string data) {
try {
var options = new JsonSerializerOptions {
public bool LoadJson(string data)
{
try
{
var options = new JsonSerializerOptions
{
WriteIndented = true
};
options.Converters.Add(new JsonStringEnumConverter());
@@ -56,12 +59,14 @@ public class BuildComparisionService : IBuildComparisonService {
NotifyDataChanged();
return true;
}
catch {
catch
{
return false;
}
}
public string BuildOrderAsYaml() {
public string BuildOrderAsYaml()
{
var stringBuilder = new StringBuilder();
var serializer = new Serializer();
stringBuilder.AppendLine(serializer.Serialize(buildComparison));
@@ -69,8 +74,16 @@ public class BuildComparisionService : IBuildComparisonService {
return buildOrderText;
}
private event Action OnChange = default!;
public void HydratedLoadedJson() {
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
public void HydratedLoadedJson()
{
foreach (var build in buildComparison.Builds)
foreach (var orders in build.StartedOrders.Values)
foreach (var order in orders)
+72 -17
View File
@@ -12,11 +12,14 @@ namespace Services.Immortal;
public class BuildOrderService : IBuildOrderService
{
private readonly BuildOrderModel buildOrder = new();
private readonly int HumanMicro = 2;
private int lastInterval;
private BuildOrderModel buildOrder = new();
public int BuildingInputDelay { get; set; } = 2;
private int lastInterval = 0;
private event Action OnChange = null!;
public BuildOrderService()
{
Reset();
}
public Dictionary<int, List<EntityModel>> StartedOrders => buildOrder.StartedOrders;
public Dictionary<int, List<EntityModel>> CompletedOrders => buildOrder.CompletedOrders;
@@ -92,7 +95,6 @@ public class BuildOrderService : IBuildOrderService
var metTime = 0;
foreach (var requiredEntity in requirements)
{
if (buildOrder.UniqueCompletedTimes.TryGetValue(requiredEntity.Id, out var completedTime))
{
if (completedTime > metTime) metTime = completedTime;
@@ -101,7 +103,6 @@ public class BuildOrderService : IBuildOrderService
{
return null;
}
}
return metTime;
}
@@ -135,7 +136,6 @@ public class BuildOrderService : IBuildOrderService
public void RemoveLast()
{
if (buildOrder.StartedOrders.Keys.Count > 1)
{
var lastStarted = buildOrder.StartedOrders.Keys.Last();
@@ -160,16 +160,15 @@ public class BuildOrderService : IBuildOrderService
if (entityRemoved.Supply()?.Grants > 0)
SupplyCountTimes.Remove(SupplyCountTimes.Last().Key);
if (entityRemoved.Supply()?.Takes > 0)
buildOrder.CurrentSupplyUsed -= entityRemoved.Supply()!.Takes;
buildOrder.UniqueCompletedCount[entityRemoved!.DataType]--;
if (buildOrder.UniqueCompletedCount[entityRemoved!.DataType] == 0) {
if (buildOrder.UniqueCompletedCount[entityRemoved!.DataType] == 0)
UniqueCompletedTimes.Remove(entityRemoved.DataType);
}
if (entityRemoved.Info().Descriptive == DescriptiveType.Worker)
{
RemoveLast();
@@ -252,6 +251,65 @@ public class BuildOrderService : IBuildOrderService
return buildOrder.Color;
}
public void Reset()
{
lastInterval = 0;
buildOrder = new BuildOrderModel
{
StartedOrders = new Dictionary<int, List<EntityModel>>
{
{
0,
new List<EntityModel>
{
EntityModel.Get(DataType.STARTING_Bastion),
EntityModel.Get(DataType.STARTING_TownHall_Aru)
}
}
},
CompletedOrders = new Dictionary<int, List<EntityModel>>
{
{
0,
new List<EntityModel>
{
EntityModel.Get(DataType.STARTING_Bastion),
EntityModel.Get(DataType.STARTING_TownHall_Aru)
}
}
},
UniqueCompletedTimes = new Dictionary<string, int>
{
{
DataType.STARTING_Bastion, 0
},
{
DataType.STARTING_TownHall_Aru, 0
}
},
UniqueCompletedCount = new Dictionary<string, int>
{
{
DataType.STARTING_Bastion, 1
},
{
DataType.STARTING_TownHall_Aru, 1
}
},
SupplyCountTimes = new Dictionary<int, int>
{
{
0, 0
}
}
};
NotifyDataChanged();
}
private event Action OnChange = null!;
private bool HandleEconomy(EntityModel entity, IEconomyService withEconomy, IToastService withToasts,
ref int atInterval)
{
@@ -266,12 +324,9 @@ public class BuildOrderService : IBuildOrderService
economyAtSecond.Pyre >= production.Pyre)
{
atInterval = interval;
if (entity.EntityType != EntityType.Army)
{
atInterval += HumanMicro;
}
if (entity.EntityType != EntityType.Army) atInterval += BuildingInputDelay;
return true;
}
+35 -26
View File
@@ -1,43 +1,47 @@
using Model.Economy;
using Model.Entity;
using Model.Feedback;
using Model.Types;
using Services.Website;
namespace Services.Immortal;
public class EconomyService : IEconomyService {
public class EconomyService : IEconomyService
{
private List<EconomyModel> _economyOverTime = null!;
private event Action OnChange = null!;
public List<EconomyModel> GetOverTime() {
public List<EconomyModel> GetOverTime()
{
return _economyOverTime;
}
public void Subscribe(Action action) {
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action) {
public void Unsubscribe(Action action)
{
OnChange -= action;
}
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval) {
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval)
{
//TODO Break all this up
if (_economyOverTime == null) {
if (_economyOverTime == null)
{
_economyOverTime = new List<EconomyModel>();
for (var interval = 0; interval < timing.GetTiming(); interval++)
_economyOverTime.Add(new EconomyModel { Interval = interval });
}
if (_economyOverTime.Count > timing.GetTiming())
_economyOverTime.RemoveRange(timing.GetTiming(), _economyOverTime.Count - timing.GetTiming());
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++)
{
@@ -119,8 +123,6 @@ public class EconomyService : IEconomyService {
// Remove Funds from Build Order
if (buildOrder.StartedOrders.TryGetValue(interval, out var ordersAtTime))
{
foreach (var order in ordersAtTime)
{
var foundEntity = EntityModel.GetDictionary()[order.DataType];
@@ -138,31 +140,38 @@ public class EconomyService : IEconomyService {
if (production.ConsumesWorker) economyAtSecond.WorkerCount -= 1;
}
}
}
// Handle new entities
if (buildOrder.CompletedOrders.TryGetValue(interval, out var completedAtInterval))
{
foreach (var newEntity in completedAtInterval)
{
var harvest = newEntity;
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
{
var harvest = newEntity;
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
var production = newEntity.Production();
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
}
var production = newEntity.Production();
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
}
}
}
NotifyDataChanged();
}
public EconomyModel GetEconomy(int atInterval) {
public EconomyModel GetEconomy(int atInterval)
{
if (atInterval >= _economyOverTime.Count)
{
return _economyOverTime.Last();
}
return _economyOverTime[atInterval];
}
private void NotifyDataChanged() {
private event Action OnChange = null!;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}
+14 -12
View File
@@ -1,28 +1,24 @@
using Model.Types;
namespace Services.Immortal;
namespace Services.Immortal;
public class EntityDisplayService : IEntityDisplayService {
public class EntityDisplayService : IEntityDisplayService
{
private string displayType = "Detailed";
private event Action OnChange = null!;
public List<string> DefaultChoices()
{
return new List<string>() { "Detailed", "Plain" };
return new List<string> { "Detailed", "Plain" };
}
public void Subscribe(Action action) {
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action) {
public void Unsubscribe(Action action)
{
OnChange -= action;
}
private void NotifyDataChanged() {
OnChange?.Invoke();
}
public string GetDisplayType()
{
return displayType;
@@ -34,4 +30,10 @@ public class EntityDisplayService : IEntityDisplayService {
NotifyDataChanged();
}
private event Action OnChange = null!;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}
+58 -33
View File
@@ -4,14 +4,16 @@ using static Services.IEntityFilterService;
namespace Services.Immortal;
public enum EntityFilterEvent {
public enum EntityFilterEvent
{
OnRefreshFaction,
OnRefreshImmortal,
OnRefreshEntity,
OnRefreshSearch
}
public class EntityFilterService : IEntityFilterService {
public class EntityFilterService : IEntityFilterService
{
private readonly List<string> _entityChoices = new();
private readonly List<string> _factionChoices = new() { FactionType.Any, FactionType.QRath, FactionType.Aru };
@@ -20,37 +22,43 @@ public class EntityFilterService : IEntityFilterService {
private string _searchText = "";
private string _selectedFaction = FactionType.Any;
private string _selectedImmortal = ImmortalType.Any;
private event EntityFilterAction OnChange = null!;
public EntityFilterService() {
public EntityFilterService()
{
RefreshImmortalChoices();
RefreshEntityChoices();
}
public void Subscribe(EntityFilterAction action) {
public void Subscribe(EntityFilterAction action)
{
OnChange += action;
}
public void Unsubscribe(EntityFilterAction action) {
public void Unsubscribe(EntityFilterAction action)
{
OnChange -= action;
}
public string GetEntityType() {
public string GetEntityType()
{
return _entityType;
}
public string GetFactionType() {
public string GetFactionType()
{
return _selectedFaction;
}
public string GetImmortalType() {
public string GetImmortalType()
{
return _selectedImmortal;
}
public bool SelectFactionType(string factionType) {
if (_selectedFaction == factionType) {
public bool SelectFactionType(string factionType)
{
if (_selectedFaction == factionType)
{
_selectedFaction = FactionType.None;
_selectedImmortal = ImmortalType.None;
@@ -72,8 +80,10 @@ public class EntityFilterService : IEntityFilterService {
return true;
}
public bool SelectImmortalType(string immortalType) {
if (_selectedImmortal == immortalType) {
public bool SelectImmortalType(string immortalType)
{
if (_selectedImmortal == immortalType)
{
_selectedImmortal = ImmortalType.None;
NotifyDataChanged(EntityFilterEvent.OnRefreshImmortal);
return true;
@@ -84,14 +94,16 @@ public class EntityFilterService : IEntityFilterService {
return true;
}
public bool SelectEntityType(string entityType) {
public bool SelectEntityType(string entityType)
{
if (_entityType == entityType) return false;
_entityType = entityType;
NotifyDataChanged(EntityFilterEvent.OnRefreshEntity);
return true;
}
public bool EnterSearchText(string searchText) {
public bool EnterSearchText(string searchText)
{
if (_searchText.Equals(searchText))
return false;
_searchText = searchText;
@@ -99,23 +111,30 @@ public class EntityFilterService : IEntityFilterService {
return true;
}
public List<string> GetFactionChoices() {
public List<string> GetFactionChoices()
{
return _factionChoices;
}
public List<string> GetImmortalChoices() {
public List<string> GetImmortalChoices()
{
return _immortalChoices;
}
public List<string> GetEntityChoices() {
public List<string> GetEntityChoices()
{
return _entityChoices;
}
public string GetSearchText() {
public string GetSearchText()
{
return _searchText;
}
private void RefreshImmortalChoices() {
private event EntityFilterAction OnChange = null!;
private void RefreshImmortalChoices()
{
_immortalChoices.Clear();
//TODO Consider getting these values from the database
@@ -128,22 +147,27 @@ public class EntityFilterService : IEntityFilterService {
_immortalChoices.Add(ImmortalType.Mala);
_immortalChoices.Add(ImmortalType.Xol);
}*/
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Any) {
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Any)
{
_immortalChoices.Add(DataType.IMMORTAL_Orzum);
_immortalChoices.Add(DataType.IMMORTAL_Ajari);
}
if (_selectedFaction == FactionType.Aru || _selectedFaction == FactionType.Any) {
if (_selectedFaction == FactionType.Aru || _selectedFaction == FactionType.Any)
{
_immortalChoices.Add(DataType.IMMORTAL_Mala);
_immortalChoices.Add(DataType.IMMORTAL_Xol);
}
}
private void RefreshEntityChoices() {
private void RefreshEntityChoices()
{
_entityChoices.Clear();
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Aru || _selectedFaction == FactionType.Any) {
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Aru ||
_selectedFaction == FactionType.Any)
{
_entityChoices.Add(EntityType.Army);
_entityChoices.Add(EntityType.Immortal);
_entityChoices.Add(EntityType.Passive);
@@ -154,21 +178,22 @@ public class EntityFilterService : IEntityFilterService {
_entityChoices.Add(EntityType.Worker);
}
if (_selectedFaction == FactionType.Any) {
_entityChoices.Add(EntityType.Any);
}
if (_selectedFaction == FactionType.Any) _entityChoices.Add(EntityType.Any);
}
private void NotifyDataChanged(EntityFilterEvent entityFilterEvent) {
private void NotifyDataChanged(EntityFilterEvent entityFilterEvent)
{
OnChange?.Invoke(entityFilterEvent);
}
public void Subscribe(Action action) {
public void Subscribe(Action action)
{
throw new NotImplementedException();
}
public void Unsubscribe(Action action) {
public void Unsubscribe(Action action)
{
throw new NotImplementedException();
}
}
+4 -2
View File
@@ -2,8 +2,10 @@
namespace Services.Immortal;
public class EntityService : IEntityService {
public List<EntityModel> GetEntities() {
public class EntityService : IEntityService
{
public List<EntityModel> GetEntities()
{
throw new NotImplementedException();
}
}
+16 -9
View File
@@ -3,27 +3,33 @@ using Model.Types;
namespace Services.Immortal;
public class ImmortalSelectionService : IImmortalSelectionService {
public class ImmortalSelectionService : IImmortalSelectionService
{
private string _selectedFaction = FactionType.QRath;
private string _selectedImmortal = DataType.IMMORTAL_Orzum;
public void Subscribe(Action action) {
public void Subscribe(Action action)
{
OnChange += action;
}
public void Unsubscribe(Action action) {
public void Unsubscribe(Action action)
{
OnChange -= action;
}
public string GetFactionType() {
public string GetFactionType()
{
return _selectedFaction;
}
public string GetImmortalType() {
public string GetImmortalType()
{
return _selectedImmortal;
}
public bool SelectFactionType(string factionType) {
public bool SelectFactionType(string factionType)
{
if (_selectedFaction == factionType) return false;
_selectedFaction = factionType;
@@ -35,7 +41,8 @@ public class ImmortalSelectionService : IImmortalSelectionService {
return true;
}
public bool SelectImmortalType(string immortalType) {
public bool SelectImmortalType(string immortalType)
{
if (_selectedImmortal == immortalType) return false;
_selectedImmortal = immortalType;
NotifyDataChanged();
@@ -44,8 +51,8 @@ public class ImmortalSelectionService : IImmortalSelectionService {
private event Action OnChange = null!;
private void NotifyDataChanged() {
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}
+34 -19
View File
@@ -2,31 +2,35 @@
namespace Services.Immortal;
public class KeyService : IKeyService {
public class KeyService : IKeyService
{
private static readonly List<string> PressedKeys = new();
private string? _hotkey;
private string _hotkeyGroup = "C";
private bool _isHoldingSpace;
private event Action? OnChange;
public void Subscribe(Action? action) {
public void Subscribe(Action? action)
{
OnChange += action;
}
public void Unsubscribe(Action? action) {
public void Unsubscribe(Action? action)
{
OnChange -= action;
}
public bool AddPressedKey(string key) {
public bool AddPressedKey(string key)
{
_hotkey = null;
if (PressedKeys.Count > 0) return false;
var pressedKey = key.ToUpper();
if (pressedKey.Equals(" ") || pressedKey.Equals("SPACE")) {
if (!_isHoldingSpace) {
if (pressedKey.Equals(" ") || pressedKey.Equals("SPACE"))
{
if (!_isHoldingSpace)
{
_isHoldingSpace = true;
NotifyDataChanged();
}
@@ -34,7 +38,8 @@ public class KeyService : IKeyService {
return false;
}
if (!PressedKeys.Contains(pressedKey)) {
if (!PressedKeys.Contains(pressedKey))
{
if (HotkeyModel.KeyGroups.Contains(pressedKey)) _hotkeyGroup = pressedKey;
if (HotkeyModel.HotKeys.Contains(pressedKey)) _hotkey = pressedKey;
@@ -47,16 +52,20 @@ public class KeyService : IKeyService {
return false;
}
public List<string> GetAllPressedKeys() {
public List<string> GetAllPressedKeys()
{
return PressedKeys;
}
public bool RemovePressedKey(string key) {
public bool RemovePressedKey(string key)
{
_hotkey = null;
var pressedKey = key.ToUpper();
if (pressedKey.Equals(" ") || pressedKey.Equals("SPACE")) {
if (_isHoldingSpace || true) {
if (pressedKey.Equals(" ") || pressedKey.Equals("SPACE"))
{
if (_isHoldingSpace || true)
{
_isHoldingSpace = false;
NotifyDataChanged();
}
@@ -64,7 +73,8 @@ public class KeyService : IKeyService {
return false;
}
if (PressedKeys.Contains(pressedKey)) {
if (PressedKeys.Contains(pressedKey))
{
PressedKeys.Remove(pressedKey);
NotifyDataChanged();
return true;
@@ -73,20 +83,25 @@ public class KeyService : IKeyService {
return false;
}
public bool IsHoldingSpace() {
public bool IsHoldingSpace()
{
return _isHoldingSpace;
}
public string? GetHotkey() {
public string? GetHotkey()
{
return _hotkey;
}
public string GetHotkeyGroup() {
public string GetHotkeyGroup()
{
return _hotkeyGroup;
}
private void NotifyDataChanged() {
private event Action? OnChange;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}
+33 -19
View File
@@ -5,31 +5,33 @@ using static Services.IMemoryTesterService;
namespace Services.Immortal;
public enum MemoryTesterEvent {
public enum MemoryTesterEvent
{
OnVerify,
OnRefresh
}
public class MemoryTesterService : IMemoryTesterService {
public class MemoryTesterService : IMemoryTesterService
{
private readonly List<MemoryEntityModel> memoryEntities = MemoryEntityModel.TestData;
private readonly List<MemoryQuestionModel> memoryQuestions = MemoryQuestionModel.TestData;
private readonly Random random = new();
private event MemoryAction OnChange = null!;
public void Subscribe(MemoryAction action) {
public void Subscribe(MemoryAction action)
{
OnChange += action;
}
public void Unsubscribe(MemoryAction action) {
public void Unsubscribe(MemoryAction action)
{
OnChange -= action;
}
public void GenerateQuiz() {
public void GenerateQuiz()
{
memoryEntities.Clear();
memoryQuestions.Clear();
@@ -42,17 +44,21 @@ public class MemoryTesterService : IMemoryTesterService {
var entityIndex = 0;
var questionIndex = 0;
foreach (var unit in units) {
memoryEntities.Add(new MemoryEntityModel {
foreach (var unit in units)
{
memoryEntities.Add(new MemoryEntityModel
{
Id = ++entityIndex,
Name = unit.Info().Name
});
var weaponIndex = 0;
foreach (var weapon in unit.Weapons()) {
foreach (var weapon in unit.Weapons())
{
weaponIndex++;
memoryQuestions.Add(new MemoryQuestionModel {
memoryQuestions.Add(new MemoryQuestionModel
{
Id = ++questionIndex,
MemoryEntityModelId = entityIndex,
Name = $"Range (Weapon {weaponIndex})",
@@ -61,7 +67,8 @@ public class MemoryTesterService : IMemoryTesterService {
});
}
memoryQuestions.Add(new MemoryQuestionModel {
memoryQuestions.Add(new MemoryQuestionModel
{
Id = ++questionIndex,
MemoryEntityModelId = entityIndex,
Name = "Speed",
@@ -73,27 +80,34 @@ public class MemoryTesterService : IMemoryTesterService {
NotifyDataChanged(MemoryTesterEvent.OnRefresh);
}
public List<MemoryEntityModel> GetEntities() {
public List<MemoryEntityModel> GetEntities()
{
return memoryEntities;
}
public List<MemoryQuestionModel> GetQuestions() {
public List<MemoryQuestionModel> GetQuestions()
{
return memoryQuestions;
}
public void Update(MemoryQuestionModel memoryQuestion) {
public void Update(MemoryQuestionModel memoryQuestion)
{
memoryQuestions[memoryQuestion.Id - 1].Guess = memoryQuestion.Guess;
}
public void Verify() {
public void Verify()
{
NotifyDataChanged(MemoryTesterEvent.OnVerify);
}
private event MemoryAction OnChange = null!;
//public delegate void MemoryAction(MemoryTesterActions memoryAction);
private void NotifyDataChanged(MemoryTesterEvent memoryAction) {
private void NotifyDataChanged(MemoryTesterEvent memoryAction)
{
OnChange?.Invoke(memoryAction);
}
}
+16 -10
View File
@@ -1,31 +1,37 @@
namespace Services.Immortal;
public class TimingService : ITimingService {
public class TimingService : ITimingService
{
private int _timing = 1500;
private event Action? OnChange;
public void Subscribe(Action? action) {
public void Subscribe(Action? action)
{
OnChange += action;
}
public void Unsubscribe(Action? action) {
public void Unsubscribe(Action? action)
{
OnChange -= action;
}
public int GetTiming() {
public int GetTiming()
{
return _timing;
}
public void SetTiming(int timing) {
if (_timing != timing) {
public void SetTiming(int timing)
{
if (_timing != timing)
{
_timing = timing;
NotifyDataChanged();
}
}
private void NotifyDataChanged() {
private event Action? OnChange;
private void NotifyDataChanged()
{
OnChange?.Invoke();
}
}