コード例 #1
0
        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);
                    }
                }
            }
        }
コード例 #2
0
        // 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;
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
            }
        }