introduce negative influence

Sometimes missions actually tell us how much negative influence a faction got through secondary influences. We now count this, and present is as negative influence via minuses. Summaries have been updated to reflect this change.
This commit is contained in:
Florian Stinglmayr 2023-09-08 11:20:49 +02:00
parent c7a70598c4
commit c43c6f742a
8 changed files with 93 additions and 35 deletions

View File

@ -9,7 +9,7 @@ namespace EDPlayerJournal.BGS;
/// faction to another. Both sometimes gain influence. /// faction to another. Both sometimes gain influence.
/// </summary> /// </summary>
public class InfluenceSupport : Transaction { public class InfluenceSupport : Transaction {
public string Influence { get; set; } = ""; public MissionInfluence? Influence { get; set; } = null;
/// <summary> /// <summary>
/// Relevant mission completed entry /// Relevant mission completed entry
@ -46,7 +46,7 @@ public class InfluenceSupport : Transaction {
builder.AppendFormat("Influence gained from \"{0}\": \"{1}\"", builder.AppendFormat("Influence gained from \"{0}\": \"{1}\"",
missionname, missionname,
string.IsNullOrEmpty(Influence) ? "NONE" : Influence Influence == null ? "NONE" : Influence.TrendAdjustedInfluence
); );
return builder.ToString(); return builder.ToString();

View File

@ -38,7 +38,14 @@ public class MissionCompleted : Transaction {
return ""; return "";
} }
return (CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress) ?? ""); return string.Join("",
CompletedEntry
.Mission
.GetInfluenceForFaction(Faction, SystemAddress)
.Select(x => x.Influence)
.ToArray()
)
;
} }
} }
@ -70,8 +77,10 @@ public class MissionCompleted : Transaction {
var influence = CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress); var influence = CompletedEntry.Mission.GetInfluenceForFaction(Faction, SystemAddress);
builder.AppendFormat("{0}", MissionName); builder.AppendFormat("{0}", MissionName);
if (influence != "") { if (influence != null && influence.Length > 0) {
builder.AppendFormat(", Influence: {0}", influence); builder.AppendFormat(", Influence: {0}",
influence.Select(x => x.InfluenceAmount).Sum()
);
} }
return builder.ToString(); return builder.ToString();

View File

@ -298,20 +298,20 @@ internal class MissionCompletedParser : ITransactionParserPart {
if (context.CurrentSystemAddress == null) { if (context.CurrentSystemAddress == null) {
continue; continue;
} }
other.Value.Add(context.CurrentSystemAddress.Value, ""); other.Value.Add(context.CurrentSystemAddress.Value, new MissionInfluence());
// Mission gave no influence to the target faction, so we assume // Mission gave no influence to the target faction, so we assume
// the target faction was in the same system. // the target faction was in the same system.
} else if (string.Compare(source_faction_name, faction, true) == 0) { } else if (string.Compare(source_faction_name, faction, true) == 0) {
// This happens if the source faction is not getting any influence // This happens if the source faction is not getting any influence
// This could be if the source faction is in a conflict, and thus does // This could be if the source faction is in a conflict, and thus does
// not gain any influence at all. // not gain any influence at all.
other.Value.Add(accepted_location.SystemAddress, ""); other.Value.Add(accepted_location.SystemAddress, new MissionInfluence());
// Just check if the target/source faction are the same, in which case // Just check if the target/source faction are the same, in which case
// we also have to make an additional entry // we also have to make an additional entry
if (string.Compare(source_faction_name, target_faction_name, true) == 0 && if (string.Compare(source_faction_name, target_faction_name, true) == 0 &&
context.CurrentSystemAddress != null) { context.CurrentSystemAddress != null) {
other.Value.Add(context.CurrentSystemAddress.Value, ""); other.Value.Add(context.CurrentSystemAddress.Value, new MissionInfluence());
} }
} }
} }

View File

