Compare commits

..

10 Commits

18 changed files with 266 additions and 168 deletions

View File

@ -3,40 +3,15 @@ using System.Linq;
namespace EDPlayerJournal.BGS;
public class CombatZone : Transaction {
/// <summary>
/// Type string for ground combat zone
/// </summary>
public static readonly string GroundCombatZone = "Ground";
/// <summary>
/// Type string for ship combat zones
/// </summary>
public static readonly string ShipCombatZone = "Ship";
/// <summary>
/// Difficulty low
/// </summary>
public static readonly string DifficultyLow = "Low";
/// <summary>
/// Difficulty medium
/// </summary>
public static readonly string DifficultyMedium = "Medium";
/// <summary>
/// Difficulty high
/// </summary>
public static readonly string DifficultyHigh = "High";
/// <summary>
/// Type, either on foot or ship
/// </summary>
public string Type { get; set; } = ShipCombatZone;
public string Type { get; set; } = CombatZones.ShipCombatZone;
/// <summary>
/// Difficulty type, low, medium or high.
/// Difficulty type, low, medium or high. Null means unknown.
/// </summary>
public string Grade { get; set; } = DifficultyLow;
public string? Grade { get; set; }
/// <summary>
/// Whether spec ops were won.
@ -77,14 +52,21 @@ public class CombatZone : Transaction {
/// Returns true if it is an on foot/ground combat zone
/// </summary>
public bool IsGround {
get { return string.Compare(Type, GroundCombatZone) == 0; }
get { return string.Compare(Type, CombatZones.GroundCombatZone) == 0; }
}
/// <summary>
/// Returns true if it is an on foot combat zone
/// </summary>
public bool IsShip {
get { return string.Compare(Type, ShipCombatZone) == 0; }
get { return string.Compare(Type, CombatZones.ShipCombatZone) == 0; }
}
/// <summary>
/// Returns true if it is a thargoid combat zone
/// </summary>
public bool IsThargoid {
get { return string.Compare(Type, CombatZones.ThargoidCombatZone) == 0; }
}
public override int CompareTo(Transaction? obj) {
@ -109,6 +91,10 @@ public class CombatZone : Transaction {
}
public override string ToString() {
return string.Format("Won {0} {1} Combat Zone", Grade, Type);
if (Grade != null) {
return string.Format("Won {0} {1} Combat Zone", Grade, Type);
} else {
return string.Format("Won {0} Combat Zone", Type);
}
}
}

View File

@ -10,8 +10,17 @@ namespace EDPlayerJournal.BGS;
/// </summary>
public class InfluenceSupport : Transaction {
public string Influence { get; set; } = "";
/// <summary>
/// Relevant mission completed entry
/// </summary>
public MissionCompletedEntry? RelevantMission { get; set; }
/// <summary>
/// Mission accepted entry
/// </summary>
public MissionAcceptedEntry? AcceptedEntry { get; set; }
public override string CompletedAt {
get {
if (RelevantMission == null) {

View File

@ -1,50 +1,72 @@
using System.Text;
using System.Collections.Generic;
using System.Text;
using EDPlayerJournal.Entries;
namespace EDPlayerJournal.BGS;
public class MissionCompleted : Transaction {
public MissionCompletedEntry? CompletedEntry { get; set; }
public MissionAcceptedEntry? AcceptedEntry { get; set; }
public MissionCompleted() { }
public MissionCompleted(MissionCompletedEntry e) {
Entries.Add(e);
public override string CompletedAt {
get {
if (CompletedEntry == null) {
return "";
}
return CompletedEntry.Timestamp.ToString("dd.MM.yyyy HH:mm UTC");
}
}
public string MissionName {
get {
MissionCompletedEntry? c = Entries[0] as MissionCompletedEntry;
if (c == null || c.Mission == null) {
if (CompletedEntry == null || CompletedEntry.Mission == null) {
return "";
}
return c.Mission.FriendlyName;
return CompletedEntry.Mission.FriendlyName;
}
}
public string Influence {
get {
MissionCompletedEntry? e = (Entries[0] as MissionCompletedEntry);
if (e == null || Faction == null || e.Mission == null) {
if (CompletedEntry == null || Faction == null || CompletedEntry.Mission == null) {
return "";
}
return (e.Mission.GetInfluenceForFaction(Faction, SystemAddress) ?? "");
return (CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress) ?? "");
}
}
/// <summary>
/// Rescue missions contribute to the system.
/// </summary>
public override bool SystemContribution {
get {
if (AcceptedEntry == null ||
AcceptedEntry.Mission == null ||
AcceptedEntry.Mission.Name == null) {
return false;
}
if (AcceptedEntry.Mission.IsRescueMission &&
AcceptedEntry.Mission.Name.Contains("Mission_TW_")) {
return true;
}
return false;
}
}
public override string ToString() {
if (Faction == null || Entries.Count <= 0) {
if (Faction == null || CompletedEntry == null || CompletedEntry.Mission == null) {
return "";
}
StringBuilder builder = new StringBuilder();
var entry = Entries[0] as MissionCompletedEntry;
if (entry == null || entry.Mission == null) {
return "";
}
var influence = entry.Mission.GetInfluenceForFaction(Faction, SystemAddress);
var influence = CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress);
builder.AppendFormat("{0}", MissionName);
if (influence != "") {

View File

@ -360,7 +360,9 @@ public class Report {
if (faction.Equals(source_faction_name) && system_address == accepted_address) {
/* This is the influence block for the origin of the mission.
*/
main_mission = new MissionCompleted(completed) {
main_mission = new MissionCompleted() {
CompletedEntry = completed,
AcceptedEntry = accepted,
System = accepted_system,
Faction = source_faction_name,
SystemAddress = accepted_address,

View File

@ -25,6 +25,14 @@ public class ThargoidKill : Transaction {
get { return (ulong)Entries.OfType<FactionKillBondEntry>().Sum(x => (decimal)x.Reward); }
}
/// <summary>
/// Kiling thargoids contributes to the system wide effort of
/// the thargoid war.
/// </summary>
public override bool SystemContribution {
get { return true; }
}
public ThargoidKill() { }
public ThargoidKill(FactionKillBondEntry entry) {

View File

@ -21,6 +21,16 @@ public class Transaction : IComparable<Transaction> {
}
}
/// <summary>
/// Whether the transaction helps the entire system.
/// While all transactions are related to one faction, sometimes their
/// overall effect on the system as a whole is more important, than to
/// their faction. For example, rescuing refugees helps the Thargoid war
/// effort in the system as a whole, not just for the faction.
/// So this is true for transactions that help the system as a whole.
/// </summary>
public virtual bool SystemContribution { get; } = false;
/// <summary>
/// Returns true if this transaction was completed in legacy ED
/// </summary>

View File

@ -34,6 +34,16 @@ internal class TransactionParserContext {
/// </summary>
public ulong ShipKills { get; set; } = 0;
/// <summary>
/// Thargoid scouts killed
/// </summary>
public ulong ThargoidScoutKills { get; set; } = 0;
/// <summary>
/// Thargoid interceptor kills
/// </summary>
public ulong ThargoidInterceptorKills { get; set; } = 0;
/// <summary>
/// A list of accepted missions index by their mission ID
/// </summary>
@ -57,7 +67,7 @@ internal class TransactionParserContext {
public Dictionary<string, long> BuyCost = new();
public void DiscernCombatZone(TransactionList transactions, Entry e) {
string grade = CombatZone.DifficultyLow;
string? grade = CombatZones.DifficultyLow;
string cztype;
ulong? highest = HighestCombatBond;
@ -66,40 +76,45 @@ internal class TransactionParserContext {
}
if (OnFootKills > 0) {
cztype = CombatZone.GroundCombatZone;
cztype = CombatZones.GroundCombatZone;
// High on foot combat zones have enforcers that bring 80k a pop
if (highest >= 80000) {
grade = CombatZone.DifficultyHigh;
grade = CombatZones.DifficultyHigh;
} else if (highest >= 40000) {
grade = CombatZone.DifficultyMedium;
grade = CombatZones.DifficultyMedium;
} else {
grade = CombatZone.DifficultyLow;
grade = CombatZones.DifficultyLow;
}
} else if (ShipKills > 0) {
// Ship combat zones can be identified by the amount of kills
if (ShipKills > 20) {
grade = CombatZone.DifficultyHigh;
grade = CombatZones.DifficultyHigh;
} else if (ShipKills > 10) {
grade = CombatZone.DifficultyMedium;
grade = CombatZones.DifficultyMedium;
}
// Cap ship, means a high conflict zone
if (HaveSeenCapShip) {
grade = CombatZone.DifficultyHigh;
grade = CombatZones.DifficultyHigh;
} else {
int warzoneNpcs = new List<bool>() { HaveSeenCaptain, HaveSeenCorrespondent, HaveSeenSpecOps }
.Where(x => x == true)
.Count()
;
if (warzoneNpcs >= 2 && grade != CombatZone.DifficultyHigh) {
if (warzoneNpcs >= 2 && grade != CombatZones.DifficultyHigh) {
// Only large combat zones have two NPCs
grade = CombatZone.DifficultyHigh;
} else if (warzoneNpcs >= 1 && grade == CombatZone.DifficultyLow) {
grade = CombatZone.DifficultyMedium;
grade = CombatZones.DifficultyHigh;
} else if (warzoneNpcs >= 1 && grade == CombatZones.DifficultyLow) {
grade = CombatZones.DifficultyMedium;
}
}
cztype = CombatZone.ShipCombatZone;
cztype = CombatZones.ShipCombatZone;
} else if (ThargoidScoutKills > 0 && ThargoidInterceptorKills > 0) {
// Could be a thargoid combat zones if interceptors and scouts are there
cztype = CombatZones.ThargoidCombatZone;
// Still unknown
grade = null;
} else {
transactions.AddIncomplete(new CombatZone(), "Failed to discern combat zone type");
return;
@ -144,6 +159,8 @@ internal class TransactionParserContext {
LastRecordedAwardingFaction = null;
OnFootKills = 0;
ShipKills = 0;
ThargoidInterceptorKills = 0;
ThargoidScoutKills = 0;
}
public void BoughtCargo(string? cargo, long? cost) {
@ -499,7 +516,9 @@ internal class MissionCompletedParser : TransactionParserPart {
system_address == accepted_location.SystemAddress) {
// Source and target faction are the same, and this is the block
// for the source system. So we make a full mission completed entry.
transactions.Add(new MissionCompleted(entry) {
transactions.Add(new MissionCompleted() {
CompletedEntry = entry,
AcceptedEntry = accepted,
System = accepted_location.StarSystem,
Faction = source_faction_name,
SystemAddress = accepted_location.SystemAddress,
@ -513,6 +532,7 @@ internal class MissionCompletedParser : TransactionParserPart {
// differs. Sometimes missions go to different systems but to
// the same faction.
transactions.Add(new InfluenceSupport() {
AcceptedEntry = accepted,
Faction = faction,
Influence = influences.Value,
System = system,
@ -773,6 +793,15 @@ internal class FactionKillBondParser : TransactionParserPart {
IsLegacy = context.IsLegacy,
});
ThargoidVessel vessel = Thargoid.GetVesselByPayout(entry.Reward);
if (vessel != ThargoidVessel.Unknown) {
if (vessel == ThargoidVessel.Scout) {
++context.ThargoidScoutKills;
} else {
++context.ThargoidInterceptorKills;
}
}
// We are done
return;
}

View File

@ -0,0 +1,36 @@
namespace EDPlayerJournal;
/// <summary>
/// Static strings related to combat zones
/// </summary>
public class CombatZones {
/// <summary>
/// Type string for ground combat zone
/// </summary>
public static readonly string GroundCombatZone = "Ground";
/// <summary>
/// Type string for ship combat zones
/// </summary>
public static readonly string ShipCombatZone = "Ship";
/// <summary>
/// Thargoid combat zone
/// </summary>
public static readonly string ThargoidCombatZone = "Thargoid";
/// <summary>
/// Difficulty low
/// </summary>
public static readonly string DifficultyLow = "Low";
/// <summary>
/// Difficulty medium
/// </summary>
public static readonly string DifficultyMedium = "Medium";
/// <summary>
/// Difficulty high
/// </summary>
public static readonly string DifficultyHigh = "High";
}

View File

@ -93,6 +93,7 @@ public class EnglishMissionNames {
{"MISSION_Scan_name", "Scan"},
{"Mission_Sightseeing_Criminal_FAMINE_name", "Sightseeing (Criminal) (Famine)"},
{"Mission_Sightseeing_name", "Sightseeing"},
{"Mission_TW_PassengerEvacuation_UnderAttack_name", "Passenger Evacuation (Thargoid Invasion)" },
};
public static string? Translate(string name) {

View File

@ -109,6 +109,11 @@ public class MissionFactionEffects {
}
public class Mission : IComparable<Mission> {
/// <summary>
/// Passenger type for refugees
/// </summary>
public static readonly string PassengerTypeRefugee = "Refugee";
public ulong MissionID { get; set; } = 0;
/// <summary>
@ -250,6 +255,31 @@ public class Mission : IComparable<Mission> {
/// </summary>
public List<MissionFactionEffects> FactionEffects { get; set; } = new List<MissionFactionEffects>();
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

View File

@ -1,48 +0,0 @@
<Window x:Class="EliteBGS.CombatZoneDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:EliteBGS"
mc:Ignorable="d"
Title="Add Combat Zone Wins" Height="150" Width="370" Icon="EliteBGS.ico" WindowStartupLocation="CenterOwner">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<GroupBox Header="Add Combat Zone" Grid.Row="0" Grid.Column="0" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ComboBox x:Name="type" Grid.Column="0" VerticalAlignment="Top" Width="Auto" IsReadOnly="True" Height="23" Margin="5" SelectedIndex="0">
<ComboBoxItem Content="Ship"/>
<ComboBoxItem Content="On Foot"/>
</ComboBox>
<ComboBox x:Name="grade" Grid.Column="1" VerticalAlignment="Top" IsReadOnly="True" Margin="5" Height="23" Width="Auto" SelectedIndex="0">
<ComboBoxItem Content="Low"/>
<ComboBoxItem Content="Medium"/>
<ComboBoxItem Content="High"/>
</ComboBox>
<TextBox x:Name="amount" Grid.Column="2" Height="23" TextWrapping="Wrap" Text="1" VerticalAlignment="Top" Width="Auto" Margin="5" HorizontalContentAlignment="Right"/>
</Grid>
</GroupBox>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button x:Name="Accept" Content="Accept" HorizontalAlignment="Right" Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Width="75" Margin="5" IsDefault="True" Click="Accept_Click"/>
<Button x:Name="Cancel" Content="Cancel" HorizontalAlignment="Right" Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Width="75" Margin="5" IsCancel="True" Click="Cancel_Click"/>
</Grid>
</Grid>
</Window>

View File

@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace EliteBGS {
/// <summary>
/// Interaction logic for CombatZoneDialog.xaml
/// </summary>
public partial class CombatZoneDialog : Window {
public CombatZoneDialog() {
InitializeComponent();
}
public string Type => (type.SelectedItem as ComboBoxItem).Content.ToString();
public string Grade => (grade.SelectedItem as ComboBoxItem).Content.ToString();
public int Amount {
get {
try {
return int.Parse(amount.Text);
} catch (Exception) {
return 1;
}
}
}
private void Accept_Click(object sender, RoutedEventArgs e) {
DialogResult = true;
Close();
}
private void Cancel_Click(object sender, RoutedEventArgs e) {
DialogResult = false;
Close();
}
}
}

View File

@ -13,6 +13,11 @@
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Salus.ico</ApplicationIcon>
<Title>BGS reporting and logging tool for Elite:Dangerous</Title>
<Authors>nola</Authors>
<Copyright>Copyright 2019 by Florian Stinglmayr</Copyright>
<RepositoryUrl>https://git.aror.org/florian/EDBGS</RepositoryUrl>
<PackageTags>ED;Elite Dangerous;BGS</PackageTags>
</PropertyGroup>
<ItemGroup>
<Resource Include="main-page.png">

View File

@ -116,6 +116,7 @@
<StackPanel Orientation="Vertical">
<Button Content="Ground" x:Name="Ground" Click="Ground_Click"/>
<Button Content="Ship" x:Name="Ship" Click="Ship_Click"/>
<Button Content="Thargoid" x:Name="Thargoid" Click="Thargoid_Click"/>
</StackPanel>
</Expander>
</StackPanel>

View File

@ -285,7 +285,7 @@ public partial class MainWindow : Window {
return;
}
transaction.Grade = CombatZone.DifficultyLow;
transaction.Grade = CombatZones.DifficultyLow;
RefreshView();
}
@ -295,7 +295,7 @@ public partial class MainWindow : Window {
return;
}
transaction.Grade = CombatZone.DifficultyMedium;
transaction.Grade = CombatZones.DifficultyMedium;
RefreshView();
}
@ -305,7 +305,7 @@ public partial class MainWindow : Window {
return;
}
transaction.Grade = CombatZone.DifficultyHigh;
transaction.Grade = CombatZones.DifficultyHigh;
RefreshView();
}
@ -315,7 +315,7 @@ public partial class MainWindow : Window {
return;
}
transaction.Type = CombatZone.GroundCombatZone;
transaction.Type = CombatZones.GroundCombatZone;
RefreshView();
}
@ -325,7 +325,17 @@ public partial class MainWindow : Window {
return;
}
transaction.Type = CombatZone.ShipCombatZone;
transaction.Type = CombatZones.ShipCombatZone;
RefreshView();
}
private void Thargoid_Click(object sender, RoutedEventArgs e) {
CombatZone transaction = GetTransaction<CombatZone>(sender);
if (transaction == null) {
return;
}
transaction.Type = CombatZones.ThargoidCombatZone;
RefreshView();
}

View File

@ -8,7 +8,7 @@ public class MinusFortyFiveConverter : IValueConverter {
/// <inheritdoc/>
public object Convert(
object value, Type targetType, object parameter, CultureInfo culture) {
return (double)value - 55;
return (double)value - 65;
}
/// <inheritdoc/>

View File

@ -5,6 +5,7 @@ using Newtonsoft.Json;
using EDPlayerJournal.BGS;
using System.Linq;
using System.Windows;
using EDPlayerJournal;
namespace EliteBGS;
@ -25,6 +26,21 @@ public class UITransaction {
}
}
public Visibility IsGroundCombatZone {
get {
CombatZone combat = Transaction as CombatZone;
if (combat == null) {
return Visibility.Hidden;
}
if (string.Compare(combat.Type, CombatZones.GroundCombatZone) == 0) {
return Visibility.Visible;
}
return Visibility.Hidden;
}
}
public Visibility IsShipCombatZone {
get {
CombatZone combat = Transaction as CombatZone;
@ -32,7 +48,22 @@ public class UITransaction {
return Visibility.Hidden;
}
if (string.Compare(combat.Type, "Ship") == 0) {
if (string.Compare(combat.Type, CombatZones.ShipCombatZone) == 0) {
return Visibility.Visible;
}
return Visibility.Hidden;
}
}
public Visibility IsThargoidCombatZone {
get {
CombatZone combat = Transaction as CombatZone;
if (combat == null) {
return Visibility.Hidden;
}
if (string.Compare(combat.Type, CombatZones.ThargoidCombatZone) == 0) {
return Visibility.Visible;
}
@ -196,6 +227,10 @@ public class Objective : IComparable<Objective> {
string.Compare(faction, Faction) == 0;
}
public bool Matches(string system) {
return string.Compare(system, System) == 0;
}
public int CompareTo(Objective other) {
return (other.System == System &&
other.Faction == Faction) ? 0 : -1;

View File

@ -18,10 +18,19 @@ public class Report {
}
foreach (Transaction t in transactions) {
Objective o = Objectives.Find(x => x.Matches(t.System, t.Faction));
Objective o;
if (t.SystemContribution) {
o = Objectives.Find(x => x.Matches(t.System));
} else {
o = Objectives.Find(x => x.Matches(t.System, t.Faction));
}
if (o == null) {
o = new Objective() { Faction = t.Faction, System = t.System };
if (t.SystemContribution) {
o = new Objective() { System = t.System };
} else {
o = new Objective() { Faction = t.Faction, System = t.System };
}
Objectives.Add(o);
}