public void Start() { if (!EditorExtensions.validVersion) { return; } //log = new Log(this.GetType().Name); Log.Debug("Start"); // var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_offset_tweak"); var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); KFSMStateChange hookOffsetUpdateFn = (from) => { var p = EditorLogic.SelectedPart; var parent = p.parent; var symCount = p.symmetryCounterparts.Count; //var attachNode = Refl.GetValue(EditorLogic.fetch, "\u001B\u0002"); //var attachNode = Refl.GetValue(EditorLogic.fetch, "symUpdateAttachNode"); var symUpdateAttachNode = Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.SYMUPDATEATTACHNODE); //public static GizmoOffset Attach(Transform host, Quaternion rotOffset, Callback<Vector3> onMove, Callback<Vector3> onMoved, Camera refCamera = null); Quaternion rotOffset = p.attRotation; gizmo = GizmoOffset.Attach(EditorLogic.SelectedPart.transform, rotOffset, new Callback <Vector3>((offset) => { p.transform.position = gizmo.transform.position; p.attPos = p.transform.localPosition - p.attPos0; Log.Info("symCount: " + symCount.ToString()); if (symCount != 0) { // Refl.Invoke(EditorLogic.fetch, "UpdateSymmetry", p, symCount, parent, symUpdateAttachNode); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.UPDATESYMMETRY, p, symCount, parent, symUpdateAttachNode); } GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffsetting, EditorLogic.SelectedPart); }), new Callback <Vector3>((offset) => { //Refl.Invoke(EditorLogic.fetch, "onOffsetGizmoUpdated", offset); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.ONOFFSETGIZMOUPDATED, offset); }), EditorLogic.fetch.editorCamera); //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "\u0012")).Detach(); //Refl.SetValue(EditorLogic.fetch, "\u0012", gizmo); //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "gizmoOffset")).Detach(); ((GizmoOffset)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET)).Detach(); //Refl.SetValue(EditorLogic.fetch, "gizmoOffset", gizmo); Refl.SetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET, gizmo); }; st_offset_tweak.OnEnter += hookOffsetUpdateFn; OnCleanup += () => { st_offset_tweak.OnEnter -= hookOffsetUpdateFn; }; Log.Debug("Installed."); }
/** * The stock root selection has two states: * - st_root_unselected: Active after switching to root mode. Waits for mouse up, picks part and sets SelectedPart. * - st_root_select: The state after the first click. * * Skip straight to st_root state by adding an event to st_root_unselected with * always true condition that sets up SelectedPart and transitions to st_root. * * Needs to run after EditorLogic#Start() so the states are initialized. */ public void Start() { Instance = this; if (!EditorExtensions.validVersion) { return; } //if (!EditorExtensions.Instance.ReRootActive || !EditorExtensions.Instance.cfg.ReRootEnabled) // return; //log = new Log(this.GetType().Name); Log.Info("SelectRoot2 Start"); // Oh god, so much dirty reflection. Please don't sue me, Squad :( //KerbalFSM editorFSM = (KerbalFSM)Refl.GetValue(EditorLogic.fetch, "\u0001"); // Skip first click in root selection mode: KFSMEvent skipFirstClickEvent = new KFSMEvent("SelectRoot2_skipFirstClickEvent"); skipFirstClickEvent.OnCheckCondition = (state) => { // Um about that always true condition... There is a funny sound glitch // if the root part doesn't have any ROOTABLE children so check for that. // Thanks Kerbas_ad_astra, http://forum.kerbalspaceprogram.com/threads/43208?p=1948755#post1948755 return(EditorReRootUtil.GetRootCandidates(EditorLogic.RootPart.GetComponentsInChildren <Part>()).Any()); }; skipFirstClickEvent.OnEvent = () => { //Refl.SetValue(EditorLogic.fetch, "selectedPart", EditorLogic.RootPart); // SelectedPart Refl.SetValue(EditorLogic.fetch, EditorExtensions.c.SELECTEDPART, EditorLogic.RootPart); // SelectedPart }; //KFSMState st_root_select = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_root_select"); KFSMState st_root_select = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_ROOT_SELECT); skipFirstClickEvent.GoToStateOnEvent = st_root_select; //KFSMState st_root_unselected = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_root_unselected"); KFSMState st_root_unselected = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_ROOT_UNSELECTED); InjectEvent(st_root_unselected, skipFirstClickEvent); // Fix ability to select if already hovering: KFSMStateChange fixAlreadyHoveringPartFn = (from) => { Part partUnderCursor = GetPartUnderCursor(); var selectors = EditorLogic.SortedShipList; //EditorLogic.fetch.Lock (true, true, true, "SelectRoot2"); var selectorUnderCursor = selectors.Find(x => (Part)x == partUnderCursor); if (selectorUnderCursor) { // Refl.Invoke(selectorUnderCursor, "OnMouseIsOver"); Refl.Invoke(selectorUnderCursor, EditorExtensions.c.ONMOUSEISOVER); } }; st_root_select.OnEnter += fixAlreadyHoveringPartFn; OnCleanup += () => { st_root_select.OnEnter -= fixAlreadyHoveringPartFn; }; // Provide a more meaningful message after our changes: KFSMStateChange postNewMessageFn = (from) => { //var template = (ScreenMessage)Refl.GetValue(EditorLogic.fetch, "modeMsg"); var template = (ScreenMessage)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.MODEMSG); ScreenMessages.PostScreenMessage("Select a new root part", template); }; st_root_select.OnEnter += postNewMessageFn; OnCleanup += () => { st_root_select.OnEnter -= postNewMessageFn; }; // Drop the new root part after selection: KFSMEvent dropNewRootPartEvent = new KFSMEvent("SelectRoot2_dropNewRootPartEvent"); dropNewRootPartEvent.OnCheckCondition = (state) => { return(EditorLogic.fetch.lastEventName.Equals("on_rootSelect")); }; dropNewRootPartEvent.OnEvent = () => { // Normally the backup is triggered in on_partDropped#OnCheckCondition() // But we skip that, so do backup here instead. EditorLogic.fetch.SetBackup(); // Normally triggered in on_partDropped#OnEvent(). GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartDropped, EditorLogic.SelectedPart); //var template = (ScreenMessage)Refl.GetValue(EditorLogic.fetch, "modeMsg"); var template = (ScreenMessage)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.MODEMSG); //ScreenMessages.PostScreenMessage(String.Empty, template); if (template != null) { ScreenMessages.PostScreenMessage("New Root selected and dropped", template); } else { ScreenMessages.PostScreenMessage("New Root selected and dropped"); } EditorLogic.SelectedPart.gameObject.SetLayerRecursive(0, 1 << 21); #if false Part[] parts = EditorLogic.RootPart.GetComponentsInChildren <Part>(); foreach (var p in parts) { Log.Info(p.ToString() + "p.enabled: " + p.enabled.ToString()); //Log.Info(p.ToString() + "p.frozen: " + p.active .ToString()); } #endif //EditorLogic.fetch.Unlock("SelectRoot2"); }; // problem is with the following line //KFSMState st_idle = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_idle"); KFSMState st_idle = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_IDLE); dropNewRootPartEvent.GoToStateOnEvent = st_idle; //KFSMState st_place = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_place"); KFSMState st_place = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_PLACE); InjectEvent(st_place, dropNewRootPartEvent); Log.Info("Setup complete.."); }
public void Start() { Instance = this; if (!EditorExtensions.validVersion) { return; } //log = new Log(this.GetType().Name); Log.trace("FreeOffsetBehaviour.Start"); // var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, "st_offset_tweak"); var st_offset_tweak = (KFSMState)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.ST_OFFSET_TWEAK); KFSMStateChange hookOffsetUpdateFn = (from) => { var p = EditorLogic.SelectedPart; if (p != null && p.GetType() == typeof(CompoundPart)) { return; } p.onEditorStartTweak(); var parent = p.parent; var symCount = p.symmetryCounterparts.Count; //var attachNode = Refl.GetValue(EditorLogic.fetch, "\u001B\u0002"); //var attachNode = Refl.GetValue(EditorLogic.fetch, "symUpdateAttachNode"); var symUpdateAttachNode = Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.SYMUPDATEATTACHNODE); //public static GizmoOffset Attach(Transform host, Quaternion rotOffset, Callback<Vector3> onMove, Callback<Vector3> onMoved, Camera refCamera = null); Quaternion rotOffset = p.attRotation; // this.gizmoOffset = GizmoOffset.Attach(this.selectedPart.transform, // new Callback<Vector3>(this.onOffsetGizmoUpdate), // new Callback<Vector3>(this.onOffsetGizmoUpdated), // this.editorCamera); // this.audioSource.PlayOneShot(this.tweakGrabClip); // gizmoRotate = (GizmoRotate)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOROTATE); gizmoOffset = GizmoOffset.Attach(EditorLogic.SelectedPart.transform, rotOffset, new Callback <Vector3>((offset) => { if (gizmoOffset.CoordSpace == Space.Self) { gizmoOffset.transform.rotation = p.transform.rotation; } else { gizmoOffset.transform.rotation = Quaternion.identity; } p.transform.position = gizmoOffset.transform.position; p.attPos = p.transform.localPosition - p.attPos0; Log.detail("symCount: {0}", symCount); if (symCount != 0) { // Refl.Invoke(EditorLogic.fetch, "UpdateSymmetry", p, symCount, parent, symUpdateAttachNode); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.UPDATESYMMETRY, p, symCount, parent, symUpdateAttachNode); } GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffsetting, EditorLogic.SelectedPart); }), new Callback <Vector3>((offset) => { //Refl.Invoke(EditorLogic.fetch, "onOffsetGizmoUpdated", offset); Refl.Invoke(EditorLogic.fetch, EditorExtensions.c.ONOFFSETGIZMOUPDATED, offset); }), EditorLogic.fetch.editorCamera); //((GizmoOffset)Refl.GetValue(EditorLogic.fetch, "gizmoOffset")).Detach(); ((GizmoOffset)Refl.GetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET)).Detach(); //Refl.SetValue(EditorLogic.fetch, "gizmoOffset", gizmo); Refl.SetValue(EditorLogic.fetch, EditorExtensions.c.GIZMOOFFSET, gizmoOffset); }; st_offset_tweak.OnEnter += hookOffsetUpdateFn; OnCleanup += () => { st_offset_tweak.OnEnter -= hookOffsetUpdateFn; }; Log.dbg("Installed."); }