@ -36,6 +36,31 @@ public class MissionInfluence {
/// </summary> /// </summary>
public string Influence { get; set; } = string.Empty; 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) { public static MissionInfluence FromJSON(JObject obj) {
MissionInfluence missionInfluence = new MissionInfluence(); MissionInfluence missionInfluence = new MissionInfluence();
@ -394,27 +419,29 @@ public class Mission : IComparable<Mission> {
/// <param name="faction">Faction name in question.</param> /// <param name="faction">Faction name in question.</param>
/// <param name="systemaddr">Star System address</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> /// <returns>null if no entry was found, or a string denoting pluses for the amount influence gained.</returns>
public string? GetInfluenceForFaction(string faction, ulong systemaddr) { public MissionInfluence[]? GetInfluenceForFaction(string faction, ulong systemaddr) {
var results = FactionEffects var results = FactionEffects
.Where(x => string.Compare(x.Faction, faction) == 0) .Where(x => string.Compare(x.Faction, faction) == 0)
.SelectMany(x => x.Influences) .SelectMany(x => x.Influences)
.Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr)) .Where(x => (x.SystemAddress != null && x.SystemAddress == systemaddr))
.Select(x => x.Influence) .Select(x => x)
.ToArray() .ToArray()
; ;
if (results == null || results.Length == 0) { if (results == null || results.Length == 0) {
return null; return new MissionInfluence[0];
} }
return string.Join("", results); return results;
} }
/// <summary> /// <summary>
/// A convenient Dictionary containing all influences given out by faction, /// A convenient Dictionary containing all influences given out by faction,
/// then by system address and then by influence handed out. /// then by system address and then by influence handed out. Influence can
/// be either a series of "+" for positive influence, or "-" for negative
/// influence.
/// </summary> /// </summary>
public Dictionary<string, Dictionary<ulong, string>> Influences { public Dictionary<string, Dictionary<ulong, MissionInfluence>> Influences {
get { get {
return FactionEffects return FactionEffects
.Where(x => x.Faction != null) .Where(x => x.Faction != null)
@ -422,7 +449,10 @@ public class Mission : IComparable<Mission> {
x => (x.Faction ?? string.Empty), x => (x.Faction ?? string.Empty),
x => x.Influences x => x.Influences
.Where(x => x.SystemAddress != null) .Where(x => x.SystemAddress != null)
.ToDictionary(x => (x.SystemAddress ?? 0), x => x.Influence) .ToDictionary(
x => (x.SystemAddress ?? 0),
x => x
)
); );
} }
} }

View File

@ -59,9 +59,9 @@ public class MissionTest {
Assert.IsTrue(e.IsEmptyFaction); Assert.IsTrue(e.IsEmptyFaction);
Assert.AreEqual(e.Faction, string.Empty); Assert.AreEqual(e.Faction, string.Empty);
string? influence = m.GetInfluenceForFaction("", 251012319587UL); var influence = m.GetInfluenceForFaction("", 251012319587UL);
Assert.IsNotNull(influence); Assert.IsNotNull(influence);
Assert.AreEqual(influence, "+"); Assert.AreEqual(influence[0].Influence, "+");
e = m.FactionEffects[1]; e = m.FactionEffects[1];
Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation"); Assert.AreEqual(e.Faction, "Social LHS 6103 Confederation");
@ -101,22 +101,25 @@ public class MissionTest {
Assert.AreEqual(effect.Reputation, "++"); Assert.AreEqual(effect.Reputation, "++");
string? influence; var influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL);
Assert.IsNotNull(influence);
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1865919973739UL); Assert.IsTrue(influence.Length > 0);
Assert.AreEqual(influence, "++"); Assert.AreEqual(influence[0].Influence, "++");
influence = m.GetInfluenceForFaction("Salus Imperial Society", 1733186884306UL); influence = m.GetInfluenceForFaction("Salus Imperial Society", 1733186884306UL);
Assert.AreEqual(influence, "++"); Assert.IsNotNull(influence);
Assert.IsTrue(influence.Length > 0);
Assert.AreEqual(influence[0].Influence, "++");
influence = m.GetInfluenceForFaction("Saelishi Saxons", 1733186884306UL); influence = m.GetInfluenceForFaction("Saelishi Saxons", 1733186884306UL);
Assert.IsNull(influence); Assert.IsNotNull(influence);
Assert.AreEqual(influence.Length, 0);
// Only one entry are we only have Salus // Only one entry are we only have Salus
Assert.AreEqual(m.Influences.Count, 1); Assert.AreEqual(m.Influences.Count, 1);
Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2); Assert.AreEqual(m.Influences["Salus Imperial Society"].Count, 2);
Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL], "++"); Assert.AreEqual(m.Influences["Salus Imperial Society"][1865919973739UL].Influence, "++");
Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL], "++"); Assert.AreEqual(m.Influences["Salus Imperial Society"][1733186884306UL].Influence, "++");
} }
[TestMethod] [TestMethod]

