Skip to content

Commit

Permalink
Implement leader notifications for contract and tech completion
Browse files Browse the repository at this point in the history
  • Loading branch information
siimav committed Apr 6, 2024
1 parent 1001698 commit fa96df4
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 57 deletions.
18 changes: 2 additions & 16 deletions Source/RP0/Harmony/Contract.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using Contracts;
using HarmonyLib;
using RP0.Requirements;
using Strategies;
using UniLinq;

namespace RP0.Harmony
Expand Down Expand Up @@ -68,20 +66,8 @@ internal static bool Postfix_TextAward(ref string __result, string title, string
value += $"\n{KSP.Localization.Localizer.Format("#rp0_ContractRewards_GainApplicants", applicants)}";
}

var leadersUnlockedByThis = StrategySystem.Instance.SystemConfig.Strategies
.OfType<StrategyConfigRP0>()
.Where(s => s.DepartmentName != "Programs" &&
s.RequirementsBlock != null &&
(!_isReward || !s.IsUnlocked()) &&
(s.RequirementsBlock.Op is Any ||
s.RequirementsBlock.Op is All && s.RequirementsBlock.Reqs.Count == 1) &&
s.RequirementsBlock.ChildBlocks.Count == 0 &&
s.RequirementsBlock.Reqs.Any(r => !r.IsInverted &&
r is ContractRequirement cr &&
cr.ContractName == _contract.contractType.name))
.Select(s => s.title);

string leaderString = string.Join("\n", leadersUnlockedByThis);
var leaderTitles = LeaderUtils.GetLeadersUnlockedByContract(_contract).Select(s => s.title);
string leaderString = string.Join("\n", leaderTitles);
if (!string.IsNullOrEmpty(leaderString))
value += "\n" + KSP.Localization.Localizer.Format(_isReward ? "#rp0_Leaders_LeadersUnlocked" : "#rp0_Leaders_UnlocksLeader") + leaderString;

Expand Down
15 changes: 2 additions & 13 deletions Source/RP0/Programs/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -512,19 +512,8 @@ public string GetDescription(bool extendedInfo)

text = $"<b>Slots Taken: {slots}</b>\n\n{text}";

var leadersUnlockedByThis = StrategySystem.Instance.SystemConfig.Strategies
.OfType<StrategyConfigRP0>()
.Where(s => s.DepartmentName != "Programs" &&
s.RequirementsBlock != null &&
(s.RequirementsBlock.Op is Any ||
s.RequirementsBlock.Op is All && s.RequirementsBlock.Reqs.Count == 1) &&
s.RequirementsBlock.ChildBlocks.Count == 0 &&
s.RequirementsBlock.Reqs.Any(r => !r.IsInverted &&
r is ProgramRequirement pr &&
pr.ProgramName == name))
.Select(s => s.title);

string leaderString = string.Join("\n", leadersUnlockedByThis);
var leaderTitles = LeaderUtils.GetLeadersUnlockedByProgram(name).Select(s => s.title);
string leaderString = string.Join("\n", leaderTitles);
if (!string.IsNullOrEmpty(leaderString))
text += "\n\n" + Localizer.Format("#rp0_Leaders_UnlocksLeader") + leaderString;

Expand Down
32 changes: 4 additions & 28 deletions Source/RP0/Programs/ProgramHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
using System.Reflection;
using System.Reflection.Emit;
using KSP.UI.Screens.DebugToolbar;
using KSP.Localization;
using ROUtils.DataTypes;
using RP0.Singletons;

