Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 45 additions & 23 deletions src/RemoteTech/FlightComputer/UIPartActionMenuPatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,56 @@ public static class UIPartActionMenuPatcher
{
public static void Wrap(Vessel parent, Action<BaseEvent, bool> pass)
{
var controller = UIPartActionController.Instance;
UIPartActionController controller = UIPartActionController.Instance;
if (!controller) return;
var listFieldInfo = controller.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(List<UIPartActionWindow>));

var list = (List<UIPartActionWindow>)listFieldInfo.GetValue(controller);
foreach (var window in list.Where(l => l.part.vessel == parent))
// Get the open context menus
FieldInfo listFieldInfo = controller.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(List<UIPartActionWindow>));

List<UIPartActionWindow> openWindows = (List<UIPartActionWindow>)listFieldInfo.GetValue(controller);

foreach (UIPartActionWindow window in openWindows.Where(l => l.part.vessel == parent))
{
var itemsFieldInfo = window.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(List<UIPartActionItem>));
// Get the list of all UIPartActionItem's
FieldInfo itemsFieldInfo = typeof(UIPartActionWindow).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(List<UIPartActionItem>));

List<UIPartActionItem> item = (List<UIPartActionItem>)itemsFieldInfo.GetValue(window);
// We only need the UIPartActionEventItem's
IEnumerable<UIPartActionItem> actionEventButtons = item.Where(l => (l as UIPartActionEventItem) != null);

var item = (List<UIPartActionItem>)itemsFieldInfo.GetValue(window);
foreach (var it in item)
foreach (UIPartActionEventItem button in actionEventButtons)
{
var button = it as UIPartActionEventItem;
if (button != null)
BaseEvent originalEvent = button.Evt;
// Get the BaseEventDelegate object from the button
FieldInfo partEventFieldInfo = typeof(BaseEvent).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(BaseEventDelegate));

BaseEventDelegate partEvent = (BaseEventDelegate)partEventFieldInfo.GetValue(originalEvent);
object[] customAttributes = partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true);

// Look for the custom attribute skip_control
bool skip_control = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_control"));

if (!skip_control)
{
var partEventFieldInfo = button.Evt.GetType().GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(BaseEventDelegate));

var partEvent = (BaseEventDelegate)partEventFieldInfo.GetValue(button.Evt);
if (!partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true).Any(a => ((KSPEvent)a).category.Contains("skip_control")))
{
bool ignore_delay = partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true).Any(a => ((KSPEvent)a).category.Contains("skip_delay"));
var eventField = typeof(UIPartActionEventItem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(BaseEvent));
eventField.SetValue(button, Wrapper.CreateWrapper(button.Evt, pass, ignore_delay));
}
// Look for the custom attribute skip_delay
bool ignore_delay = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_delay"));

// Override the old BaseEvent with our BaseEvent to the button
FieldInfo eventField = typeof(UIPartActionEventItem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
.First(fi => fi.FieldType == typeof(BaseEvent));

BaseEventList eventList = originalEvent.listParent;
int listIndex = eventList.IndexOf(originalEvent);

// create the new BaseEvent
BaseEvent hookedEvent = Wrapper.CreateWrapper(originalEvent, pass, ignore_delay);
eventList.RemoveAt(listIndex);
eventList.Add(hookedEvent);

eventField.SetValue(button, hookedEvent);
}
}
}
Expand Down Expand Up @@ -66,7 +88,7 @@ public static BaseEvent CreateWrapper(BaseEvent original, Action<BaseEvent, bool
return new_event;
}

[KSPEvent(category="skip_control")]
[KSPEvent(category = "skip_control")]
public void Invoke()
{
mPassthrough.Invoke(mEvent, mIgnoreDelay);
Expand Down
9 changes: 8 additions & 1 deletion src/RemoteTech/Modules/ModuleSPU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ public override void OnStart(StartState state)
{
GameEvents.onVesselWasModified.Add(OnVesselModified);
GameEvents.onPartUndock.Add(OnPartUndock);
GameEvents.onPartActionUICreate.Add(onPartActionUICreate);
mRegisteredId = vessel.id;
RTCore.Instance.Satellites.Register(vessel, this);
if (FlightComputer == null)
Expand All @@ -86,11 +87,17 @@ public override void OnStart(StartState state)
Fields["GUI_Status"].guiActive = ShowGUI_Status;
}

public void onPartActionUICreate(Part p)
{
HookPartMenus();
}

public void OnDestroy()
{
RTLog.Notify("ModuleSPU: OnDestroy");
GameEvents.onVesselWasModified.Remove(OnVesselModified);
GameEvents.onPartUndock.Remove(OnPartUndock);
GameEvents.onPartActionUICreate.Remove(onPartActionUICreate);
if (RTCore.Instance != null)
{
RTCore.Instance.Satellites.Unregister(mRegisteredId, this);
Expand Down Expand Up @@ -127,7 +134,7 @@ public void Update()
public void FixedUpdate()
{
if (FlightComputer != null) FlightComputer.OnFixedUpdate();
HookPartMenus();

switch (UpdateControlState())
{
case State.Operational:
Expand Down