View File

@ -19,7 +19,13 @@ public class TestTransactionParser {
return; return;
} }
List<Transaction>? transactions = parser.Parse(entries); var options = new TransactionParserOptions() {
IgnoreInfluenceSupport = false,
IgnoreExoBiology = false,
IgnoreFleetCarrierFaction = false,
IgnoreMarketBuy = false,
};
List<Transaction>? transactions = parser.Parse(entries, options);
Assert.IsNotNull(transactions, "could not parse entries"); Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 3); Assert.AreEqual(transactions.Count, 3);
@ -144,7 +150,14 @@ public class TestTransactionParser {
return; return;
} }
List<Transaction>? transactions = parser.Parse(entries); var options = new TransactionParserOptions() {
IgnoreInfluenceSupport = false,
IgnoreExoBiology = false,
IgnoreFleetCarrierFaction = false,
IgnoreMarketBuy = false,
};
List<Transaction>? transactions = parser.Parse(entries, options);
Assert.IsNotNull(transactions, "could not parse entries"); Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 1); Assert.AreEqual(transactions.Count, 1);
Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data"); Assert.IsInstanceOfType(transactions[0], typeof(OrganicData), "result is not of type Organic Data");

View File

@ -22,14 +22,17 @@ public class ThargoidKills {
Assert.IsNotNull(transactions, "could not parse entries"); Assert.IsNotNull(transactions, "could not parse entries");
Assert.AreEqual(transactions.Count, 3); Assert.AreEqual(transactions.Count, 3);
// In recent updates the payout was changed, that's why this test reports unknown thargoid vessels
// This test makes sure the new parser does not conflict with legacy values
//
Assert.IsInstanceOfType(transactions[0], typeof(ThargoidKill), "result is not of type ThargoidKill"); Assert.IsInstanceOfType(transactions[0], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[0].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout); Assert.AreEqual(transactions[0].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
Assert.IsInstanceOfType(transactions[1], typeof(ThargoidKill), "result is not of type ThargoidKill"); Assert.IsInstanceOfType(transactions[1], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[1].ThargoidType, EDPlayerJournal.ThargoidVessel.Basilisk); Assert.AreEqual(transactions[1].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
Assert.IsInstanceOfType(transactions[2], typeof(ThargoidKill), "result is not of type ThargoidKill"); Assert.IsInstanceOfType(transactions[2], typeof(ThargoidKill), "result is not of type ThargoidKill");
Assert.AreEqual(transactions[2].ThargoidType, EDPlayerJournal.ThargoidVessel.Scout); Assert.AreEqual(transactions[2].ThargoidType, EDPlayerJournal.ThargoidVessel.Unknown);
} }
[TestMethod] [TestMethod]

View File

@ -10,7 +10,7 @@ public class MissionFormat : LogFormatter {
Dictionary<string, Dictionary<string, int>> collated = new(); Dictionary<string, Dictionary<string, int>> collated = new();
Dictionary<string, ulong> passengers = new(); Dictionary<string, ulong> passengers = new();
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
int total_influence = 0; long total_influence = 0;
var missions = objective.EnabledOfType<MissionCompleted>(); var missions = objective.EnabledOfType<MissionCompleted>();
var support = objective.EnabledOfType<InfluenceSupport>(); var support = objective.EnabledOfType<InfluenceSupport>();
@ -63,14 +63,14 @@ public class MissionFormat : LogFormatter {
foreach (InfluenceSupport inf in support) { foreach (InfluenceSupport inf in support) {
output.Append(inf.ToString()); output.Append(inf.ToString());
output.Append("\n"); output.Append("\n");
total_influence += inf.Influence.Length; total_influence += inf.Influence.InfluenceAmount;
} }
if (support.Count() > 0) { if (support.Count() > 0) {
output.Append("\n"); output.Append("\n");
} }
if (total_influence > 0) { if (total_influence != 0) {
output.AppendFormat("Total Influence: {0}", total_influence); output.AppendFormat("Total Influence: {0}", total_influence);
} }
@ -84,10 +84,10 @@ public class MissionFormat : LogFormatter {
; ;
long support = objective long support = objective
.EnabledOfType<InfluenceSupport>() .EnabledOfType<InfluenceSupport>()
.Sum(x => x.Influence.Length) .Sum(x => x.Influence.InfluenceAmount)
; ;
if (influence + support <= 0) { if (influence == 0 && support == 0) {
return ""; return "";
} }