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); } } } }
private void onVesselLoaded(Vessel vessel) { List <Part> parts = vessel.Parts; float biggestAttachNode = 0.0f; foreach (Part part in parts) { List <AttachNode> attachNodes = part.attachNodes; foreach (AttachNode attachNode in attachNodes) { biggestAttachNode = Math.Max(biggestAttachNode, attachNode.size); } PartModuleList modules = part.Modules; foreach (PartModule module in modules) { string moduleName = module.moduleName; BaseEventList events = module.Events; foreach (BaseEvent kspevent in events) { float unfocusedRangeBuffed = (kspevent.unfocusedRange + biggestAttachNode) * Config.pawRangeCoef; kspevent.unfocusedRange = unfocusedRangeBuffed; } } } }
/// <summary>Re-applies GUI name string from the event attributes.</summary> /// <param name="events">The events to process.</param> static void UpdateStockEvents(BaseEventList events) { var ownerType = events.module != null ? events.module.GetType() : events.part.GetType(); foreach (var kspEvent in events) { var info = ownerType.GetMethod( kspEvent.name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null /* default binder */, new Type[0], null /* no modifiers */); if (info == null) { DebugEx.Error("Cannot get event: {0}.{1}", ownerType.FullName, kspEvent.name); continue; } info = info.GetBaseDefinition(); // Only the base has the right attributes. SetupArgumentFromAttribute( info, typeof(KSPEvent), nameof(KSPEvent.guiName), x => { kspEvent.guiName = x; }); } }
void SetToggleName(BaseEventList pmEvents) { switch (integratedDecoupler) { case DecouplerType.none: pmEvents["ToggleIntegratedDecoupler"].guiName = "No decoupler"; break; case DecouplerType.Enabled: pmEvents["ToggleIntegratedDecoupler"].guiName = "Integrated Decoupler"; break; case DecouplerType.EnabledStagingDisabled: pmEvents["ToggleIntegratedDecoupler"].guiName = "Integrated Decoupler, staging disabled"; break; } }
/// <summary> /// Attempt to set radiator state. Returns true for success, false for failure. /// </summary> /// <param name="part"></param> /// <param name="events"></param> /// <param name="isEnabled"></param> private static bool setRadiatorState(Part part, BaseEventList events, bool isEnabled) { List <ModuleActiveRadiator> radiatorModules = part.Modules.GetModules <ModuleActiveRadiator>(); if (radiatorModules.Count == 0) { Debug.LogWarning("RadiatorToggle: No ModuleActiveRadiator found for " + part.name); events["toggleRadiatorFlightEvent"].active = false; events["toggleRadiatorEditorEvent"].active = false; return(false); } foreach (ModuleActiveRadiator radiatorModule in radiatorModules) { radiatorModule.enabled = isEnabled; } String eventText = isEnabled ? DEACTIVATE_EVENT_TEXT : ACTIVATE_EVENT_TEXT; events["toggleRadiatorFlightEvent"].guiName = eventText; events["toggleRadiatorEditorEvent"].guiName = eventText; return(true); }
// Adding Selfie button private void addSelfie(KerbalEVA evaCtl) { Log.dbg("Adding Selfie to {0}", evaCtl.GUIName); BaseEventList pEvents = evaCtl.Events; BaseEventDelegate slf = new BaseEventDelegate(TakeSelfie); KSPEvent evt = new KSPEvent { active = true, externalToEVAOnly = true, guiActive = true, guiActiveEditor = false, guiActiveUnfocused = false, guiActiveUncommand = false, guiName = "Take Selfie", name = "TakeSelfie" }; BaseEvent selfie = new BaseEvent(pEvents, "Take Selfie", slf, evt); pEvents.Add(selfie); selfie.guiActive = true; selfie.active = true; }
private void reinitEvents(Vessel v) { printDebug("entered"); if (v.evaController == null) { return; } KerbalEVA evaCtl = v.evaController; ProtoCrewMember crew = v.GetVesselCrew() [0]; String kerbalName = crew.name; printDebug("evCtl found; checking name: " + kerbalName); Tourist t; if (!tourists.TryGetValue(kerbalName, out t)) { return; } printDebug("among tourists: " + kerbalName); t.smile = false; t.taken = false; if (!Tourist.isTourist(v.GetVesselCrew()[0])) { printDebug("...but is a crew"); return; // not a real tourist } // Change crew type right away to avoid them being crew after recovery crew.type = ProtoCrewMember.KerbalType.Tourist; BaseEventList pEvents = evaCtl.Events; foreach (BaseEvent e in pEvents) { printDebug("disabling event " + e.guiName); e.guiActive = false; e.guiActiveUnfocused = false; e.guiActiveUncommand = false; } // Adding Selfie button BaseEventDelegate slf = new BaseEventDelegate(TakeSelfie); KSPEvent evt = new KSPEvent(); evt.active = true; evt.externalToEVAOnly = true; evt.guiActive = true; evt.guiActiveEditor = false; evt.guiActiveUnfocused = false; evt.guiActiveUncommand = false; evt.guiName = "Take Selfie"; evt.name = "TakeSelfie"; BaseEvent selfie = new BaseEvent(pEvents, "Take Selfie", slf, evt); pEvents.Add(selfie); selfie.guiActive = true; selfie.active = true; foreach (PartModule m in evaCtl.part.Modules) { if (!m.ClassName.Equals("ModuleScienceExperiment")) { continue; } printDebug("science module id: " + ((ModuleScienceExperiment)m).experimentID); // Disable all science foreach (BaseEvent e in m.Events) { e.guiActive = false; e.guiActiveUnfocused = false; e.guiActiveUncommand = false; } foreach (BaseAction a in m.Actions) { a.active = false; } } printDebug("Initializing sound"); // Should we always invalidate cache??? fx = null; getOrCreateAudio(evaCtl.part.gameObject); }
public WrappedEvent(BaseEvent originalEvent, BaseEventList baseParentList, string name, BaseEventDelegate baseActionDelegate, KSPEvent kspEvent) : base(baseParentList, name, baseActionDelegate, kspEvent) { _originalEvent = originalEvent; }
public static void WrapPartActionEventItem(Part part, Action <BaseEvent, bool> passthrough) { var controller = UIPartActionController.Instance; if (!controller) { return; } // get the part action window corresponding to the part var window = controller.GetItem(part); if (window == null) { return; } // get all the items that makes this window (toggle buttons, sliders, etc.) var partActionItems = window.ListItems; // loop through all of those UI components for (var i = 0; i < partActionItems.Count(); i++) { // check that the part action item is actually a UIPartActionFieldItem (it could be a UIPartActionEventItem) var uiPartActionEventItem = (partActionItems[i] as UIPartActionEventItem); if (uiPartActionEventItem == null) { continue; } // get event from button BaseEvent originalEvent = uiPartActionEventItem.Evt; // Search for the BaseEventDelegate (BaseEvent.onEvent) field defined for the current BaseEvent type. // Note that 'onEvent' is protected, so we have to go through reflection. FieldInfo partEventFieldInfo = typeof(BaseEvent).GetFields(BindingFlags.Instance | BindingFlags.NonPublic) .First(fi => fi.FieldType == typeof(BaseEventDelegate)); // Get the actual value of the 'onEvent' field BaseEventDelegate partEvent = (BaseEventDelegate)partEventFieldInfo.GetValue(originalEvent); // Gets the method represented by the delegate and from this method returns an array of custom attributes applied to this member. // Simply put, we want all [KSPEvent] attributes applied to the BaseEventDelegate.Method field. object[] customAttributes = partEvent.Method.GetCustomAttributes(typeof(KSPEvent), true); // Look for the custom attribute skip_control bool skipControl = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_control")); if (skipControl) { continue; } /* * Override the old BaseEvent with our BaseEvent to the button */ // fix problems with other mods (behavior not seen with KSP) when the customAttributes list is empty. KSPEvent kspEvent = !customAttributes.Any() ? WrappedEvent.KspEventFromBaseEvent(originalEvent) : (KSPEvent)customAttributes[0]; // Look for the custom attribute skip_delay bool ignoreDelay = customAttributes.Any(a => ((KSPEvent)a).category.Contains("skip_delay")); // create the new BaseEvent BaseEvent hookedEvent = EventWrapper.CreateWrapper(originalEvent, passthrough, ignoreDelay, kspEvent); // get the original event index in the event list BaseEventList eventList = originalEvent.listParent; int listIndex = eventList.IndexOf(originalEvent); // remove the original event in the event list and add our hooked event eventList.RemoveAt(listIndex); eventList.Add(hookedEvent); // get the baseEvent field from UIPartActionEventItem (note: this is uiPartActionEventItem.Evt, but we can't set its value...) FieldInfo baseEventField = typeof(UIPartActionEventItem).GetFields(BindingFlags.Instance | BindingFlags.NonPublic) .First(fi => fi.FieldType == typeof(BaseEvent)); // replace the button baseEvent value with our hooked event baseEventField.SetValue(uiPartActionEventItem, hookedEvent); } }
/// <summary> /// Load infos into this object and create a new BaseEvent /// </summary> /// <returns>true - loaded successfull</returns> public override bool Load(ConfigNode n, FlightComputer fc) { if (base.Load(n, fc)) { // deprecated since 1.6.2, we need this for upgrading from 1.6.x => 1.6.2 int PartId = 0; { if (n.HasValue("PartId")) { PartId = int.Parse(n.GetValue("PartId")); } } if (n.HasValue("flightID")) { this.flightID = uint.Parse(n.GetValue("flightID")); } this.Module = n.GetValue("Module"); this.GUIName = n.GetValue("GUIName"); this.Name = n.GetValue("Name"); RTLog.Notify("Try to load an EventCommand from persistent with {0},{1},{2},{3},{4}", PartId, this.flightID, this.Module, this.GUIName, this.Name); Part part = null; var partlist = FlightGlobals.ActiveVessel.parts; if (this.flightID == 0) { // only look with the partid if we've enough parts if (PartId < partlist.Count) { part = partlist.ElementAt(PartId); } } else { part = partlist.Where(p => p.flightID == this.flightID).FirstOrDefault(); } if (part == null) { return(false); } PartModule partmodule = part.Modules[Module]; if (partmodule == null) { return(false); } BaseEventList eventlist = new BaseEventList(part, partmodule); if (eventlist.Count <= 0) { return(false); } this.BaseEvent = eventlist.Where(ba => (ba.GUIName == this.GUIName || ba.name == this.Name)).FirstOrDefault(); return(true); } return(false); }
public override void OnUpdate() { //If there are overrideEvents and we haven't initially processed them do so now (should only run ONCE) if (overrideEvents && !overrideEventsProcessed) { try { foreach (PartModule pm in part.Modules) //should be a shorter way to do this, but a foreach cycle works { if (pm.moduleName == overrideModuleName) { overrideEventList = pm.Events; if (overrideEventNameOpen != "" && !overrideEventList.Contains(overrideEventNameOpen)) { overrideEventNameOpen = ""; overrideEvents = false; } if (overrideEventNameClose != "" && !overrideEventList.Contains(overrideEventNameClose)) { overrideEventNameClose = ""; overrideEvents = false; } break; } } } catch (Exception) { //throw; } overrideEventsProcessed = true; } //If there are disableEvents and we haven't initially processed them do so now (should only run ONCE) if (disableEvents && !disableEventsProcessed) { try { foreach (PartModule pm in part.Modules) //should be a shorter way to do this, but a foreach cycle works { if (pm.moduleName == disableModuleName) { disableEventList = pm.Events; if (disableEventName != "" && !disableEventList.Contains(disableEventName)) { disableEventName = ""; disableEvents = false; } break; } } } catch (Exception) { //throw; } disableEventsProcessed = true; } //Once-OFF if camera active on startup/loading open the camera (moved from OnStart to allow for disable and override events if (activeonStartup) { eventOpenCamera(); activeonStartup = false; } //If there are overrideEvents or disableEvents process them on every OnUpdate in case their partmodule is resetting them. if (overrideEvents || disableEvents) { processOverrideDisableEvents(!Active); } Events["eventReviewScience"].active = _scienceData.Count > 0; if (vessel.targetObject != _lastTarget && vessel.targetObject != null) { targettingMode = TargettingMode.Planet; selectedTargetIndex = -1; _lastTarget = vessel.targetObject; } //if (vessel.targetObject != null) //{ // Utilities.Log_Debug("Vessel target=" + vessel.targetObject.GetTransform().position); //} //if (!_inEditor && _camera.Enabled && windowState != WindowSate.Hidden && vessel.isActiveVessel) //{ //if (_camera.Enabled && f++ % frameLimit == 0) //_camera.draw(); //} }
/// <summary> /// Attempt to set radiator state. Returns true for success, false for failure. /// </summary> /// <param name="part"></param> /// <param name="events"></param> /// <param name="isEnabled"></param> private static bool setRadiatorState(Part part, BaseEventList events, bool isEnabled) { List<ModuleActiveRadiator> radiatorModules = part.Modules.GetModules<ModuleActiveRadiator>(); if (radiatorModules.Count == 0) { Debug.LogWarning("RadiatorToggle: No ModuleActiveRadiator found for " + part.name); events["toggleRadiatorFlightEvent"].active = false; events["toggleRadiatorEditorEvent"].active = false; return false; } foreach (ModuleActiveRadiator radiatorModule in radiatorModules) { radiatorModule.enabled = isEnabled; } String eventText = isEnabled ? DEACTIVATE_EVENT_TEXT : ACTIVATE_EVENT_TEXT; events["toggleRadiatorFlightEvent"].guiName = eventText; events["toggleRadiatorEditorEvent"].guiName = eventText; return true; }
public WrappedEvent(BaseEvent originalEvent, BaseEventList baseParentList, string name, BaseEventDelegate baseActionDelegate) : base(baseParentList, name, baseActionDelegate) { this.originalEvent = originalEvent; }
/// <summary> /// Load infos into this object and create a new BaseEvent /// </summary> /// <returns>true - loaded successfull</returns> public override bool Load(ConfigNode n, FlightComputer fc) { if(base.Load(n, fc)) { // deprecated since 1.6.2, we need this for upgrading from 1.6.x => 1.6.2 int PartId = 0; { if (n.HasValue("PartId")) PartId = int.Parse(n.GetValue("PartId")); } if (n.HasValue("flightID")) this.flightID = uint.Parse(n.GetValue("flightID")); this.Module = n.GetValue("Module"); this.GUIName = n.GetValue("GUIName"); this.Name = n.GetValue("Name"); RTLog.Notify("Try to load an EventCommand from persistent with {0},{1},{2},{3},{4}", PartId, this.flightID, this.Module, this.GUIName, this.Name); Part part = null; var partlist = FlightGlobals.ActiveVessel.parts; if (this.flightID == 0) { // only look with the partid if we've enough parts if (PartId < partlist.Count) part = partlist.ElementAt(PartId); } else { part = partlist.Where(p => p.flightID == this.flightID).FirstOrDefault(); } if (part == null) return false; PartModule partmodule = part.Modules[Module]; if (partmodule == null) return false; BaseEventList eventlist = new BaseEventList(part, partmodule); if (eventlist.Count <= 0) return false; this.BaseEvent = eventlist.Where(ba => (ba.GUIName == this.GUIName || ba.name == this.Name)).FirstOrDefault(); return true; } return false; }