namespace RP0.Programs
{
Expand Down Expand Up @@ -528,18 +528,18 @@ public void ActivateProgram(Program p)

public void CompleteProgram(Program p)
{
List<StrategyConfigRP0> unlockedLeadersBef = GetAllUnlockedLeaders();
List<StrategyConfigRP0> unlockedLeadersBef = LeaderUtils.GetAllUnlockedLeaders().ToList();

ActivePrograms.Remove(p);
CompletedPrograms.Add(p);
p.Complete();
// No change needed to ProgramStrategy because reference holds.
ContractPreLoader.Instance?.ResetGenerationFailure();

List<StrategyConfigRP0> unlockedLeadersAft = GetAllUnlockedLeaders();
IEnumerable<StrategyConfigRP0> unlockedLeadersAft = LeaderUtils.GetAllUnlockedLeaders();
IEnumerable<StrategyConfigRP0> newLeaders = unlockedLeadersAft.Except(unlockedLeadersBef);

ShowNotificationForNewLeaders(newLeaders);
LeaderNotifications.ShowNotificationForNewLeaders(newLeaders);
}

private void DisableProgram(string s)
Expand All @@ -549,29 +549,5 @@ private void DisableProgram(string s)
else
RP0Debug.Log($"tried to disable program {s} but it already was!");
}

private static List<StrategyConfigRP0> GetAllUnlockedLeaders()
{
return Strategies.StrategySystem.Instance.SystemConfig.Strategies
.OfType<StrategyConfigRP0>()
.Where(s => s.DepartmentName != "Programs" && s.IsUnlocked())
.ToList();
}

private static void ShowNotificationForNewLeaders(IEnumerable<StrategyConfigRP0> newLeaders)
{
string leaderString = string.Join("\n", newLeaders.Select(s => s.Title));
if (!string.IsNullOrEmpty(leaderString))
{
PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
new Vector2(0.5f, 0.5f),
"LeaderUnlocked",
Localizer.Format("#rp0_Leaders_LeadersUnlockedTitle"),
Localizer.Format("#rp0_Leaders_LeadersUnlocked") + leaderString,
Localizer.GetStringByTag("#autoLOC_190905"),
true,
HighLogic.UISkin).HideGUIsWhilePopup();
}
}
}
}
2 changes: 2 additions & 0 deletions Source/RP0/RP0.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
<Compile Include="Harmony\FlightInputHandler.cs" />
<Compile Include="Harmony\ModuleRCS.cs" />
<Compile Include="ModIntegrations\TFInterop.cs" />
<Compile Include="Singletons\LeaderNotifications.cs" />
<Compile Include="SpaceCenter\Projects\VesselRepairProject.cs" />
<Compile Include="UI\ProceduralAvionicsWindow.cs" />
<Compile Include="CareerLog\CareerEvent.cs" />
Expand Down Expand Up @@ -69,6 +70,7 @@
<Compile Include="UI\TrainingGUI.cs" />
<Compile Include="Crew\TrainingExpiration.cs" />
<Compile Include="DesignConcerns\UntooledParts.cs" />
<Compile Include="Utilities\LeaderUtils.cs" />
<Compile Include="Utilities\RP0DTUtils.cs" />
<Compile Include="Harmony\MainMenu.cs" />
<Compile Include="Harmony\CrewListItem.cs" />
Expand Down
75 changes: 75 additions & 0 deletions Source/RP0/Singletons/LeaderNotifications.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using ContractConfigurator;
using Contracts;
using KSP.Localization;
using KSP.UI.Screens;
using ROUtils;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using static KSP.UI.Screens.MessageSystem;

namespace RP0.Singletons
{
public class LeaderNotifications : HostedSingleton
{
public LeaderNotifications(SingletonHost host) : base(host) { }

public override void Awake()
{
SubscribeToEvents();
}

public void SubscribeToEvents()
{
GameEvents.OnTechnologyResearched.Add(OnTechnologyResearched);
GameEvents.Contract.onCompleted.Add(OnContractComplete);
}

public static void ShowNotificationForNewLeaders(IEnumerable<StrategyConfigRP0> newLeaders)
{
string leaderString = string.Join("\n", newLeaders.Select(s => s.Title));
if (!string.IsNullOrEmpty(leaderString))
{
PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f),
new Vector2(0.5f, 0.5f),
"LeaderUnlocked",
Localizer.Format("#rp0_Leaders_LeadersUnlockedTitle"),
Localizer.Format("#rp0_Leaders_LeadersUnlocked") + leaderString,
Localizer.GetStringByTag("#autoLOC_190905"),
true,
HighLogic.UISkin).HideGUIsWhilePopup();
}
}

