/// <summary> /// Find the UIPartActionWindow for a part. Usually this is useful just to mark it as dirty. /// </summary> public static UIPartActionWindow FindActionWindow(this Part part) { if (part == null) return null; // We need to do quite a bit of piss-farting about with reflection to // dig the thing out. We could just use Object.Find, but that requires hitting a heap more objects. UIPartActionController controller = UIPartActionController.Instance; if (controller == null) return null; if (windowListField == null) { Type cntrType = typeof(UIPartActionController); foreach (FieldInfo info in cntrType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) { if (info.FieldType == typeof(List<UIPartActionWindow>)) { windowListField = info; goto foundField; } } Debug.LogWarning("*PartUtils* Unable to find UIPartActionWindow list"); return null; } foundField: List<UIPartActionWindow> uiPartActionWindows = (List<UIPartActionWindow>) windowListField.GetValue(controller); if (uiPartActionWindows == null) return null; return uiPartActionWindows.FirstOrDefault(window => window != null && window.part == part); }
public static void Wrap(Vessel parent, Action <BaseEvent, bool> pass) { UIPartActionController controller = UIPartActionController.Instance; if (!controller) { return; } // 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)) { // 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); foreach (UIPartActionEventItem button in actionEventButtons) { 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) { // 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); } } } }
/// <summary> /// Find the UIPartActionWindow for a part. Usually this is useful just to mark it as dirty. /// </summary> public static UIPartActionWindow FindActionWindow(this Part part) { if (part == null) { return(null); } // We need to do quite a bit of reflection to dig the thing out. // We could just use Object.Find, but that requires hitting a heap more objects. UIPartActionController controller = UIPartActionController.Instance; if (controller == null) { return(null); } //initialize the window list if (windowListField == null) { Type controllerType = typeof(UIPartActionController); foreach (FieldInfo info in controllerType.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)) { if (info.FieldType == typeof(List <UIPartActionWindow>)) { windowListField = info; break; } } if (windowListField == null) { Debug.LogWarning("*PartExtentions* Unable to find UIPartActionWindow list"); return(null); } } //get the list if UIPartActionWindows List <UIPartActionWindow> uiPartActionWindows = (List <UIPartActionWindow>)windowListField.GetValue(controller); if (uiPartActionWindows == null) { return(null); } //find and return the right partactionwindow for (int i = uiPartActionWindows.Count - 1; i >= 0; i--) { if ((uiPartActionWindows[i] != null) && (uiPartActionWindows[i].part == part)) { return(uiPartActionWindows[i]); } } return(null); }
public static Part GetPartUnderCursor() { RaycastHit hit; Part part = null; Camera cam = null; if (HighLogic.LoadedSceneIsEditor) { cam = EditorLogic.fetch.editorCamera; } if (HighLogic.LoadedSceneIsFlight) { cam = FlightCamera.fetch.mainCamera; } if (Physics.Raycast(cam.ScreenPointToRay(Input.mousePosition), out hit, 1000, 557059)) { //part = hit.transform.gameObject.GetComponent<Part>(); part = (Part)UIPartActionController.GetComponentUpwards("Part", hit.collider.gameObject); } return(part); }
public void UpdateHoverDetect() { if (isRunning) { //Cast ray Ray ray = FlightCamera.fetch.mainCamera.ScreenPointToRay(Input.mousePosition); if (!Physics.Raycast(ray, out hit, 500, 557059)) { pointerTarget = PointerTarget.Nothing; ResetMouseOver(); return; } // Check target type Part tgtPart = null; KerbalEVA tgtKerbalEva = null; AttachNode tgtAttachNode = null; if (hit.rigidbody) { tgtPart = hit.rigidbody.GetComponent <Part>(); } if (!tgtPart) { tgtPart = (Part)UIPartActionController.GetComponentUpwards("Part", hit.collider.gameObject); } if (!tgtPart) { // check linked part KIS_LinkedPart linkedObject = hit.collider.gameObject.GetComponent <KIS_LinkedPart>(); if (linkedObject) { tgtPart = linkedObject.part; } } if (tgtPart) { tgtKerbalEva = tgtPart.GetComponent <KerbalEVA>(); } // If rigidbody if (hit.rigidbody && !tgtPart && !tgtKerbalEva) { pointerTarget = PointerTarget.StaticRb; } // If kerbal if (tgtKerbalEva) { pointerTarget = PointerTarget.KerbalEva; } // If part if (tgtPart && !tgtKerbalEva) { float currentDist = Mathf.Infinity; foreach (AttachNode an in tgtPart.attachNodes) { if (an.icon) { float dist; if (an.icon.renderer.bounds.IntersectRay(FlightCamera.fetch.mainCamera.ScreenPointToRay(Input.mousePosition), out dist)) { if (dist < currentDist) { tgtAttachNode = an; currentDist = dist; } } } } if (tgtAttachNode != null) { if (tgtAttachNode.icon.name == "KISMount") { pointerTarget = PointerTarget.PartMount; } else { pointerTarget = PointerTarget.PartNode; } } else { pointerTarget = PointerTarget.Part; } } //if nothing if (!hit.rigidbody && !tgtPart && !tgtKerbalEva) { pointerTarget = PointerTarget.Static; } if (tgtPart) { if (tgtAttachNode != null) { // OnMouseEnter node if (tgtAttachNode != hoveredNode) { if (hoveredNode != null) { OnMouseExitNode(hoveredNode); } OnMouseEnterNode(tgtAttachNode); hoveredNode = tgtAttachNode; } } else { // OnMouseExit node if (tgtAttachNode != hoveredNode) { OnMouseExitNode(hoveredNode); hoveredNode = null; } } // OnMouseEnter part if (tgtPart != hoveredPart) { if (hoveredPart) { OnMouseExitPart(hoveredPart); } OnMouseEnterPart(tgtPart); hoveredPart = tgtPart; } } else { // OnMouseExit part if (tgtPart != hoveredPart) { OnMouseExitPart(hoveredPart); hoveredPart = null; } } } }