/
AdvancedRunHistory.cs
151 lines (141 loc) · 6.94 KB
/
AdvancedRunHistory.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using BepInEx;
using HarmonyLib;
using ShinyShoe;
using BepInEx.Logging;
using AdvancedRunHistory.CustomUIStuff;
using System.Reflection;
using AdvancedRunHistory.Filters;
namespace AdvancedRunHistory
{
/// <summary>
/// The main class of the Advanced Run History mod.
/// </summary>
/// <remarks>
/// This mod aims to add a few options to the Run History screen, which I find to be a bit lacking in the
/// base game. At the moment, it implements the possibility to filter runs so that only runs that fulfill
/// certain criteria are returned by the search function.
/// A downside of this is that the current implementation requires <c>RunAggregateData</c> objects to be
/// instantiated from database entries, which slows down the search process by a bit.
/// Right now, a lot of information like cards, relics, etc. cannot be retrieved from the run data objects
/// during the filtering process. This is because only minimal run data is returned while the game searches
/// for runs. There might be a workaround for this, but it would probably slow down the game significantly.
/// This class itself is only used for logging and holding a few variables that are globally needed.
/// Everything else has been moved to some other place.
/// </remarks>
[BepInPlugin(MOD_ID, MOD_NAME, MOD_VERSION)]
[BepInProcess("MonsterTrain.exe")]
[BepInProcess("MtLinkHandler.exe")]
public class AdvancedRunHistory : BaseUnityPlugin
{
// Just some constants
public const string MOD_ID = "luc.mods.runfilters";
public const string MOD_NAME = "Advanced Run History";
public const string MOD_VERSION = "1.0.2";
private static ManualLogSource logger = BepInEx.Logging.Logger.CreateLogSource(MOD_NAME);
public static FilterManager filterManager = new FilterManager();
public static RunFilterDialog filterDialog;
public static GameUISelectableButton openFilterDialogButton;
public static GameUISelectableToggle applyFiltersToggle;
private void Awake()
{
// Apply patches.
var harmony = new Harmony(MOD_ID);
harmony.PatchAll();
}
/// <summary>
/// Use BepInEx to log stuff.
/// </summary>
/// <param name="message">The message you want to log.</param>
/// <param name="level">The logging level. Default: Debug.</param>
public static void Log(string message, LogLevel level = LogLevel.Debug)
{
logger.Log(level, message);
}
}
/// <summary>
/// This patch adds a few custom UI elements to the Run History screen and initalized the Run Filter dialog.
/// </summary>
[HarmonyPatch(typeof(RunHistoryScreen), "Setup")]
public class RunHistoryUIPatch
{
public static void Postfix(ref RunHistoryScreen __instance, ref SaveManager saveManager)
{
// Only do this if the elements are actually usable
if(CustomUIManager.AreTemplatesUsable())
{
// Add a few UI elements. TODO: Currenty, these are added directly to the screen. It might be nicer to add
// them to the screen's content, but I'm too lazy for it right now.
CustomUIManager.AddLabelToComponent(__instance, "Apply Filters:", 170, 145, 200, 50);
AdvancedRunHistory.applyFiltersToggle = CustomUIManager.AddToggleToComponent(__instance, "ApplyFiltersToggle", 310, 146);
AdvancedRunHistory.applyFiltersToggle.isOn = AdvancedRunHistory.filterManager.Active;
AdvancedRunHistory.openFilterDialogButton = CustomUIManager.AddButtonToComponent(__instance, "OpenFilterScreenButton", "Edit Filters", 570, 140, 250, 60);
// If the Filter dialog has not yet been created, do so. Otherwise, reinitalize it.
if (AdvancedRunHistory.filterDialog == null)
{
AdvancedRunHistory.filterDialog = new RunFilterDialog(__instance, saveManager, AdvancedRunHistory.filterManager);
}
else
{
AdvancedRunHistory.filterDialog.Reinit(__instance);
}
}
else
{
AdvancedRunHistory.Log("At least one UI template has not been initalized successfully", LogLevel.Error);
}
}
}
/// <summary>
/// This patch adds handling for the custom UI elements added to the Run History screen.
/// </summary>
[HarmonyPatch(typeof(RunHistoryScreen), "ApplyScreenInput")]
public class RunHistoryInputPatch
{
public static bool Prefix(ref RunHistoryScreen __instance, ref bool __result, ref CoreInputControlMapping mapping, ref IGameUIComponent triggeredUI, ref InputManager.Controls triggeredMappingID)
{
// If the filter dialog is null, abort.
if(AdvancedRunHistory.filterDialog == null)
{
AdvancedRunHistory.Log("Filter dialog does not seem to have initalized successfully.", LogLevel.Warning);
return true;
}
// If the filter dialog is open, handle it first.
if(AdvancedRunHistory.filterDialog.IsActive())
{
if(AdvancedRunHistory.filterDialog.ApplyScreenInput(mapping, triggeredUI, triggeredMappingID))
{
__result = true;
}
// If one of the filters was changed, re-fetch runs.
if (AdvancedRunHistory.filterDialog.WasUpdated() && AdvancedRunHistory.filterManager.Active)
{
UpdateHistoryUI(__instance);
}
return false;
}
// "Edit Filters" button clicked: Open the filter dialog.
if(AdvancedRunHistory.openFilterDialogButton.TryTrigger(triggeredUI, triggeredMappingID))
{
AdvancedRunHistory.filterDialog.Open();
__result = true;
return false;
}
// "Apply Filters" toggle clicked: Toggle the filter manager's active state and re-fetch runs.
if(AdvancedRunHistory.applyFiltersToggle.TryTrigger(triggeredUI, triggeredMappingID))
{
AdvancedRunHistory.filterManager.Active = AdvancedRunHistory.applyFiltersToggle.Toggle();
UpdateHistoryUI(__instance);
return false;
}
// If nothing else has been found, run the original method.
return true;
}
// A quick method to make the Run History UI re-fetch runs.
private static void UpdateHistoryUI(RunHistoryScreen screen)
{
RunHistoryUI ui = Traverse.Create(screen).Field("runHistoryUI").GetValue<RunHistoryUI>();
MethodInfo fetch = ui.GetType().GetMethod("FetchGameRuns", BindingFlags.NonPublic | BindingFlags.Instance);
fetch.Invoke(ui, new object[] { 1 });
}
}
}