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
        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;
                    }
                }
            }
        }
示例#3
0
        /// <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;
                });
            }
        }
示例#4
0
        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;
            }
        }
示例#5
0
        /// <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;
        }
示例#7
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);
        }
示例#8
0
 public WrappedEvent(BaseEvent originalEvent, BaseEventList baseParentList, string name, BaseEventDelegate baseActionDelegate, KSPEvent kspEvent)
     : base(baseParentList, name, baseActionDelegate, kspEvent)
 {
     _originalEvent = originalEvent;
 }
示例#9
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);
            }
        }
示例#10
0
        /// <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;
 }
示例#14
0
        /// <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 WrappedEvent(BaseEvent originalEvent, BaseEventList baseParentList, string name, BaseEventDelegate baseActionDelegate, KSPEvent kspEvent)
     : base(baseParentList, name, baseActionDelegate, kspEvent)
 {
     _originalEvent = originalEvent;
 }
示例#16
0
 public WrappedEvent(BaseEvent originalEvent, BaseEventList baseParentList, string name, BaseEventDelegate baseActionDelegate)
     : base(baseParentList, name, baseActionDelegate)
 {
     this.originalEvent = originalEvent;
 }