|
|
|
@ -9,29 +9,34 @@ using YamlDotNet.Serialization; |
|
|
|
|
|
|
|
|
|
|
|
namespace Services.Immortal; |
|
|
|
namespace Services.Immortal; |
|
|
|
|
|
|
|
|
|
|
|
public class BuildOrderService : IBuildOrderService { |
|
|
|
public class BuildOrderService : IBuildOrderService |
|
|
|
private int HumanMicro = 2; |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
private readonly BuildOrderModel buildOrder = new(); |
|
|
|
private readonly BuildOrderModel buildOrder = new(); |
|
|
|
private int lastInterval = 0; |
|
|
|
private readonly int HumanMicro = 2; |
|
|
|
|
|
|
|
private int lastInterval; |
|
|
|
public int GetLastRequestInterval() { |
|
|
|
|
|
|
|
|
|
|
|
public int GetLastRequestInterval() |
|
|
|
|
|
|
|
{ |
|
|
|
return lastInterval; |
|
|
|
return lastInterval; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Dictionary<int, List<EntityModel>> GetOrders() { |
|
|
|
public Dictionary<int, List<EntityModel>> GetOrders() |
|
|
|
|
|
|
|
{ |
|
|
|
return buildOrder.Orders; |
|
|
|
return buildOrder.Orders; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Subscribe(Action action) { |
|
|
|
public void Subscribe(Action action) |
|
|
|
|
|
|
|
{ |
|
|
|
OnChange += action; |
|
|
|
OnChange += action; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Unsubscribe(Action action) { |
|
|
|
public void Unsubscribe(Action action) |
|
|
|
|
|
|
|
{ |
|
|
|
OnChange -= action; |
|
|
|
OnChange -= action; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void Add(EntityModel entity, int atInterval) { |
|
|
|
public void Add(EntityModel entity, int atInterval) |
|
|
|
|
|
|
|
{ |
|
|
|
if (!buildOrder.Orders.ContainsKey(atInterval)) |
|
|
|
if (!buildOrder.Orders.ContainsKey(atInterval)) |
|
|
|
buildOrder.Orders.Add(atInterval, new List<EntityModel> { entity.Clone() }); |
|
|
|
buildOrder.Orders.Add(atInterval, new List<EntityModel> { entity.Clone() }); |
|
|
|
else |
|
|
|
else |
|
|
|
@ -40,64 +45,76 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
if (atInterval > lastInterval) lastInterval = atInterval; |
|
|
|
if (atInterval > lastInterval) lastInterval = atInterval; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService withToasts) { |
|
|
|
public bool Add(EntityModel entity, IEconomyService withEconomy, IToastService withToasts) |
|
|
|
if (entity != null) { |
|
|
|
{ |
|
|
|
var production = entity.Production(); |
|
|
|
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)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
withToasts.AddToast(new ToastModel |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Title = "Supply Cap Reached", Message = "Build more supply!", |
|
|
|
|
|
|
|
SeverityType = SeverityType.Error |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (production != null) { |
|
|
|
if (!MeetsRequirements(entity, interval)) continue; |
|
|
|
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)) { |
|
|
|
|
|
|
|
withToasts.AddToast(new ToastModel {Title = "Supply Cap Reached", Message = "Build more supply!", SeverityType = SeverityType.Error}); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!MeetsRequirements(entity, interval)) continue; |
|
|
|
//Account for human Micro delay |
|
|
|
|
|
|
|
interval += HumanMicro; |
|
|
|
|
|
|
|
|
|
|
|
//Account for human Micro delay |
|
|
|
if (!buildOrder.Orders.ContainsKey(interval)) |
|
|
|
interval += HumanMicro; |
|
|
|
buildOrder.Orders.Add(interval, new List<EntityModel> { entity.Clone() }); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
buildOrder.Orders[interval].Add(entity.Clone()); |
|
|
|
|
|
|
|
|
|
|
|
if (!buildOrder.Orders.ContainsKey(interval)) |
|
|
|
lastInterval = interval; |
|
|
|
buildOrder.Orders.Add(interval, new List<EntityModel> { entity.Clone() }); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
buildOrder.Orders[interval].Add(entity.Clone()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lastInterval = interval; |
|
|
|
NotifyDataChanged(); |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
NotifyDataChanged(); |
|
|
|
if (interval + 1 == withEconomy.GetOverTime().Count) |
|
|
|
return true; |
|
|
|
{ |
|
|
|
} |
|
|
|
if (economyAtSecond.Ether < production.Ether) |
|
|
|
else if(interval + 1 == withEconomy.GetOverTime().Count) |
|
|
|
withToasts.AddToast(new ToastModel |
|
|
|
{ |
|
|
|
|
|
|
|
if (economyAtSecond.Ether < production.Ether) |
|
|
|
|
|
|
|
{ |
|
|
|
{ |
|
|
|
withToasts.AddToast(new ToastModel {Title = "Not Enough Ether", Message = "Build more ether extractors!", SeverityType = SeverityType.Error}); |
|
|
|
Title = "Not Enough Ether", Message = "Build more ether extractors!", |
|
|
|
|
|
|
|
SeverityType = SeverityType.Error |
|
|
|
} |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
} |
|
|
|
Add(entity, 0); |
|
|
|
else |
|
|
|
NotifyDataChanged(); |
|
|
|
{ |
|
|
|
return true; |
|
|
|
Add(entity, 0); |
|
|
|
} |
|
|
|
NotifyDataChanged(); |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void RemoveLast() { |
|
|
|
public void RemoveLast() |
|
|
|
|
|
|
|
{ |
|
|
|
EntityModel entityRemoved = null!; |
|
|
|
EntityModel entityRemoved = null!; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (buildOrder.Orders.Keys.Count > 1) { |
|
|
|
if (buildOrder.Orders.Keys.Count > 1) |
|
|
|
|
|
|
|
{ |
|
|
|
var last = buildOrder.Orders.Keys.Last(); |
|
|
|
var last = buildOrder.Orders.Keys.Last(); |
|
|
|
|
|
|
|
|
|
|
|
if (buildOrder.Orders[last].Count > 0) { |
|
|
|
if (buildOrder.Orders[last].Count > 0) |
|
|
|
|
|
|
|
{ |
|
|
|
entityRemoved = buildOrder.Orders[last].Last(); |
|
|
|
entityRemoved = buildOrder.Orders[last].Last(); |
|
|
|
buildOrder.Orders[last].Remove(buildOrder.Orders[last].Last()); |
|
|
|
buildOrder.Orders[last].Remove(buildOrder.Orders[last].Last()); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -109,7 +126,8 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
else |
|
|
|
else |
|
|
|
lastInterval = 1; |
|
|
|
lastInterval = 1; |
|
|
|
|
|
|
|
|
|
|
|
if (entityRemoved?.Info()?.Descriptive == DescriptiveType.Worker) { |
|
|
|
if (entityRemoved?.Info()?.Descriptive == DescriptiveType.Worker) |
|
|
|
|
|
|
|
{ |
|
|
|
RemoveLast(); |
|
|
|
RemoveLast(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -119,15 +137,18 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public string AsJson() { |
|
|
|
public string AsJson() |
|
|
|
var options = new JsonSerializerOptions { |
|
|
|
{ |
|
|
|
|
|
|
|
var options = new JsonSerializerOptions |
|
|
|
|
|
|
|
{ |
|
|
|
WriteIndented = true |
|
|
|
WriteIndented = true |
|
|
|
}; |
|
|
|
}; |
|
|
|
options.Converters.Add(new JsonStringEnumConverter()); |
|
|
|
options.Converters.Add(new JsonStringEnumConverter()); |
|
|
|
return JsonSerializer.Serialize(buildOrder, options); |
|
|
|
return JsonSerializer.Serialize(buildOrder, options); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string BuildOrderAsYaml() { |
|
|
|
public string BuildOrderAsYaml() |
|
|
|
|
|
|
|
{ |
|
|
|
var stringBuilder = new StringBuilder(); |
|
|
|
var stringBuilder = new StringBuilder(); |
|
|
|
var serializer = new Serializer(); |
|
|
|
var serializer = new Serializer(); |
|
|
|
stringBuilder.AppendLine(serializer.Serialize(buildOrder)); |
|
|
|
stringBuilder.AppendLine(serializer.Serialize(buildOrder)); |
|
|
|
@ -135,28 +156,32 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
return buildOrderText; |
|
|
|
return buildOrderText; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<EntityModel> GetOrdersAt(int interval) { |
|
|
|
public List<EntityModel> GetOrdersAt(int interval) |
|
|
|
|
|
|
|
{ |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
where ordersAtTime.Key == interval |
|
|
|
where ordersAtTime.Key == interval |
|
|
|
select orders).ToList(); |
|
|
|
select orders).ToList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<EntityModel> GetCompletedAt(int interval) { |
|
|
|
public List<EntityModel> GetCompletedAt(int interval) |
|
|
|
|
|
|
|
{ |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) == interval |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) == interval |
|
|
|
select orders).ToList(); |
|
|
|
select orders).ToList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<EntityModel> GetCompletedBefore(int interval) { |
|
|
|
public List<EntityModel> GetCompletedBefore(int interval) |
|
|
|
|
|
|
|
{ |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval |
|
|
|
select orders).ToList(); |
|
|
|
select orders).ToList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public List<EntityModel> GetHarvestersCompletedBefore(int interval) { |
|
|
|
public List<EntityModel> GetHarvestersCompletedBefore(int interval) |
|
|
|
|
|
|
|
{ |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
return (from ordersAtTime in buildOrder.Orders |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
from orders in ordersAtTime.Value |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval |
|
|
|
where ordersAtTime.Key + (orders.Production() == null ? 0 : orders.Production().BuildTime) <= interval |
|
|
|
@ -164,12 +189,14 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
select orders).ToList(); |
|
|
|
select orders).ToList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool MeetsRequirements(EntityModel entity, int requestedInterval) { |
|
|
|
public bool MeetsRequirements(EntityModel entity, int requestedInterval) |
|
|
|
|
|
|
|
{ |
|
|
|
var requirements = entity.Requirements(); |
|
|
|
var requirements = entity.Requirements(); |
|
|
|
if (requirements.Count == 0) return true; |
|
|
|
if (requirements.Count == 0) return true; |
|
|
|
|
|
|
|
|
|
|
|
foreach (var requirement in requirements) |
|
|
|
foreach (var requirement in requirements) |
|
|
|
if (requirement.Requirement == RequirementType.Morph) { |
|
|
|
if (requirement.Requirement == RequirementType.Morph) |
|
|
|
|
|
|
|
{ |
|
|
|
var entitiesNeeded = from entitiesAtInterval in buildOrder.Orders |
|
|
|
var entitiesNeeded = from entitiesAtInterval in buildOrder.Orders |
|
|
|
from requiredEntity in entitiesAtInterval.Value |
|
|
|
from requiredEntity in entitiesAtInterval.Value |
|
|
|
where requestedInterval > entitiesAtInterval.Key + |
|
|
|
where requestedInterval > entitiesAtInterval.Key + |
|
|
|
@ -185,7 +212,8 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
if (entitiesAlreadyMorphed.Count() >= entitiesNeeded.Count()) |
|
|
|
if (entitiesAlreadyMorphed.Count() >= entitiesNeeded.Count()) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
var entitiesNeeded = from entitiesAtInterval in buildOrder.Orders |
|
|
|
var entitiesNeeded = from entitiesAtInterval in buildOrder.Orders |
|
|
|
from requiredEntity in entitiesAtInterval.Value |
|
|
|
from requiredEntity in entitiesAtInterval.Value |
|
|
|
where requestedInterval > entitiesAtInterval.Key + |
|
|
|
where requestedInterval > entitiesAtInterval.Key + |
|
|
|
@ -204,40 +232,48 @@ public class BuildOrderService : IBuildOrderService { |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void SetName(string Name) { |
|
|
|
public void SetName(string Name) |
|
|
|
|
|
|
|
{ |
|
|
|
buildOrder.Name = Name; |
|
|
|
buildOrder.Name = Name; |
|
|
|
NotifyDataChanged(); |
|
|
|
NotifyDataChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string GetName() { |
|
|
|
public string GetName() |
|
|
|
|
|
|
|
{ |
|
|
|
return buildOrder.Name; |
|
|
|
return buildOrder.Name; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void SetNotes(string Notes) { |
|
|
|
public void SetNotes(string Notes) |
|
|
|
|
|
|
|
{ |
|
|
|
buildOrder.Notes = Notes; |
|
|
|
buildOrder.Notes = Notes; |
|
|
|
NotifyDataChanged(); |
|
|
|
NotifyDataChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string GetNotes() { |
|
|
|
public string GetNotes() |
|
|
|
|
|
|
|
{ |
|
|
|
return buildOrder.Notes; |
|
|
|
return buildOrder.Notes; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void SetColor(string color) { |
|
|
|
public void SetColor(string color) |
|
|
|
|
|
|
|
{ |
|
|
|
buildOrder.Color = color; |
|
|
|
buildOrder.Color = color; |
|
|
|
NotifyDataChanged(); |
|
|
|
NotifyDataChanged(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public string GetColor() { |
|
|
|
public string GetColor() |
|
|
|
|
|
|
|
{ |
|
|
|
return buildOrder.Color; |
|
|
|
return buildOrder.Color; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private event Action OnChange = null!; |
|
|
|
private event Action OnChange = null!; |
|
|
|
|
|
|
|
|
|
|
|
private void NotifyDataChanged() { |
|
|
|
private void NotifyDataChanged() |
|
|
|
|
|
|
|
{ |
|
|
|
OnChange?.Invoke(); |
|
|
|
OnChange?.Invoke(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public bool MeetsSupply(EntityModel entity) { |
|
|
|
public bool MeetsSupply(EntityModel entity) |
|
|
|
|
|
|
|
{ |
|
|
|
var supply = entity.Supply(); |
|
|
|
var supply = entity.Supply(); |
|
|
|
if (supply == null || supply.Takes == 0) return true; |
|
|
|
if (supply == null || supply.Takes == 0) return true; |
|
|
|
|
|
|
|
|
|
|
|
|