-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSelection.cs
125 lines (119 loc) · 6.66 KB
/
Selection.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
using System.Collections.Generic;
using System.Linq;
using FormationSorter.Patches;
using FormationSorter.Utilities;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.MountAndBlade;
using TaleWorlds.MountAndBlade.ViewModelCollection.Order;
namespace FormationSorter;
public static class Selection
{
private static List<Formation> previousSelections = new();
internal static void UpdateTroops()
{
if (!Mission.IsCurrentValid())
return;
MissionOrderVM missionOrder = Mission.MissionOrderVM;
OrderController orderController = missionOrder?.OrderController;
MissionOrderTroopControllerVM troopController = missionOrder?.TroopController;
if (orderController is null || troopController is null)
return;
foreach (OrderTroopItemVM troopItem in from formation in Mission.Current.PlayerTeam.FormationsIncludingEmpty
where formation is not null && troopController.TroopList.All(item => item.Formation != formation)
select new OrderTroopItemVM(formation,
i => typeof(MissionOrderTroopControllerVM).GetCachedMethod("OnSelectFormation")
.Invoke(troopController, new object[] { i }),
f => (int)typeof(MissionOrderTroopControllerVM).GetCachedMethod("GetFormationMorale")
.Invoke(troopController, new object[] { f }))
into troopItem
select (OrderTroopItemVM)typeof(MissionOrderTroopControllerVM).GetCachedMethod("AddTroopItemIfNotExist")
.Invoke(troopController, new object[] { troopItem, -1 }))
_ = typeof(MissionOrderTroopControllerVM).GetCachedMethod("SetTroopActiveOrders").Invoke(troopController, new object[] { troopItem });
_ = typeof(MissionOrderTroopControllerVM).GetCachedMethod("SortFormations").Invoke(troopController, new object[] { });
foreach (OrderTroopItemVM troopItem in troopController.TroopList)
{
Formation formation = troopItem.Formation;
troopItem.IsSelectable = orderController.IsFormationSelectable(formation);
if (troopItem.IsSelectable && orderController.IsFormationListening(formation))
troopItem.IsSelected = true;
}
}
public static void SelectFormations(SkinVoiceManager.SkinVoiceType voiceFeedback, IEnumerable<FormationClass> formationClasses = null,
string feedback = null, bool uiFeedback = true)
{
MissionOrderVM missionOrder = Mission.MissionOrderVM;
if (missionOrder is null)
return;
UpdateTroops();
if (!missionOrder.IsToggleOrderShown || !Settings.Instance.InverseSelectKey.IsDefinedAndDown())
previousSelections.Clear();
SetFormationSelections();
formationClasses = formationClasses?.ToHashSet();
List<Formation> selections = formationClasses is null
? new()
: previousSelections.Where(formation => !formation.IsOneOfFormationClasses(formationClasses)).ToList();
Team playerTeam = Mission.Current?.PlayerTeam;
if (playerTeam == null)
return;
List<Formation> invertedSelections = new();
foreach (Formation formation in playerTeam.FormationsIncludingEmpty)
{
if (formation is null)
continue;
bool isCorrectFormation = formationClasses is null || formation.IsOneOfFormationClasses(formationClasses);
bool wasPreviouslySelected = previousSelections.Contains(formation);
bool shouldInvertSelection = Settings.Instance.InverseSelectKey.IsDefinedAndDown() && wasPreviouslySelected;
if (!isCorrectFormation)
continue;
if (shouldInvertSelection)
invertedSelections.Add(formation);
else
selections.Add(formation);
}
if (uiFeedback)
{
if (invertedSelections.Any() || selections.Any(f => f.CountOfUnits > 0))
InformationManager.DisplayMessage(new($"{(invertedSelections.Any() ? "Unselected" : "Selected")} all {feedback}formations", Colors.White,
SubModule.Id));
else
InformationManager.DisplayMessage(new($"There are no troops to be selected in any {feedback}formations", Colors.White, SubModule.Id));
}
PatchInformationManager.SuppressSelectAllFormations = true;
SetFormationSelections(selections);
PatchInformationManager.SuppressSelectAllFormations = false;
previousSelections = selections;
_ = typeof(MissionOrderVM).GetCachedMethod("SetActiveOrders").Invoke(missionOrder, new object[] { });
if (selections.Count == 0 || !Mission.IsOrderShoutingAllowed())
return;
Mission.PlayerAgent.MakeVoice(voiceFeedback, SkinVoiceManager.CombatVoiceNetworkPredictionType.NoPrediction);
}
private static void SetFormationSelections(List<Formation> selections = null)
{
MissionOrderVM missionOrder = Mission.MissionOrderVM;
OrderController orderController = missionOrder?.OrderController;
MissionOrderTroopControllerVM troopController = missionOrder?.TroopController;
if (orderController is null || troopController is null)
return;
orderController.ClearSelectedFormations();
_ = missionOrder.TryCloseToggleOrder();
if (selections?.Any(f => f.CountOfUnits > 0) != true)
return;
missionOrder.OpenToggleOrder(false);
OrderTroopItemVM orderTroopItemVM = GetOrderTroopItemVM(selections.First());
if (orderTroopItemVM is not null)
{
missionOrder.OnSelect(selections.First().Index);
_ = typeof(MissionOrderTroopControllerVM).GetCachedMethod("SetSelectedFormation").Invoke(troopController, new object[] { orderTroopItemVM });
}
for (int i = 1; i <= selections.Count - 1; i++)
{
Formation formation = selections[i];
orderTroopItemVM = GetOrderTroopItemVM(formation);
if (orderTroopItemVM is not null)
_ = typeof(MissionOrderTroopControllerVM).GetCachedMethod("AddSelectedFormation").Invoke(troopController, new object[] { orderTroopItemVM });
}
}
private static OrderTroopItemVM GetOrderTroopItemVM(Formation formation)
=> Mission.MissionOrderVM?.TroopController?.TroopList?.SingleOrDefault(t => t.Formation == formation);
}