add a highly rudimentary combat zone detector

This commit is contained in:
Florian Stinglmayr 2022-11-25 17:13:17 +01:00
parent fe28a4d17d
commit 955a108f2e
7 changed files with 331 additions and 1 deletions

View File

@ -1,6 +1,7 @@
using EDPlayerJournal.Entries; using EDPlayerJournal.Entries;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection.Metadata.Ecma335; using System.Reflection.Metadata.Ecma335;
using System.Transactions;
namespace EDPlayerJournal.BGS; namespace EDPlayerJournal.BGS;
@ -10,6 +11,22 @@ internal class TransactionParserContext {
public string? CurrentStation { get; set; } public string? CurrentStation { get; set; }
public string? ControllingFaction { get; set; } public string? ControllingFaction { get; set; }
public bool IsOnFoot { get; set; } = false;
public string? LastRecordedAwardingFaction { get; set; }
public ulong? HighestCombatBond { get; set; }
/// <summary>
/// How many on foot kills were done.
/// </summary>
public ulong OnFootKills { get; set; } = 0;
/// <summary>
/// How many ship kills were done.
/// </summary>
public ulong ShipKills { get; set; } = 0;
/// <summary> /// <summary>
/// A list of accepted missions index by their mission ID /// A list of accepted missions index by their mission ID
/// </summary> /// </summary>
@ -32,6 +49,67 @@ internal class TransactionParserContext {
/// </summary> /// </summary>
public Dictionary<string, long> BuyCost = new(); public Dictionary<string, long> BuyCost = new();
public void DiscernCombatZone(TransactionList transactions) {
string grade = "Low";
string cztype;
ulong? highest = HighestCombatBond;
if (highest == null || LastRecordedAwardingFaction == null) {
return;
}
if (OnFootKills > 0) {
cztype = "OnFoot";
// High on foot combat zones have enforcers that bring 80k a pop
if (highest >= 80000) {
grade = "High";
} else if (highest >= 4000) {
grade = "Medium";
}
} else if (ShipKills > 0) {
// Ship combat zones can be identified by the amount of kills
if (ShipKills > 20) {
grade = "High";
} else if (ShipKills > 10) {
grade = "Medium";
}
cztype = "Ship";
} else {
transactions.AddIncomplete(new CombatZone(), "Failed to discern combat zone type");
return;
}
CombatZone zone = new CombatZone() {
System = CurrentSystem,
Faction = LastRecordedAwardingFaction,
Grade = grade,
Type = cztype,
Amount = 1,
};
transactions.Add(zone);
}
public void RecordCombatBond(FactionKillBondEntry e) {
if (HighestCombatBond == null || e.Reward > HighestCombatBond) {
HighestCombatBond = e.Reward;
}
LastRecordedAwardingFaction = e.AwardingFaction;
if (IsOnFoot) {
++OnFootKills;
} else {
++ShipKills;
}
}
public void ResetCombatZone() {
HighestCombatBond = null;
LastRecordedAwardingFaction = null;
OnFootKills = 0;
ShipKills = 0;
}
public void BoughtCargo(string? cargo, long? cost) { public void BoughtCargo(string? cargo, long? cost) {
if (cargo == null || cost == null) { if (cargo == null || cost == null) {
return; return;
@ -610,7 +688,36 @@ internal class FactionKillBondParser : TransactionParserPart {
Faction = Factions.PilotsFederation, Faction = Factions.PilotsFederation,
Station = context.CurrentStation, Station = context.CurrentStation,
}); });
// We are done
return;
} }
context.RecordCombatBond(entry);
}
}
internal class EmbarkDisembarkParser : TransactionParserPart {
public void Parse(Entry e, TransactionParserContext context, TransactionList transactions) {
if (e.Is(Events.Embark)) {
context.IsOnFoot = false;
} else if (e.Is(Events.Disembark)) {
context.IsOnFoot = true;
}
}
}
internal class SupercruiseEntryParser : TransactionParserPart {
public void Parse(Entry entry, TransactionParserContext context, TransactionList transactions) {
context.DiscernCombatZone(transactions);
context.ResetCombatZone();
}
}
internal class ShutdownParser : TransactionParserPart {
public void Parse(Entry entry, TransactionParserContext context, TransactionList transactions) {
context.DiscernCombatZone(transactions);
context.ResetCombatZone();
} }
} }
@ -618,7 +725,9 @@ public class TransactionParser {
private static Dictionary<string, TransactionParserPart> ParserParts { get; } = new() private static Dictionary<string, TransactionParserPart> ParserParts { get; } = new()
{ {
{ Events.CommitCrime, new CommitCrimeParser() }, { Events.CommitCrime, new CommitCrimeParser() },
{ Events.Disembark, new EmbarkDisembarkParser() },
{ Events.Docked, new DockedParser() }, { Events.Docked, new DockedParser() },
{ Events.Embark, new EmbarkDisembarkParser() },
{ Events.FactionKillBond, new FactionKillBondParser() }, { Events.FactionKillBond, new FactionKillBondParser() },
{ Events.FSDJump, new FSDJumpParser() }, { Events.FSDJump, new FSDJumpParser() },
{ Events.Location, new LocationParser() }, { Events.Location, new LocationParser() },
@ -634,6 +743,8 @@ public class TransactionParser {
{ Events.SellMicroResources, new SellMicroResourcesParser() }, { Events.SellMicroResources, new SellMicroResourcesParser() },
{ Events.SellOrganicData, new SellOrganicDataParser() }, { Events.SellOrganicData, new SellOrganicDataParser() },
{ Events.ShipTargeted, new ShipTargetedParser() }, { Events.ShipTargeted, new ShipTargetedParser() },
{ Events.Shutdown, new ShutdownParser() },
{ Events.SupercruiseEntry, new SupercruiseEntryParser() },
}; };
public List<Transaction>? Parse(IEnumerable<Entry> entries) { public List<Transaction>? Parse(IEnumerable<Entry> entries) {

View File

@ -0,0 +1,66 @@
namespace EDPlayerJournal.Entries;
public class DisembarkEntry : Entry {
/// <summary>
/// Disembarked into an SRV?
/// </summary>
public bool SRV { get; set; } = false;
/// <summary>
/// Taxi?
/// </summary>
public bool Taxi { get; set; } = false;
/// <summary>
/// Multicrew or not.
/// </summary>
public bool Multicrew { get; set; } = false;
/// <summary>
/// Player's ship ID
/// </summary>
public ulong? ID { get; set; }
/// <summary>
/// Star system
/// </summary>
public string? StarSystem { get; set; }
/// <summary>
/// System address
/// </summary>
public ulong? SystemAddress { get; set; }
/// <summary>
/// Body, name e.g. HIP 6182 B 2 a
/// </summary>
public string? Body { get; set; }
/// <summary>
/// Body ID
/// </summary>
public ulong? BodyID { get; set; }
/// <summary>
/// Disembarked on a station?
/// </summary>
public bool OnStation { get; set; } = false;
/// <summary>
/// Disembarked on a planet?
/// </summary>
public bool OnPlanet { get; set; } = false;
protected override void Initialise() {
SRV = JSON.Value<bool?>("SRV") ?? false;
Taxi = JSON.Value<bool?>("Taxi") ?? false;
Multicrew = JSON.Value<bool?>("Multicrew") ?? false;
ID = JSON.Value<ulong?>("ID");
StarSystem = JSON.Value<string?>("StarSystem");
SystemAddress = JSON.Value<ulong?>("SystemAddress");
Body = JSON.Value<string?>("Body");
BodyID = JSON.Value<ulong?>("BodyID");
OnStation = JSON.Value<bool?>("OnStation") ?? false;
OnPlanet = JSON.Value<bool?>("OnPlanet") ?? false;
}
}

View File

@ -0,0 +1,66 @@
namespace EDPlayerJournal.Entries;
public class EmbarkEntry : Entry {
/// <summary>
/// Disembarked into an SRV?
/// </summary>
public bool SRV { get; set; } = false;
/// <summary>
/// Taxi?
/// </summary>
public bool Taxi { get; set; } = false;
/// <summary>
/// Multicrew or not.
/// </summary>
public bool Multicrew { get; set; } = false;
/// <summary>
/// Player's ship ID
/// </summary>
public ulong? ID { get; set; }
/// <summary>
/// Star system
/// </summary>
public string? StarSystem { get; set; }
/// <summary>
/// System address
/// </summary>
public ulong? SystemAddress { get; set; }
/// <summary>
/// Body, name e.g. HIP 6182 B 2 a
/// </summary>
public string? Body { get; set; }
/// <summary>
/// Body ID
/// </summary>
public ulong? BodyID { get; set; }
/// <summary>
/// Disembarked on a station?
/// </summary>
public bool OnStation { get; set; } = false;
/// <summary>
/// Disembarked on a planet?
/// </summary>
public bool OnPlanet { get; set; } = false;
protected override void Initialise() {
SRV = JSON.Value<bool?>("SRV") ?? false;
Taxi = JSON.Value<bool?>("Taxi") ?? false;
Multicrew = JSON.Value<bool?>("Multicrew") ?? false;
ID = JSON.Value<ulong?>("ID");
StarSystem = JSON.Value<string?>("StarSystem");
SystemAddress = JSON.Value<ulong?>("SystemAddress");
Body = JSON.Value<string?>("Body");
BodyID = JSON.Value<ulong?>("BodyID");
OnStation = JSON.Value<bool?>("OnStation") ?? false;
OnPlanet = JSON.Value<bool?>("OnPlanet") ?? false;
}
}

View File

@ -16,9 +16,11 @@ public class Entry {
{ Events.Commander, typeof(CommanderEntry) }, { Events.Commander, typeof(CommanderEntry) },
{ Events.CommitCrime, typeof(CommitCrimeEntry) }, { Events.CommitCrime, typeof(CommitCrimeEntry) },
{ Events.Died, typeof(DiedEntry) }, { Events.Died, typeof(DiedEntry) },
{ Events.Disembark, typeof(DisembarkEntry) },
{ Events.Docked, typeof(DockedEntry) }, { Events.Docked, typeof(DockedEntry) },
{ Events.FileHeader, typeof(FileHeaderEntry) }, { Events.Embark, typeof(EmbarkEntry) },
{ Events.FactionKillBond, typeof(FactionKillBondEntry) }, { Events.FactionKillBond, typeof(FactionKillBondEntry) },
{ Events.FileHeader, typeof(FileHeaderEntry) },
{ Events.FSDJump, typeof(FSDJumpEntry) }, { Events.FSDJump, typeof(FSDJumpEntry) },
{ Events.HullDamage, typeof(HullDamageEntry) }, { Events.HullDamage, typeof(HullDamageEntry) },
{ Events.LoadGame, typeof(LoadGameEntry) }, { Events.LoadGame, typeof(LoadGameEntry) },
@ -39,6 +41,8 @@ public class Entry {
{ Events.SellOrganicData, typeof(SellOrganicDataEntry) }, { Events.SellOrganicData, typeof(SellOrganicDataEntry) },
{ Events.ShieldState, typeof(ShieldStateEntry) }, { Events.ShieldState, typeof(ShieldStateEntry) },
{ Events.ShipTargeted, typeof(ShipTargetedEntry) }, { Events.ShipTargeted, typeof(ShipTargetedEntry) },
{ Events.SupercruiseEntry, typeof(SupercruiseEntryEntry) },
{ Events.SupercruiseExit, typeof(SupercruiseExitEntry) },
{ Events.UnderAttack, typeof(UnderAttackEntry) }, { Events.UnderAttack, typeof(UnderAttackEntry) },
}; };

View File

@ -5,7 +5,9 @@ public class Events {
public static readonly string Commander = "Commander"; public static readonly string Commander = "Commander";
public static readonly string CommitCrime = "CommitCrime"; public static readonly string CommitCrime = "CommitCrime";
public static readonly string Died = "Died"; public static readonly string Died = "Died";
public static readonly string Disembark = "Disembark";
public static readonly string Docked = "Docked"; public static readonly string Docked = "Docked";
public static readonly string Embark = "Embark";
public static readonly string FactionKillBond = "FactionKillBond"; public static readonly string FactionKillBond = "FactionKillBond";
public static readonly string FighterDestroyed = "FighterDestroyed"; public static readonly string FighterDestroyed = "FighterDestroyed";
public static readonly string FileHeader = "Fileheader"; public static readonly string FileHeader = "Fileheader";
@ -29,5 +31,8 @@ public class Events {
public static readonly string SellOrganicData = "SellOrganicData"; public static readonly string SellOrganicData = "SellOrganicData";
public static readonly string ShieldState = "ShieldState"; public static readonly string ShieldState = "ShieldState";
public static readonly string ShipTargeted = "ShipTargeted"; public static readonly string ShipTargeted = "ShipTargeted";
public static readonly string Shutdown = "Shutdown";
public static readonly string SupercruiseEntry = "SupercruiseEntry";
public static readonly string SupercruiseExit = "SupercruiseExit";
public static readonly string UnderAttack = "UnderAttack"; public static readonly string UnderAttack = "UnderAttack";
} }

View File

@ -0,0 +1,30 @@
namespace EDPlayerJournal.Entries;
public class SupercruiseEntryEntry : Entry {
/// <summary>
/// Taxi?
/// </summary>
public bool Taxi { get; set; } = false;
/// <summary>
/// Multicrew or not.
/// </summary>
public bool Multicrew { get; set; } = false;
/// <summary>
/// Star system
/// </summary>
public string? StarSystem { get; set; }
/// <summary>
/// System address
/// </summary>
public ulong? SystemAddress { get; set; }
protected override void Initialise() {
Taxi = JSON.Value<bool?>("Taxi") ?? false;
Multicrew = JSON.Value<bool?>("Multicrew") ?? false;
StarSystem = JSON.Value<string?>("StarSystem");
SystemAddress = JSON.Value<ulong?>("SystemAddress");
}
}

View File

@ -0,0 +1,48 @@
namespace EDPlayerJournal.Entries;
public class SupercruiseExitEntry : Entry {
/// <summary>
/// Taxi?
/// </summary>
public bool Taxi { get; set; } = false;
/// <summary>
/// Multicrew or not.
/// </summary>
public bool Multicrew { get; set; } = false;
/// <summary>
/// Star system
/// </summary>
public string? StarSystem { get; set; }
/// <summary>
/// System address
/// </summary>
public ulong? SystemAddress { get; set; }
/// <summary>
/// Body, name e.g. HIP 6182 B 2 a
/// </summary>
public string? Body { get; set; }
/// <summary>
/// Body ID
/// </summary>
public ulong? BodyID { get; set; }
/// <summary>
/// Body type (star, planet etc.)
/// </summary>
public string? BodyType { get; set; }
protected override void Initialise() {
Taxi = JSON.Value<bool?>("Taxi") ?? false;
Multicrew = JSON.Value<bool?>("Multicrew") ?? false;
StarSystem = JSON.Value<string?>("StarSystem");
SystemAddress = JSON.Value<ulong?>("SystemAddress");
Body = JSON.Value<string?>("Body");
BodyType = JSON.Value<string?>("BodyType");
BodyID = JSON.Value<ulong?>("BodyID");
}
}