|
|
|
|
@ -1,14 +1,13 @@
|
|
|
|
|
using Model.Economy; |
|
|
|
|
using Model.Entity; |
|
|
|
|
using Model.Entity.Parts; |
|
|
|
|
using Model.Types; |
|
|
|
|
|
|
|
|
|
namespace Services.Immortal; |
|
|
|
|
|
|
|
|
|
public class EconomyService : IEconomyService |
|
|
|
|
{ |
|
|
|
|
private List<EconomyModel> buildEconomyOverTime = null!; |
|
|
|
|
|
|
|
|
|
private Dictionary<string, List<EconomyModel>> specficEconomiesOverTime = null!; |
|
|
|
|
private List<EconomyModel>? buildEconomyOverTime; |
|
|
|
|
|
|
|
|
|
public List<EconomyModel> GetOverTime() |
|
|
|
|
{ |
|
|
|
|
@ -30,15 +29,13 @@ public class EconomyService : IEconomyService
|
|
|
|
|
// We don't consider things mining at zero seconds |
|
|
|
|
if (fromInterval == 0) fromInterval = 1; |
|
|
|
|
|
|
|
|
|
//TODO Break all this up |
|
|
|
|
if (buildEconomyOverTime == null) |
|
|
|
|
{ |
|
|
|
|
buildEconomyOverTime = new List<EconomyModel>(); |
|
|
|
|
buildEconomyOverTime = []; |
|
|
|
|
for (var interval = 0; interval < timing.GetAttackTime(); interval++) |
|
|
|
|
buildEconomyOverTime.Add(new EconomyModel { Interval = interval }); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (buildEconomyOverTime.Count > timing.GetAttackTime()) |
|
|
|
|
buildEconomyOverTime.RemoveRange(timing.GetAttackTime(), |
|
|
|
|
buildEconomyOverTime.Count - timing.GetAttackTime()); |
|
|
|
|
@ -54,7 +51,7 @@ public class EconomyService : IEconomyService
|
|
|
|
|
|
|
|
|
|
CarryOverEconomyFromPreviousInterval(interval, economyAtSecond); |
|
|
|
|
|
|
|
|
|
SetupCurrentInverval(buildOrder, economyAtSecond, interval); |
|
|
|
|
SetupCurrentInterval(buildOrder, economyAtSecond, interval); |
|
|
|
|
AddPassivePyreGain(interval, economyAtSecond); |
|
|
|
|
float freeWorkers = economyAtSecond.WorkerCount - economyAtSecond.BusyWorkerCount; |
|
|
|
|
var workersNeeded = AddFundsFromHarvestPoints(economyAtSecond, freeWorkers); |
|
|
|
|
@ -70,12 +67,12 @@ public class EconomyService : IEconomyService
|
|
|
|
|
|
|
|
|
|
public EconomyModel GetEconomy(int atInterval) |
|
|
|
|
{ |
|
|
|
|
if (atInterval >= buildEconomyOverTime.Count) return buildEconomyOverTime.Last(); |
|
|
|
|
|
|
|
|
|
return buildEconomyOverTime[atInterval]; |
|
|
|
|
return atInterval >= buildEconomyOverTime.Count |
|
|
|
|
? buildEconomyOverTime.Last() |
|
|
|
|
: buildEconomyOverTime[atInterval]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void SetupCurrentInverval(IBuildOrderService buildOrder, EconomyModel economyAtSecond, int interval) |
|
|
|
|
private static void SetupCurrentInterval(IBuildOrderService buildOrder, EconomyModel economyAtSecond, int interval) |
|
|
|
|
{ |
|
|
|
|
economyAtSecond.Interval = interval; |
|
|
|
|
economyAtSecond.HarvestPoints = |
|
|
|
|
@ -86,66 +83,61 @@ public class EconomyService : IEconomyService
|
|
|
|
|
private static void HandledAddingNewHarvestPointsAndWorkersToEconomy(IBuildOrderService buildOrder, int interval, |
|
|
|
|
EconomyModel economyAtSecond) |
|
|
|
|
{ |
|
|
|
|
if (buildOrder.CompletedOrders.TryGetValue(interval, out var completedAtInterval)) |
|
|
|
|
if (!buildOrder.CompletedOrders.TryGetValue(interval, out var completedAtInterval)) return; |
|
|
|
|
|
|
|
|
|
foreach (var newEntity in completedAtInterval) |
|
|
|
|
{ |
|
|
|
|
var harvest = newEntity; |
|
|
|
|
if (harvest != null) economyAtSecond.HarvestPoints.Add(harvest); |
|
|
|
|
economyAtSecond.HarvestPoints.Add(newEntity); |
|
|
|
|
|
|
|
|
|
var production = newEntity.Production(); |
|
|
|
|
if (production != null && production.RequiresWorker) economyAtSecond.BusyWorkerCount -= 1; |
|
|
|
|
if (production is { RequiresWorker: true }) economyAtSecond.BusyWorkerCount -= 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void SubtractFundsOnRequestedOrders(IBuildOrderService buildOrder, int interval, |
|
|
|
|
EconomyModel economyAtSecond) |
|
|
|
|
{ |
|
|
|
|
if (buildOrder.StartedOrders.TryGetValue(interval, out var ordersAtTime)) |
|
|
|
|
foreach (var order in ordersAtTime) |
|
|
|
|
{ |
|
|
|
|
var foundEntity = EntityModel.GetDictionary()[order.DataType]; |
|
|
|
|
var production = foundEntity.Production(); |
|
|
|
|
if (!buildOrder.StartedOrders.TryGetValue(interval, out var ordersAtTime)) return; |
|
|
|
|
|
|
|
|
|
if (production != null) |
|
|
|
|
foreach (var production in |
|
|
|
|
ordersAtTime.Select(order => EntityModel.GetDictionary()[order.DataType]) |
|
|
|
|
.Select(foundEntity => foundEntity.Production()) |
|
|
|
|
.OfType<EntityProductionModel>()) |
|
|
|
|
{ |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static void MakeNeededNewWorkersRequests(int workersNeeded, EconomyModel economyAtSecond) |
|
|
|
|
{ |
|
|
|
|
if (workersNeeded > economyAtSecond.CreatingWorkerCount) |
|
|
|
|
{ |
|
|
|
|
if (workersNeeded <= economyAtSecond.CreatingWorkerCount) return; |
|
|
|
|
|
|
|
|
|
economyAtSecond.CreatingWorkerCount += 1; |
|
|
|
|
economyAtSecond.CreatingWorkerDelays.Add(20); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns amount of workers created |
|
|
|
|
* Returns number of workers created |
|
|
|
|
*/ |
|
|
|
|
private static int CalculateCreatingWorkerCosts(EconomyModel economyAtSecond) |
|
|
|
|
{ |
|
|
|
|
var createdWorkers = 0; |
|
|
|
|
|
|
|
|
|
if (economyAtSecond.CreatingWorkerCount > 0) |
|
|
|
|
if (economyAtSecond.CreatingWorkerCount <= 0) return createdWorkers; |
|
|
|
|
|
|
|
|
|
for (var i = 0; i < economyAtSecond.CreatingWorkerDelays.Count; i++) |
|
|
|
|
if (economyAtSecond.CreatingWorkerDelays[i] > 0) |
|
|
|
|
{ |
|
|
|
|
if (economyAtSecond.Alloy > 2.5f) |
|
|
|
|
{ |
|
|
|
|
if (!(economyAtSecond.Alloy > 2.5f)) continue; |
|
|
|
|
|
|
|
|
|
economyAtSecond.Alloy -= 2.5f; |
|
|
|
|
economyAtSecond.CreatingWorkerDelays[i]--; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
economyAtSecond.CreatingWorkerCount -= 1; |
|
|
|
|
@ -165,33 +157,43 @@ public class EconomyService : IEconomyService
|
|
|
|
|
{ |
|
|
|
|
var workersNeeded = 0; |
|
|
|
|
|
|
|
|
|
foreach (var entity in economyAtSecond.HarvestPoints) |
|
|
|
|
foreach (var harvesterPoint in |
|
|
|
|
economyAtSecond.HarvestPoints.Select(entity => entity.Harvest())) |
|
|
|
|
{ |
|
|
|
|
var harvester = entity.Harvest(); |
|
|
|
|
if (harvester.RequiresWorker) |
|
|
|
|
if (harvester.Resource == ResourceType.Alloy) |
|
|
|
|
switch (harvesterPoint.RequiresWorker) |
|
|
|
|
{ |
|
|
|
|
var usedWorkers = Math.Min(harvester.Slots, freeWorkers); |
|
|
|
|
economyAtSecond.Alloy += harvester.HarvestedPerInterval * usedWorkers; |
|
|
|
|
economyAtSecond.AlloyIncome += harvester.HarvestedPerInterval * usedWorkers; |
|
|
|
|
case true: |
|
|
|
|
{ |
|
|
|
|
if (harvesterPoint.Resource == ResourceType.Alloy) |
|
|
|
|
{ |
|
|
|
|
var usedWorkers = Math.Min(harvesterPoint.Slots, freeWorkers); |
|
|
|
|
economyAtSecond.Alloy += harvesterPoint.HarvestedPerInterval * usedWorkers; |
|
|
|
|
economyAtSecond.AlloyIncome += harvesterPoint.HarvestedPerInterval * usedWorkers; |
|
|
|
|
|
|
|
|
|
freeWorkers -= usedWorkers; |
|
|
|
|
|
|
|
|
|
if (usedWorkers < harvester.Slots) workersNeeded += 1; |
|
|
|
|
if (usedWorkers < harvesterPoint.Slots) workersNeeded += 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (harvester.RequiresWorker == false) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
case false: |
|
|
|
|
{ |
|
|
|
|
if (harvester.Resource == ResourceType.Ether) |
|
|
|
|
switch (harvesterPoint.Resource) |
|
|
|
|
{ |
|
|
|
|
economyAtSecond.Ether += harvester.HarvestedPerInterval * harvester.Slots; |
|
|
|
|
economyAtSecond.EtherIncome += harvester.HarvestedPerInterval * harvester.Slots; |
|
|
|
|
case ResourceType.Ether: |
|
|
|
|
economyAtSecond.Ether += harvesterPoint.HarvestedPerInterval * harvesterPoint.Slots; |
|
|
|
|
economyAtSecond.EtherIncome += harvesterPoint.HarvestedPerInterval * harvesterPoint.Slots; |
|
|
|
|
break; |
|
|
|
|
case ResourceType.Alloy: |
|
|
|
|
economyAtSecond.Alloy += harvesterPoint.HarvestedPerInterval * harvesterPoint.Slots; |
|
|
|
|
economyAtSecond.AlloyIncome += harvesterPoint.HarvestedPerInterval * harvesterPoint.Slots; |
|
|
|
|
break; |
|
|
|
|
case ResourceType.Pyre: |
|
|
|
|
break; // Pyre Miner? |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (harvester.Resource == ResourceType.Alloy) |
|
|
|
|
{ |
|
|
|
|
economyAtSecond.Alloy += harvester.HarvestedPerInterval * harvester.Slots; |
|
|
|
|
economyAtSecond.AlloyIncome += harvester.HarvestedPerInterval * harvester.Slots; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|