Initial commit

This commit is contained in:
2022-03-28 18:44:08 -04:00
commit e43d9a90e7
267 changed files with 17049 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
using Contexts;
using Microsoft.EntityFrameworkCore;
using Model.Immortal.BuildOrders;
using Model.Immortal.Economy;
using Model.Immortal.Entity;
using Model.Immortal.MemoryTester;
using Model.Website;
using Model.Website.Enums;
using Model.Work.Git;
using Model.Work.Tasks;
using Services.Immortal;
namespace Services;
public interface IAgileService {
public DbSet<SprintModel> SprintModels { get; }
public DbSet<TaskModel> TaskModels { get; }
public void Subscribe(Action action);
public void Unsubscribe(Action action);
public void Update();
public Task Load(DatabaseContext database);
public bool IsLoaded();
}
public interface IWebsiteService {
public DbSet<WebPageModel> WebPageModels { get; }
public DbSet<WebSectionModel> WebSectionModels { get; }
public void Subscribe(Action action);
public void Unsubscribe(Action action);
public void Update();
public Task Load(DatabaseContext database);
public bool IsLoaded();
}
public interface IGitService {
public DbSet<ChangeModel> ChangeModels { get; }
public DbSet<PatchModel> PatchModels { get; }
public void Subscribe(Action action);
public void Unsubscribe(Action action);
public void Update();
public Task Load(DatabaseContext database);
public bool IsLoaded();
}
public interface INavigationService {
public void Subscribe(Action action);
public void Unsubscribe(Action action);
public void ChangeNavigationState(string newState);
public string GetNavigationState();
public void Back();
public void SelectSection(int webSectionType);
public void SelectPage(int pageType, Type webPageType);
public NavSelectionType GetNavSelectionType();
public int GetWebPageId();
public int GetWebSectionId();
public Type GetRenderType();
}
public interface IBuildComparisonService {
public void SetBuilds(BuildComparisonModel buildComparison);
public BuildComparisonModel Get();
public string BuildOrderAsYaml();
public string AsJson();
public bool LoadJson(string data);
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
public interface ITimingService {
public int GetTiming();
public void SetTiming(int timing);
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
public interface IEconomyService {
public List<EconomyModel> GetOverTime();
public EconomyModel GetEconomy(int atInterval);
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval);
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
public interface IEntityFilterService {
public delegate void EntityFilterAction(EntityFilterEvent entityFilterEvent);
public string GetFactionType();
public string GetImmortalType();
public string GetEntityType();
public string GetSearchText();
public List<string> GetFactionChoices();
public List<string> GetImmortalChoices();
public List<string> GetEntityChoices();
public bool SelectFactionType(string factionType);
public bool SelectImmortalType(string immortalType);
public bool SelectEntityType(string entityType);
public bool EnterSearchText(string searchText);
public void Subscribe(EntityFilterAction action);
public void Unsubscribe(EntityFilterAction action);
}
public interface IEntityService {
public List<EntityModel> GetEntities();
}
public interface IImmortalSelectionService {
public string GetFactionType();
public string GetImmortalType();
public bool SelectFactionType(string factionType);
public bool SelectImmortalType(string immortalType);
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
public interface IKeyService {
public List<string> GetAllPressedKeys();
public string GetHotkey();
public string GetHotkeyGroup();
public bool IsHoldingSpace();
public bool AddPressedKey(string key);
public bool RemovePressedKey(string key);
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
public interface IMemoryTesterService {
public delegate void MemoryAction(MemoryTesterEvent memoryEvent);
public List<MemoryEntityModel> GetEntities();
public List<MemoryQuestionModel> GetQuestions();
void GenerateQuiz();
public void Update(MemoryQuestionModel question);
public void Verify();
public void Subscribe(MemoryAction memoryAction);
public void Unsubscribe(MemoryAction memoryAction);
}
public interface IBuildOrderService {
public bool Add(EntityModel entity, IEconomyService withEconomy);
public void Add(EntityModel entity, int atInterval);
public void SetName(string Name);
public string GetName();
public void SetNotes(string Notes);
public string GetNotes();
public void SetColor(string Color);
public string GetColor();
public bool MeetsRequirements(EntityModel entity, int interval);
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> GetHarvestersCompletedBefore(int interval);
public void RemoveLast();
public int GetLastRequestInterval();
public string BuildOrderAsYaml();
public string AsJson();
public void Subscribe(Action action);
public void Unsubscribe(Action action);
}
@@ -0,0 +1,106 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Model.Immortal.BuildOrders;
using Model.Immortal.Entity;
using Model.Immortal.Entity.Data;
using YamlDotNet.Serialization;
namespace Services.Immortal;
public class BuildComparisionService : IBuildComparisonService {
private BuildComparisonModel buildComparison = new() {
Builds = new List<BuildOrderModel> {
new() {
Name = "one base",
Orders = new Dictionary<int, List<EntityModel>> {
{
0, new List<EntityModel> {
new(DataType.STARTING_Bastion, EntityType.Building)
}
}
}
},
new() {
Name = "two base",
Orders = new Dictionary<int, List<EntityModel>> {
{
0, new List<EntityModel> {
new(DataType.STARTING_Bastion, EntityType.Building),
new(DataType.STARTING_Bastion, EntityType.Building)
}
}
}
}
}
};
public void Subscribe(Action action) {
onChange += action;
}
public void Unsubscribe(Action action) {
onChange -= action;
}
public void SetBuilds(BuildComparisonModel buildComparison) {
this.buildComparison = buildComparison;
NotifyDataChanged();
}
public BuildComparisonModel Get() {
return buildComparison;
}
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 {
WriteIndented = true
};
options.Converters.Add(new JsonStringEnumConverter());
buildComparison = JsonSerializer.Deserialize<BuildComparisonModel>(data, options);
// Must Hydrate because not loaded with Parts
HydratedLoadedJson();
NotifyDataChanged();
return true;
}
catch {
return false;
}
}
public string BuildOrderAsYaml() {
var stringBuilder = new StringBuilder();
var serializer = new Serializer();
stringBuilder.AppendLine(serializer.Serialize(buildComparison));
var buildOrderText = stringBuilder.ToString();
return buildOrderText;
}
private event Action onChange;
private void NotifyDataChanged() {
onChange?.Invoke();
}
public Action OnChange() {
return onChange;
}
public void HydratedLoadedJson() {
foreach (var build in buildComparison.Builds)
foreach (var orders in build.Orders.Values)
foreach (var order in orders)
order.Copy(EntityModel.Get(order.DataType));
}
}
+259
View File
@@ -0,0 +1,259 @@
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using Model.Immortal.BuildOrders;
using Model.Immortal.Entity;
using Model.Immortal.Types;
using YamlDotNet.Serialization;
namespace Services.Immortal;
public class BuildOrderService : IBuildOrderService {
public static int HumanMicro = 2;
private readonly BuildOrderModel buildOrder = new();
private int lastInterval;
public int GetLastRequestInterval() {
return lastInterval;
}
public Dictionary<int, List<EntityModel>> GetOrders() {
return buildOrder.Orders;
}
public void Subscribe(Action action) {
onChange += action;
}
public void Unsubscribe(Action action) {
onChange -= action;
}
public void Add(EntityModel entity, int atInterval) {
if (!buildOrder.Orders.ContainsKey(atInterval))
buildOrder.Orders.Add(atInterval, new List<EntityModel> { entity.Clone() });
else
buildOrder.Orders[atInterval].Add(entity.Clone());
if (atInterval > lastInterval) lastInterval = atInterval;
}
public bool Add(EntityModel entity, IEconomyService withEconomy) {
if (entity != null) {
var production = entity.Production();
if (production != null) {
for (var interval = lastInterval; interval < withEconomy.GetOverTime().Count; interval++) {
var economyAtSecond = withEconomy.GetOverTime()[interval];
if (economyAtSecond.Alloy >= production.Alloy && economyAtSecond.Ether >= production.Ether &&
economyAtSecond.Pyre >= production.Pyre) {
if (!MeetsSupply(entity)) {
Console.WriteLine("More Supply Needed");
return false;
}
if (!MeetsRequirements(entity, interval)) continue;
//Account for human Micro delay
interval += HumanMicro;
if (!buildOrder.Orders.ContainsKey(interval))
buildOrder.Orders.Add(interval, new List<EntityModel> { entity.Clone() });
else
buildOrder.Orders[interval].Add(entity.Clone());
lastInterval = interval;
NotifyDataChanged();
return true;
}
}
}
else {
Add(entity, 0);
NotifyDataChanged();
return true;
}
}
return false;
}
public void RemoveLast() {
EntityModel entityRemoved = null;
if (buildOrder.Orders.Keys.Count > 1) {
var last = buildOrder.Orders.Keys.Last();
if (buildOrder.Orders[last].Count > 0) {
entityRemoved = buildOrder.Orders[last].Last();
buildOrder.Orders[last].Remove(buildOrder.Orders[last].Last());
}
if (buildOrder.Orders[last].Count == 0) buildOrder.Orders.Remove(last);
if (buildOrder.Orders.Keys.Count > 0)
lastInterval = buildOrder.Orders.Keys.Last() + 1;
else
lastInterval = 1;
if (entityRemoved?.Info()?.Descriptive == DescriptiveType.Worker) {
RemoveLast();
return;
}
NotifyDataChanged();
}
}
public string AsJson() {
var options = new JsonSerializerOptions {
WriteIndented = true
};
options.Converters.Add(new JsonStringEnumConverter());
return JsonSerializer.Serialize(buildOrder, options);
}
public string BuildOrderAsYaml() {
var stringBuilder = new StringBuilder();
var serializer = new Serializer();
stringBuilder.AppendLine(serializer.Serialize(buildOrder));
var buildOrderText = stringBuilder.ToString();
return buildOrderText;
}
public List<EntityModel> GetOrdersAt(int interval) {
return (from ordersAtTime in buildOrder.Orders
from orders in ordersAtTime.Value
where ordersAtTime.Key == interval
select orders).ToList();
}
public List<EntityModel> GetCompletedAt(int interval) {
return (from ordersAtTime in buildOrder.Orders
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) {
return (from ordersAtTime in buildOrder.Orders
from orders in ordersAtTime.Value
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval
select orders).ToList();
}
public List<EntityModel> GetHarvestersCompletedBefore(int interval) {
return (from ordersAtTime in buildOrder.Orders
from orders in ordersAtTime.Value
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval
where orders.Harvest() != null
select orders).ToList();
}
public bool MeetsRequirements(EntityModel entity, int requestedInterval) {
var requirements = entity.Requirements();
if (requirements.Count == 0) return true;
foreach (var requirement in requirements)
if (requirement.Requirement == RequirementType.Morph) {
var entitiesNeeded = from entitiesAtInterval in buildOrder.Orders
from requiredEntity in entitiesAtInterval.Value
where requestedInterval > entitiesAtInterval.Key +
(requiredEntity.Production() == null ? 0 : requiredEntity.Production().BuildTime)
where requiredEntity.DataType == requirement.DataType
select requiredEntity;
var entitiesAlreadyMorphed = from entitiesAtInterval in buildOrder.Orders
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.Orders
from requiredEntity in entitiesAtInterval.Value
where requestedInterval > entitiesAtInterval.Key +
(requiredEntity.Production() == null ? 0 : requiredEntity.Production().BuildTime)
where requiredEntity.DataType == requirement.DataType
select requiredEntity;
if (entitiesNeeded.Count() == 0) return false;
if (entitiesNeeded.Any() == false)
return false;
}
return true;
}
public void SetName(string Name) {
buildOrder.Name = Name;
NotifyDataChanged();
}
public string GetName() {
return buildOrder.Name;
}
public void SetNotes(string Notes) {
buildOrder.Notes = Notes;
NotifyDataChanged();
}
public string GetNotes() {
return buildOrder.Notes;
}
public void SetColor(string Color) {
buildOrder.Color = Color;
NotifyDataChanged();
}
public string GetColor() {
return buildOrder.Color;
}
private event Action onChange;
private void NotifyDataChanged() {
onChange?.Invoke();
}
public Action OnChange() {
return onChange;
}
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.Orders
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.Orders
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;
}
}
+149
View File
@@ -0,0 +1,149 @@
using Model.Immortal.Economy;
using Model.Immortal.Entity;
using Model.Immortal.Types;
namespace Services.Immortal;
public class EconomyService : IEconomyService {
private List<EconomyModel> _overTime;
public List<EconomyModel> GetOverTime() {
return _overTime;
}
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public void Calculate(IBuildOrderService buildOrder, ITimingService timing, int fromInterval) {
if (_overTime == null) {
_overTime = new List<EconomyModel>();
for (var interval = 0; interval < timing.GetTiming(); interval++)
_overTime.Add(new EconomyModel { Interval = interval });
}
if (_overTime.Count > timing.GetTiming())
_overTime.RemoveRange(timing.GetTiming(), _overTime.Count - timing.GetTiming());
while (_overTime.Count < timing.GetTiming()) _overTime.Add(new EconomyModel { Interval = _overTime.Count - 1 });
for (var interval = fromInterval; interval < timing.GetTiming(); interval++) {
var economyAtSecond = _overTime[interval];
if (interval > 0) {
economyAtSecond.Alloy = _overTime[interval - 1].Alloy;
economyAtSecond.Ether = _overTime[interval - 1].Ether;
economyAtSecond.Pyre = _overTime[interval - 1].Pyre;
economyAtSecond.WorkerCount = _overTime[interval - 1].WorkerCount;
economyAtSecond.BusyWorkerCount = _overTime[interval - 1].BusyWorkerCount;
economyAtSecond.CreatingWorkerCount = _overTime[interval - 1].CreatingWorkerCount;
economyAtSecond.Harvesters = _overTime[interval - 1].Harvesters.ToList();
economyAtSecond.CreatingWorkerDelays = _overTime[interval - 1].CreatingWorkerDelays.ToList();
}
economyAtSecond.Interval = interval;
// Add funds
float freeWorkers = economyAtSecond.WorkerCount - economyAtSecond.BusyWorkerCount;
var workersNeeded = 0;
economyAtSecond.Harvesters =
(from harvester in buildOrder.GetHarvestersCompletedBefore(interval)
select harvester).ToList();
// Add funds
economyAtSecond.Pyre += 1;
// Add funds
foreach (var entity in economyAtSecond.Harvesters) {
var harvester = entity.Harvest();
if (harvester.RequiresWorker)
if (harvester.Resource == ResourceType.Alloy) {
var usedWorkers = Math.Min(harvester.Slots, freeWorkers);
economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers;
freeWorkers -= usedWorkers;
if (usedWorkers < harvester.Slots) workersNeeded += 1;
}
if (harvester.RequiresWorker == false) {
if (harvester.Resource == ResourceType.Ether)
economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots;
if (harvester.Resource == ResourceType.Alloy)
economyAtSecond.Alloy += harvester.HarvestedPerInterval * harvester.Slots;
}
}
// Create new worker
if (economyAtSecond.CreatingWorkerCount > 0)
for (var i = 0; i < economyAtSecond.CreatingWorkerDelays.Count; i++)
if (economyAtSecond.CreatingWorkerDelays[i] > 0) {
if (economyAtSecond.Alloy > 2.5f) {
economyAtSecond.Alloy -= 2.5f;
economyAtSecond.CreatingWorkerDelays[i]--;
}
}
else {
economyAtSecond.CreatingWorkerCount -= 1;
economyAtSecond.WorkerCount += 1;
economyAtSecond.CreatingWorkerDelays.Remove(i);
i--;
}
if (workersNeeded > economyAtSecond.CreatingWorkerCount) {
economyAtSecond.CreatingWorkerCount += 1;
economyAtSecond.CreatingWorkerDelays.Add(50);
}
// Remove Funds from Build Order
var ordersAtTime = buildOrder.GetOrdersAt(interval);
foreach (var order in ordersAtTime) {
var foundEntity = EntityModel.GetDictionary()[order.DataType];
var production = foundEntity.Production();
if (production != null) {
economyAtSecond.Alloy -= production.Alloy;
economyAtSecond.Ether -= production.Ether;
economyAtSecond.Pyre -= production.Pyre;
var finishedAt = interval + production.BuildTime;
if (production.RequiresWorker) economyAtSecond.BusyWorkerCount += 1;
if (production.ConsumesWorker) economyAtSecond.WorkerCount -= 1;
}
}
// Handle new entities
var completedAtInterval = buildOrder.GetCompletedAt(interval);
foreach (var newEntity in completedAtInterval) {
var harvest = newEntity;
if (harvest != null) economyAtSecond.Harvesters.Add(harvest);
var production = newEntity.Production();
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1;
}
}
NotifyDataChanged();
}
public EconomyModel GetEconomy(int atInterval) {
return _overTime[atInterval];
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
public Action OnChange() {
return _onChange;
}
}
+175
View File
@@ -0,0 +1,175 @@
using Model.Immortal.Entity.Data;
using Model.Immortal.Types;
using static Services.IEntityFilterService;
namespace Services.Immortal;
public enum EntityFilterEvent {
OnRefreshFaction,
OnRefreshImmortal,
OnRefreshEntity,
OnRefreshSearch
}
public class EntityFilterService : IEntityFilterService {
private readonly List<string> _entityChoices = new();
private readonly List<string> _factionChoices = new() { FactionType.QRath, FactionType.Aru, FactionType.Any };
private readonly List<string> _immortalChoices = new();
private string _entityType = EntityType.Army;
private string _searchText = "";
private string _selectedFaction = FactionType.QRath;
private string _selectedImmortal = ImmortalType.Orzum;
public EntityFilterService() {
RefreshImmortalChoices();
RefreshEntityChoices();
}
public void Subscribe(EntityFilterAction action) {
_onChange += action;
}
public void Unsubscribe(EntityFilterAction action) {
_onChange -= action;
}
public string GetEntityType() {
return _entityType;
}
public string GetFactionType() {
return _selectedFaction;
}
public string GetImmortalType() {
return _selectedImmortal;
}
public bool SelectFactionType(string factionType) {
if (_selectedFaction == factionType) {
_selectedFaction = FactionType.None;
_selectedImmortal = ImmortalType.None;
RefreshImmortalChoices();
RefreshEntityChoices();
NotifyDataChanged(EntityFilterEvent.OnRefreshFaction);
return true;
}
_selectedFaction = factionType;
_selectedImmortal = ImmortalType.Any;
RefreshImmortalChoices();
RefreshEntityChoices();
NotifyDataChanged(EntityFilterEvent.OnRefreshFaction);
return true;
}
public bool SelectImmortalType(string immortalType) {
if (_selectedImmortal == immortalType) {
_selectedImmortal = ImmortalType.None;
NotifyDataChanged(EntityFilterEvent.OnRefreshImmortal);
return true;
}
_selectedImmortal = immortalType;
NotifyDataChanged(EntityFilterEvent.OnRefreshImmortal);
return true;
}
public bool SelectEntityType(string entityType) {
if (_entityType == entityType) return false;
_entityType = entityType;
NotifyDataChanged(EntityFilterEvent.OnRefreshEntity);
return true;
}
public bool EnterSearchText(string searchText) {
if (_searchText.Equals(searchText))
return false;
_searchText = searchText;
NotifyDataChanged(EntityFilterEvent.OnRefreshSearch);
return true;
}
public List<string> GetFactionChoices() {
return _factionChoices;
}
public List<string> GetImmortalChoices() {
return _immortalChoices;
}
public List<string> GetEntityChoices() {
return _entityChoices;
}
public string GetSearchText() {
return _searchText;
}
private void RefreshImmortalChoices() {
_immortalChoices.Clear();
//TODO Consider getting these values from the database
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Any) {
_immortalChoices.Add(ImmortalType.Orzum);
_immortalChoices.Add(ImmortalType.Ajari);
}
if (_selectedFaction == FactionType.Aru || _selectedFaction == FactionType.Any) {
_immortalChoices.Add(ImmortalType.Mala);
_immortalChoices.Add(ImmortalType.Xol);
}
}
private void RefreshEntityChoices() {
_entityChoices.Clear();
if (_selectedFaction == FactionType.QRath || _selectedFaction == FactionType.Aru) {
_entityChoices.Add(EntityType.Army);
_entityChoices.Add(EntityType.Immortal);
_entityChoices.Add(EntityType.Passive);
_entityChoices.Add(EntityType.Building);
_entityChoices.Add(EntityType.Tech);
_entityChoices.Add(EntityType.Ability);
_entityChoices.Add(EntityType.Pyre_Spell);
_entityChoices.Add(EntityType.Building_Upgrade);
_entityChoices.Add(EntityType.Worker);
}
if (_selectedFaction == FactionType.Any) {
_entityChoices.Add(EntityType.Teapot);
_entityChoices.Add(EntityType.Command);
_entityChoices.Add(EntityType.Pyre_Event);
_entityChoices.Add(EntityType.Family);
_entityChoices.Add(EntityType.Faction);
_entityChoices.Add(EntityType.Any);
}
}
private event EntityFilterAction _onChange;
private void NotifyDataChanged(EntityFilterEvent entityFilterEvent) {
_onChange?.Invoke(entityFilterEvent);
}
public EntityFilterAction OnChange() {
return _onChange;
}
public void Subscribe(Action action) {
throw new NotImplementedException();
}
public void Unsubscribe(Action action) {
throw new NotImplementedException();
}
}
+9
View File
@@ -0,0 +1,9 @@
using Model.Immortal.Entity;
namespace Services.Immortal;
public class EntityService : IEntityService {
public List<EntityModel> GetEntities() {
throw new NotImplementedException();
}
}
@@ -0,0 +1,53 @@
using Model.Immortal.Types;
namespace Services.Immortal;
public class ImmortalSelectionService : IImmortalSelectionService {
private string _selectedFaction = FactionType.QRath;
private string _selectedImmortal = ImmortalType.Orzum;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public string GetFactionType() {
return _selectedFaction;
}
public string GetImmortalType() {
return _selectedImmortal;
}
public bool SelectFactionType(string factionType) {
if (_selectedFaction == factionType) return false;
_selectedFaction = factionType;
if (_selectedFaction == FactionType.QRath) _selectedImmortal = ImmortalType.Orzum;
if (_selectedFaction == FactionType.Aru) _selectedImmortal = ImmortalType.Mala;
NotifyDataChanged();
return true;
}
public bool SelectImmortalType(string immortalType) {
if (_selectedImmortal == immortalType) return false;
_selectedImmortal = immortalType;
NotifyDataChanged();
return true;
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
public Action OnChange() {
return _onChange;
}
}
+94
View File
@@ -0,0 +1,94 @@
using Model.Immortal.Hotkeys;
namespace Services.Immortal;
public class KeyService : IKeyService {
private static readonly List<string> _pressedKeys = new();
private string? _hotkey;
private string _hotkeyGroup = "C";
private bool _isHoldingSpace;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
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) {
_isHoldingSpace = true;
NotifyDataChanged();
}
return false;
}
if (!_pressedKeys.Contains(pressedKey)) {
if (HotkeyModel.KeyGroups.Contains(pressedKey)) _hotkeyGroup = pressedKey;
if (HotkeyModel.HotKeys.Contains(pressedKey)) _hotkey = pressedKey;
_pressedKeys.Add(pressedKey);
NotifyDataChanged();
return true;
}
return false;
}
public List<string> GetAllPressedKeys() {
return _pressedKeys;
}
public bool RemovePressedKey(string key) {
_hotkey = null;
var pressedKey = key.ToUpper();
if (pressedKey.Equals(" ") || pressedKey.Equals("SPACE")) {
if (_isHoldingSpace || true) {
_isHoldingSpace = false;
NotifyDataChanged();
}
return false;
}
if (_pressedKeys.Contains(pressedKey)) {
_pressedKeys.Remove(pressedKey);
NotifyDataChanged();
return true;
}
return false;
}
public bool IsHoldingSpace() {
return _isHoldingSpace;
}
public string GetHotkey() {
return _hotkey;
}
public string GetHotkeyGroup() {
return _hotkeyGroup;
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
public Action OnChange() {
return _onChange;
}
}
+100
View File
@@ -0,0 +1,100 @@
using Model.Immortal.Entity;
using Model.Immortal.Entity.Data;
using Model.Immortal.MemoryTester;
using static Services.IMemoryTesterService;
namespace Services.Immortal;
public enum MemoryTesterEvent {
OnVerify,
OnRefresh
}
public class MemoryTesterService : IMemoryTesterService {
private readonly List<MemoryEntityModel> memoryEntities = MemoryEntityModel.TestData;
private readonly List<MemoryQuestionModel> memoryQuestions = MemoryQuestionModel.TestData;
private readonly Random random = new();
public void Subscribe(MemoryAction action) {
_onChange += action;
}
public void Unsubscribe(MemoryAction action) {
_onChange -= action;
}
public void GenerateQuiz() {
memoryEntities.Clear();
memoryQuestions.Clear();
//TODO redo this
var units = (from entity in EntityModel.GetListOnlyHotkey()
where entity.EntityType == EntityType.Army
where entity.Weapons().Count > 0
select entity).OrderBy(entity => random.Next()).Take(4).ToList();
var entityIndex = 0;
var questionIndex = 0;
foreach (var unit in units) {
memoryEntities.Add(new MemoryEntityModel {
Id = ++entityIndex,
Name = unit.Info().Name
});
var weaponIndex = 0;
foreach (var weapon in unit.Weapons()) {
weaponIndex++;
memoryQuestions.Add(new MemoryQuestionModel {
Id = ++questionIndex,
MemoryEntityModelId = entityIndex,
Name = $"Range (Weapon {weaponIndex})",
Answer = weapon.Range,
IsRevealed = entityIndex == 1 || entityIndex == 3
});
}
memoryQuestions.Add(new MemoryQuestionModel {
Id = ++questionIndex,
MemoryEntityModelId = entityIndex,
Name = "Speed",
Answer = (int)unit.Movement().Speed,
IsRevealed = entityIndex == 1 || entityIndex == 2
});
}
NotifyDataChanged(MemoryTesterEvent.OnRefresh);
}
public List<MemoryEntityModel> GetEntities() {
return memoryEntities;
}
public List<MemoryQuestionModel> GetQuestions() {
return memoryQuestions;
}
public void Update(MemoryQuestionModel memoryQuestion) {
memoryQuestions[memoryQuestion.Id - 1].Guess = memoryQuestion.Guess;
}
public void Verify() {
NotifyDataChanged(MemoryTesterEvent.OnVerify);
}
//public delegate void MemoryAction(MemoryTesterActions memoryAction);
private event MemoryAction _onChange;
private void NotifyDataChanged(MemoryTesterEvent memoryAction) {
_onChange?.Invoke(memoryAction);
}
public MemoryAction OnChange() {
return _onChange;
}
}
+34
View File
@@ -0,0 +1,34 @@
namespace Services.Immortal;
public class TimingService : ITimingService {
private int _timing = 360;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public int GetTiming() {
return _timing;
}
public void SetTiming(int timing) {
if (_timing != timing) {
_timing = timing;
NotifyDataChanged();
}
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
public Action OnChange() {
return _onChange;
}
}
+18
View File
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="11.2.1"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Contexts\Contexts.csproj"/>
<ProjectReference Include="..\Model\Model.csproj"/>
</ItemGroup>
</Project>
+3
View File
@@ -0,0 +1,3 @@
namespace Services.Website;
public class DialogService { }
+95
View File
@@ -0,0 +1,95 @@
using Model.Website.Enums;
namespace Services.Website;
public class NavigationService : INavigationService {
private string navigationStateType = NavigationStateType.Default;
private NavSelectionType navSelectionType = NavSelectionType.None;
private Type renderType;
private int webPageType;
private int webSectionType;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange += action;
}
public void ChangeNavigationState(string newState) {
if (newState.Equals(navigationStateType))
return;
navigationStateType = newState;
NotifyDataChanged();
}
public string GetNavigationState() {
return navigationStateType;
}
public void SelectPage(int pageType, Type page) {
if (renderType != page) {
renderType = page;
webPageType = pageType;
navSelectionType = NavSelectionType.Page;
NotifyDataChanged();
}
}
public void SelectSection(int section) {
if (section == webSectionType) return;
webSectionType = section;
navSelectionType = NavSelectionType.Section;
Console.WriteLine(webSectionType);
NotifyDataChanged();
}
public void Back() {
if (navSelectionType == NavSelectionType.Page) {
navSelectionType = NavSelectionType.Section;
webPageType = 0;
NotifyDataChanged();
return;
}
if (navSelectionType == NavSelectionType.Section) {
navSelectionType = NavSelectionType.None;
webSectionType = 0;
webPageType = 0;
NotifyDataChanged();
}
}
public NavSelectionType GetNavSelectionType() {
return navSelectionType;
}
public int GetWebPageId() {
return webPageType;
}
public int GetWebSectionId() {
return webSectionType;
}
public Type GetRenderType() {
return renderType;
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
public Action OnChange() {
return _onChange;
}
}
+58
View File
@@ -0,0 +1,58 @@
using System.Net.Http.Json;
using Contexts;
using Microsoft.EntityFrameworkCore;
using Model.Website;
namespace Services.Work;
public class WebsiteService : IWebsiteService {
private readonly HttpClient httpClient;
private bool isLoaded;
public WebsiteService(HttpClient httpClient) {
this.httpClient = httpClient;
}
private DatabaseContext Database { get; set; }
public DbSet<WebSectionModel> WebSectionModels => Database.WebSectionModels;
public DbSet<WebPageModel> WebPageModels => Database.WebPageModels;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public bool IsLoaded() {
return isLoaded;
}
public async Task Load(DatabaseContext database) {
Database = database;
if (isLoaded) return;
Database.WebPageModels.AddRange(await httpClient.GetFromJsonAsync<WebPageModel[]>("generated/WebPageModels.json"));
Database.WebSectionModels.AddRange(
await httpClient.GetFromJsonAsync<WebSectionModel[]>("generated/WebSectionModels.json"));
Database.SaveChanges();
isLoaded = true;
NotifyDataChanged();
}
public void Update() {
NotifyDataChanged();
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
}
+57
View File
@@ -0,0 +1,57 @@
using System.Net.Http.Json;
using Contexts;
using Microsoft.EntityFrameworkCore;
using Model.Work.Tasks;
namespace Services.Work;
public class AgileService : IAgileService {
private readonly HttpClient httpClient;
private bool isLoaded;
public AgileService(HttpClient httpClient) {
this.httpClient = httpClient;
}
private DatabaseContext Database { get; set; }
public DbSet<SprintModel> SprintModels => Database.SprintModels;
public DbSet<TaskModel> TaskModels => Database.TaskModels;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public bool IsLoaded() {
return isLoaded;
}
public async Task Load(DatabaseContext database) {
Database = database;
if (isLoaded) return;
Database.SprintModels.AddRange(await httpClient.GetFromJsonAsync<SprintModel[]>("generated/SprintModels.json"));
Database.TaskModels.AddRange(await httpClient.GetFromJsonAsync<TaskModel[]>("generated/TaskModels.json"));
Database.SaveChanges();
isLoaded = true;
NotifyDataChanged();
}
public void Update() {
NotifyDataChanged();
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
}
+56
View File
@@ -0,0 +1,56 @@
using System.Net.Http.Json;
using Contexts;
using Microsoft.EntityFrameworkCore;
using Model.Work.Git;
namespace Services.Work;
public class GitService : IGitService {
private readonly HttpClient httpClient;
private bool isLoaded;
public GitService(HttpClient httpClient) {
this.httpClient = httpClient;
}
public DatabaseContext Database { get; set; }
public DbSet<ChangeModel> ChangeModels => Database.ChangeModels;
public DbSet<PatchModel> PatchModels => Database.PatchModels;
public void Subscribe(Action action) {
_onChange += action;
}
public void Unsubscribe(Action action) {
_onChange -= action;
}
public bool IsLoaded() {
return isLoaded;
}
public async Task Load(DatabaseContext database) {
Database = database;
if (isLoaded) return;
Database.ChangeModels.AddRange(await httpClient.GetFromJsonAsync<ChangeModel[]>("generated/ChangeModels.json"));
Database.PatchModels.AddRange(await httpClient.GetFromJsonAsync<PatchModel[]>("generated/PatchModels.json"));
Database.SaveChanges();
isLoaded = true;
NotifyDataChanged();
}
public void Update() {
NotifyDataChanged();
}
private event Action _onChange;
private void NotifyDataChanged() {
_onChange?.Invoke();
}
}