public static void AddNewLeadersUnlockedMessage(IEnumerable<StrategyConfigRP0> newLeaders)
{
var leaderLines = newLeaders.Select(s => s.title)
.Distinct()
.Select(s => $"{s}");
string leaderString = string.Join("\n", leaderLines);
if (!string.IsNullOrEmpty(leaderString))
{
MessageSystem.Instance?.AddMessage(
new Message(Localizer.Format("#rp0_Leaders_LeadersUnlockedTitle"),
Localizer.Format("#rp0_Leaders_LeadersUnlocked") + leaderString,
MessageSystemButton.MessageButtonColor.BLUE,
MessageSystemButton.ButtonIcons.MESSAGE));
}
}

private void OnContractComplete(Contract data)
{
if (data is ConfiguredContract cc)
{
var leadersUnlockedByThis = LeaderUtils.GetLeadersUnlockedByContract(cc);
AddNewLeadersUnlockedMessage(leadersUnlockedByThis);
}
}

private void OnTechnologyResearched(GameEvents.HostTargetAction<RDTech, RDTech.OperationResult> data)
{
var leadersUnlockedByThis = LeaderUtils.GetLeadersUnlockedByTech(data.host.techID);
AddNewLeadersUnlockedMessage(leadersUnlockedByThis);
}
}
}
59 changes: 59 additions & 0 deletions Source/RP0/Utilities/LeaderUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using ContractConfigurator;
using RP0.Requirements;
using Strategies;
using System.Collections.Generic;
using System.Linq;

namespace RP0
{
public static class LeaderUtils
{
public static IEnumerable<StrategyConfigRP0> GetLeadersUnlockedByTech(string techID)
{
return GetAllLeaderStrategies()
.Where(s => s.RequirementsBlock != null &&
(s.RequirementsBlock.Op is Any ||
s.RequirementsBlock.Op is All && s.RequirementsBlock.Reqs.Count == 1) &&
s.RequirementsBlock.ChildBlocks.Count == 0 &&
s.RequirementsBlock.Reqs.Any(r => !r.IsInverted &&
r is TechRequirement cr &&
cr.TechName == techID));
}

public static IEnumerable<StrategyConfigRP0> GetLeadersUnlockedByContract(ConfiguredContract cc)
{
return GetAllLeaderStrategies()
.Where(s => s.RequirementsBlock != null &&
(s.RequirementsBlock.Op is Any ||
s.RequirementsBlock.Op is All && s.RequirementsBlock.Reqs.Count == 1) &&
s.RequirementsBlock.ChildBlocks.Count == 0 &&
s.RequirementsBlock.Reqs.Any(r => !r.IsInverted &&
r is Requirements.ContractRequirement cr &&
cr.ContractName == cc.contractType.name));
}

public static IEnumerable<StrategyConfigRP0> GetLeadersUnlockedByProgram(string programName)
{
return GetAllLeaderStrategies()
.Where(s => s.RequirementsBlock != null &&
(s.RequirementsBlock.Op is Any ||
s.RequirementsBlock.Op is All && s.RequirementsBlock.Reqs.Count == 1) &&
s.RequirementsBlock.ChildBlocks.Count == 0 &&
s.RequirementsBlock.Reqs.Any(r => !r.IsInverted &&
r is ProgramRequirement pr &&
pr.ProgramName == programName));
}

public static IEnumerable<StrategyConfigRP0> GetAllUnlockedLeaders()
{
return GetAllLeaderStrategies().Where(s => s.IsUnlocked());
}

private static IEnumerable<StrategyConfigRP0> GetAllLeaderStrategies()
{
return StrategySystem.Instance.SystemConfig.Strategies
.OfType<StrategyConfigRP0>()
.Where(s => s.DepartmentName != "Programs");
}
}
}

0 comments on commit fa96df4

Please sign in to comment.