forked from mspielberg/dv-remote-dispatch
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathJobData.cs
132 lines (121 loc) · 5.42 KB
/
JobData.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
using DV.Logic.Job;
using HarmonyLib;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
namespace DvMod.RemoteDispatch
{
public static class JobData
{
private static readonly Dictionary<TrainCar, string> jobIdForCar = InitializeJobIdForCar();
private static Dictionary<string, Job> jobForId = new Dictionary<string, Job>();
private const JobLicenses LicensesToExport =
JobLicenses.Hazmat1 | JobLicenses.Hazmat2 | JobLicenses.Hazmat3 |
JobLicenses.Military1 | JobLicenses.Military2 | JobLicenses.Military3 |
JobLicenses.TrainLength1 | JobLicenses.TrainLength2;
public static string? JobIdForCar(TrainCar car)
{
jobIdForCar.TryGetValue(car, out var jobId);
return jobId;
}
public static Job? JobForCar(TrainCar car)
{
var jobId = JobIdForCar(car);
if (jobId == null)
return null;
return JobForId(jobId);
}
private static Dictionary<TrainCar, string> InitializeJobIdForCar()
{
return JobChainController.jobToJobCars
.SelectMany(kvp => kvp.Value.Select(car => (car, job: kvp.Key)))
.ToDictionary(p => p.car, p => p.job.ID);
}
public static Job? JobForId(string jobId)
{
if (jobForId.TryGetValue(jobId, out var job))
return job;
jobForId = JobChainController.jobToJobCars.Keys.ToDictionary(job => job.ID);
jobForId.TryGetValue(jobId, out job);
return job;
}
public static Dictionary<string, JObject> GetAllJobData()
{
static IEnumerable<TaskData> FlattenToTransport(TaskData data)
{
if (data.type == TaskType.Transport)
{
yield return data;
}
else if (data.nestedTasks != null)
{
foreach (var nested in data.nestedTasks)
{
foreach (var task in FlattenToTransport(nested.GetTaskData()))
yield return task;
}
}
}
static IEnumerable<TaskData> FlattenMany(IEnumerable<TaskData> data) => data.SelectMany(FlattenToTransport);
static JObject TaskToJson(TaskData data) => new JObject(
new JProperty("startTrack", data.startTrack?.ID?.FullDisplayID),
new JProperty("destinationTrack", data.destinationTrack?.ID?.FullDisplayID),
new JProperty("cars", (data.cars ?? new List<Car>()).Select(car => car.ID))
);
static JArray RequiredLicenses(Job job) => JArray.FromObject(
Enum.GetValues(typeof(JobLicenses))
.OfType<JobLicenses>()
.Where(v => (job.requiredLicenses & LicensesToExport & v) != JobLicenses.Basic)
.Select(v => Enum.GetName(typeof(JobLicenses), v))
);
static float TotalLength(TaskData task) => task.cars.Sum(car => car.length);
static float TotalMass(TaskData task) => task.cars.Sum(car => car.carOnlyMass)
+ ((task.cargoTypePerCar == null)
? 0f
: task.cars.Zip(task.cargoTypePerCar, (car, cargoType) => car.capacity * CargoTypes.GetCargoUnitMass(cargoType)).Sum());
static JObject JobToJson(Job job)
{
var flattenedTasks = FlattenMany(job.tasks.Select(task => task.GetTaskData())).ToArray();
var mainTask = job.jobType == JobType.ShuntingLoad ? flattenedTasks.Last() : flattenedTasks.First();
var length = TotalLength(mainTask);
return new JObject(
new JProperty("originYardId", job.chainData.chainOriginYardId),
new JProperty("destinationYardId", job.chainData.chainDestinationYardId),
new JProperty("tasks", flattenedTasks.Select(TaskToJson)),
new JProperty("requiredLicenses", RequiredLicenses(job)),
new JProperty("length", TotalLength(mainTask)),
new JProperty("mass", TotalMass(mainTask) / 1000),
new JProperty("basePayment", job.GetBasePaymentForTheJob()));
}
// ensure cache is updated
JobForId("");
return jobForId.ToDictionary(
kvp => kvp.Key,
kvp => JobToJson(kvp.Value));
}
public static string GetAllJobDataJson()
{
return JsonConvert.SerializeObject(GetAllJobData());
}
public static class JobPatches
{
[HarmonyPatch(typeof(JobChainController), nameof(JobChainController.UpdateTrainCarPlatesOfCarsOnJob))]
public static class UpdateTrainCarPlatesOfCarsOnJobPatch
{
public static void Postfix(JobChainController __instance, string jobId)
{
foreach (TrainCar car in __instance.trainCarsForJobChain)
{
if (jobId.Length == 0)
jobIdForCar.Remove(car);
else
jobIdForCar[car] = jobId;
Sessions.AddTag("jobs");
}
}
}
}
}
}