EDBGS/EDPlayerJournal/Mission.cs

476 lines
14 KiB
C#
Raw Normal View History

using Newtonsoft.Json.Linq;
using EDPlayerJournal.Entries;
using System.Runtime.CompilerServices;
namespace EDPlayerJournal;
public class FactionEffect {
public string? Effect { get; set; }
public string? EffectLocalised { get; set; }
public string? Trend { get; set; }
public static FactionEffect FromJSON(JObject obj) {
FactionEffect effect = new FactionEffect();
effect.Effect = obj.Value<string?>("Effect");
effect.EffectLocalised = obj.Value<string?>("Effect_Localised");
effect.Trend = obj.Value<string?>("Trend");
return effect;
}
}
public class MissionInfluence {
/// <summary>
/// System Address this influence happened in.
/// </summary>
public ulong? SystemAddress { get; set; }
/// <summary>
/// Generic description of the trend (up or down)
/// </summary>
public string? Trend { get; set; }
/// <summary>
/// Influence gained in plusses
/// </summary>
public string Influence { get; set; } = string.Empty;
public long InfluenceAmount {
get {
string trend = TrendAdjustedInfluence;
return (long)
(trend.Count(x => x == '-') * -1) +
trend.Count(x => x == '+')
;
}
}
/// <summary>
/// Returns how much influence was made, represented in pluses for positive influence,
/// and minuses with negative influence. This takes Trend (up, bad etc.) into account.
/// </summary>
public string TrendAdjustedInfluence {
get {
if (!string.IsNullOrEmpty(Trend) &&
Trend.Contains("bad", StringComparison.OrdinalIgnoreCase)) {
return new string('-', Influence.Length);
} else {
return new string('+', Influence.Length);
}
}
}
public static MissionInfluence FromJSON(JObject obj) {
MissionInfluence missionInfluence = new MissionInfluence();
missionInfluence.SystemAddress = obj.Value<ulong?>("SystemAddress");
missionInfluence.Trend = obj.Value<string?>("Trend");
missionInfluence.Influence = obj.Value<string?>("Influence") ?? "";
return missionInfluence;
}
}
public class MissionFactionEffects {
/// <summary>
/// Faction in question
/// </summary>
public string? Faction { get; set; }
/// <summary>
/// Reputation trend
/// </summary>
public string? ReputationTrend { get; set; }
/// <summary>
/// Reputation in pluses.
/// </summary>
public string Reputation { get; set; } = string.Empty;
/// <summary>
/// List of economic and security affects.
/// </summary>
public List<FactionEffect> Effects { get; set; } = new List<FactionEffect>();
/// <summary>
/// Influence gained.
/// </summary>
public List<MissionInfluence> Influences { get; set; } = new List<MissionInfluence>();
/// <summary>
/// Whether this affect is for an empty, or non-existant faction.
/// </summary>
public bool IsEmptyFaction {
get { return string.IsNullOrEmpty(Faction); }
}
public static MissionFactionEffects FromJSON(JObject j) {
MissionFactionEffects o = new MissionFactionEffects();
o.Faction = j.Value<string>("Faction");
o.ReputationTrend = j.Value<string?>("ReputationTrend");
o.Reputation = j.Value<string?>("Reputation") ?? string.Empty;
JArray? effects = j.Value<JArray?>("Effects");
if (effects != null) {
foreach (JObject effect in effects.Children().OfType<JObject>()) {
FactionEffect e = FactionEffect.FromJSON(effect);
o.Effects.Add(e);
}
}
JArray? influences = j.Value<JArray?>("Influence");
if (influences != null) {
foreach (JObject influence in influences.Children().OfType<JObject>()) {
MissionInfluence missionInfluence = MissionInfluence.FromJSON(influence);
o.Influences.Add(missionInfluence);
}
}
return o;
}
}
public class Mission : IComparable<Mission> {
2022-12-03 14:16:45 +01:00
/// <summary>
/// Passenger type for refugees
/// </summary>
public static readonly string PassengerTypeRefugee = "Refugee";
2022-12-03 14:16:45 +01:00
public ulong MissionID { get; set; } = 0;
/// <summary>
/// Name of the mission, in machine readable format.
/// </summary>
public string? Name { get; set; }
/// <summary>
/// Localised, human readable mission name.
/// </summary>
public string? LocalisedName { get; set; }
/// <summary>
/// Target of the mission. Optional.
/// </summary>
public string? Target { get; set; }
/// <summary>
/// Target of the mission as a localised human readable string.
/// </summary>
public string? TargetLocalised { get; set; }
/// <summary>
/// Target system of the mission
/// </summary>
public string? DestinationSystem { get; set; }
/// <summary>
/// Destination station.
/// </summary>
public string? DestinationStation { get; set; }
/// <summary>
/// Destination settlement
/// </summary>
public string? DestinationSettlement { get; set; }
/// <summary>
/// In case of redirection, these values denote the new system.
/// </summary>
public string? NewDestinationSystem { get; set; }
/// <summary>
/// In case of redirection, these values denote the new station.
/// </summary>
public string? NewDestinationStation { get; set; }
/// <summary>
/// Faction offering the mission.
/// </summary>
public string? Faction { get; set; }
/// <summary>
/// Target faction (for example for courier missions).
/// </summary>
public string? TargetFaction { get; set; }
/// <summary>
/// Whether the mission is a wing message.
/// </summary>
public bool Wing { get; set; } = false;
/// <summary>
/// Expiry date for the mission.
/// </summary>
public string? Expiry { get; set; }
2022-11-24 16:28:35 +01:00
/// <summary>
/// Certain missions have an expires number. No one knows what that is.
/// </summary>
public ulong? Expires { get; set; }
/// <summary>
/// Influence reward offered. This is for accepting missions only, see the
/// mission effects for actual effects once the mission is complete.
/// </summary>
public string? Influence { get; set; }
/// <summary>
/// Reputation reward offered.
/// </summary>
public string? Reputation { get; set; }
/// <summary>
/// Number of kills required for massacre missions.
/// </summary>
public ulong? KillCount { get; set; }
/// <summary>
/// Monatery reward offered for the mission. Optional, as donate missions don't give
/// a monatery reward.
/// </summary>
public ulong? Reward { get; set; }
/// <summary>
/// Amount donated for donation missions, optional. If this is null, then
/// the mission was not a donation mission.
/// </summary>
public ulong? Donation { get; set; }
/// <summary>
/// Actual amount donated.
/// </summary>
public ulong? Donated { get; set; }
/// <summary>
/// Commodity delivered, or donated. Optional, if this is null, then no
/// commodity was donated or delivered.
/// </summary>
public string? Commodity { get; set; }
/// <summary>
/// Amount of the commodity donated or delivered. Optional.
/// </summary>
public ulong? Count { get; set; }
/// <summary>
/// How many passengers are being transported.
/// </summary>
public ulong? PassengerCount { get; set; }
/// <summary>
/// If the passengers are VIPs.
/// </summary>
public bool? PassengerVIPs { get; set; }
/// <summary>
/// If the passengers are wanted.
/// </summary>
public bool? PassengerWanted { get; set; }
/// <summary>
/// What sort of passengers are being transported.
/// </summary>
public string? PassengerType { get; set; }
/// <summary>
/// Affect this mission had on factions.
/// </summary>
public List<MissionFactionEffects> FactionEffects { get; set; } = new List<MissionFactionEffects>();
2022-12-28 09:53:02 +01:00
/// <summary>
/// Returns true if the name is an on foot mission.
/// </summary>
public bool IsOnFoot {
get {
if (string.IsNullOrEmpty(Name)) {
return false;
}
return Name.Contains("OnFoot");
}
}
2022-12-03 14:16:45 +01:00
public bool IsPassengerMission {
get {
if (PassengerCount == null || PassengerCount == 0) {
return false;
}
return true;
}
}
public bool IsRescueMission {
get {
if (!IsPassengerMission) {
return false;
}
if (string.Compare(PassengerType, PassengerTypeRefugee) == 0) {
return true;
}
return false;
}
}
/// <summary>
/// Returns a friendly human-readable name for the mission. If a localised name is available
/// it will use that, baring that it will check EnglishMissionNames for a translation, and
/// if that ain't available either, it will just use the internal Name.
/// </summary>
public string FriendlyName {
get {
if (!string.IsNullOrEmpty(LocalisedName)) {
return LocalisedName;
}
if (string.IsNullOrEmpty(Name)) {
return "Unknown Mission";
}
string? translate = EnglishMissionNames.Translate(Name);
if (!string.IsNullOrEmpty(translate)) {
return translate;
}
return Name;
}
}
public int CompareTo(Mission? other) {
if (other == null) {
return 1;
}
return MissionID.CompareTo(other.MissionID);
}
private static Mission FromJSON(JObject o) {
Mission mission = new Mission();
mission.MissionID = o.Value<ulong?>("MissionID") ?? 0;
mission.Reputation = o.Value<string>("Reputation");
mission.Influence = o.Value<string>("Influence");
mission.DestinationSystem = o.Value<string>("DestinationSystem");
mission.DestinationSettlement = o.Value<string>("DestinationSettlement");
mission.DestinationStation = o.Value<string>("DestinationStation");
mission.NewDestinationSystem = o.Value<string>("NewDestinationSystem");
mission.NewDestinationStation = o.Value<string>("NewDestinationSystem");
mission.Reward = o.Value<ulong?>("Reward");
mission.Target = o.Value<string>("Target");
mission.TargetLocalised = o.Value<string>("Target_Localised");
2022-11-24 16:28:35 +01:00
mission.Expiry = o.Value<string?>("Expiry");
mission.Expires = o.Value<ulong?>("Expires");
mission.Wing = o.Value<bool?>("Wing") ?? false;
mission.Name = o.Value<string>("Name");
mission.LocalisedName = o.Value<string>("LocalisedName");
mission.Faction = o.Value<string?>("Faction");
mission.TargetFaction = o.Value<string?>("TargetFaction");
mission.Donation = o.Value<ulong?>("Donation");
mission.Donated = o.Value<ulong?>("Donated");
mission.PassengerCount = o.Value<ulong?>("PassengerCount");
mission.PassengerVIPs = o.Value<bool?>("PassengerVIPs");
mission.PassengerWanted = o.Value<bool?>("PassengerWanted");
mission.PassengerType = o.Value<string>("PassengerType");
mission.KillCount = o.Value<ulong?>("KillCount");
JArray? factionEffects = o.Value<JArray?>("FactionEffects");
if (factionEffects != null) {
foreach (JObject effect in factionEffects.Children().OfType<JObject>()) {
MissionFactionEffects factionEffect = MissionFactionEffects.FromJSON(effect);
mission.FactionEffects.Add(factionEffect);
}
}
return mission;
}
/// <summary>
/// Returns a list of all affected factions.
/// </summary>
public string[] AffectedFactions {
get {
return FactionEffects
.Where(x => !string.IsNullOrEmpty(x.Faction))
.Select(x => (x.Faction ?? string.Empty))
.ToArray()
;
}
}
/// <summary>
/// Returns the influence for a given faction in a given star system.
/// </summary>
/// <param name="faction">Faction name in question.</param>
/// <param name="systemaddr">Star System address</param>
/// <returns>null if no entry was found, or a string denoting pluses for the amount influence gained.</returns>
public MissionInfluence[]? GetInfluenceForFaction(string faction, ulong systemaddr) {
var results = FactionEffects
.Where(x => string.Compare(x.Faction, faction) == 0)
.SelectMany(x => x.Influences)
.Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr))
.Select(x => x)
.ToArray()
;
if (results == null || results.Length == 0) {
return new MissionInfluence[0];
}
return results;
}
2022-11-24 15:54:44 +01:00
/// <summary>
/// A convenient Dictionary containing all influences given out by faction,
/// then by system address and then by influence handed out. Influence can
/// be either a series of "+" for positive influence, or "-" for negative
/// influence.
2022-11-24 15:54:44 +01:00
/// </summary>
public Dictionary<string, Dictionary<ulong, MissionInfluence>> Influences {
get {
return FactionEffects
.Where(x => x.Faction != null)
.ToDictionary(
x => (x.Faction ?? string.Empty),
x => x.Influences
.Where(x => x.SystemAddress != null)
.ToDictionary(
x => (x.SystemAddress ?? 0),
x => x
)
);
}
}
public static Mission FromMissionAccepted(JObject o) {
return FromJSON(o);
}
public static Mission FromMissionAbandoned(JObject o) {
return FromJSON(o);
}
public static Mission FromMissionFailed(JObject o) {
return FromJSON(o);
}
public static Mission FromMissionCompleted(JObject o) {
return FromJSON(o);
}
}