示例#1
0
        public static void SetWorldPosition(CompoundPart part, Vector3 newPosition, bool targetSelected)
        {
            bool    targetActive  = IsTargetActive(part, targetSelected);
            Vector3 localPosition = part.transform.InverseTransformPoint(newPosition);

            if (targetActive)
            {
                SetTargetPosition(part, newPosition);
            }
            else
            {
                part.transform.position = newPosition;
            }

            UpdateEditorGizmo(part, targetActive);
            GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffset, part);

            if (part.symMethod == SymmetryMethod.Mirror)
            {
                UpdateMirrorSymmetryCounterpartsPosition(part, targetActive);
            }
            else if (part.symMethod == SymmetryMethod.Radial)
            {
                UpdateRadialSymmetryCounterpartsPosition(part, localPosition, targetActive);
            }

            EditorLogic.fetch.SetBackup();
        }
        public static bool PartIsStrutOrFuelLine(CompoundPart part, bool techRequired = true)
        {
            if (part == null || !HighLogic.CurrentGame.Parameters.CustomParams <KLFCustomParams2>().allowStrutFuelFailures)
            {
                return(false);
            }
            if (HighLogic.CurrentGame.Mode != Game.Modes.SANDBOX && !techRequired)
            {
                ProtoTechNode techNode = ResearchAndDevelopment.Instance.GetTechState(part.partInfo.TechRequired);
                if (techNode != null && techNode.state == RDTech.State.Available)
                {
                    return(false);
                }
            }

            if (part.name != "fuelLine" && part.name != "strutConnector")
            {
                return(false);
            }
            if (part.attachState == CompoundPart.AttachState.Detached || part.attachState == CompoundPart.AttachState.Attaching)
            {
                return(false);
            }
            if (part.target == part.parent)
            {
                return(false);
            }
            return(true);
        }
示例#3
0
        private static void RotateRadialSymmetryCounterparts(CompoundPart part, Vector3 eulerAngles, Space space, bool targetActive)
        {
            if (space == Space.World)
            {
                if (targetActive)
                {
                    CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
                    eulerAngles = module.targetAnchor.InverseTransformDirection(eulerAngles);
                }
                else
                {
                    eulerAngles = part.transform.InverseTransformDirection(eulerAngles);
                }
            }

            foreach (CompoundPart symmetryCounterpart in part.symmetryCounterparts)
            {
                if (targetActive)
                {
                    RotateTarget(symmetryCounterpart, eulerAngles, Space.Self);
                }
                else
                {
                    symmetryCounterpart.transform.Rotate(eulerAngles, Space.Self);
                    symmetryCounterpart.onEditorEndTweak();
                }

                UpdateEditorGizmo(symmetryCounterpart, targetActive);
                GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartRotated, symmetryCounterpart);
            }
        }
示例#4
0
        private static void UpdateMirrorSymmetryCounterpartsPosition(CompoundPart part, bool targetActive)
        {
            Vector3 mirrorPosition;

            if (targetActive)
            {
                Vector3 targetPosition = PartUtil.GetPosition(part, Space.World, targetActive);
                mirrorPosition = MirrorPosition(targetPosition);
            }
            else
            {
                mirrorPosition = MirrorPosition(part.transform.position);
            }

            foreach (CompoundPart symmetryCounterpart in part.symmetryCounterparts)
            {
                if (targetActive)
                {
                    SetTargetPosition(symmetryCounterpart, mirrorPosition);
                }
                else
                {
                    symmetryCounterpart.transform.position = mirrorPosition;
                }
                UpdateEditorGizmo(symmetryCounterpart, targetActive);
                GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffset, symmetryCounterpart);
            }
        }
 public override void OnStart(PartModule.StartState state)
 {
     if (state != StartState.Editor)
     {
         cPart = GetComponent <CompoundPart>();
     }
 }
示例#6
0
        public static Vector3 GetPosition(Part part, Space space, bool compoundTargetSelected)
        {
            bool         targetActive = IsTargetActive(part, compoundTargetSelected);
            CompoundPart compoundPart = null;

            if (targetActive)
            {
                compoundPart = (CompoundPart)part;
            }

            if (space == Space.Self)
            {
                if (targetActive)
                {
                    Vector3 worldPosition = compoundPart.transform.TransformPoint(compoundPart.targetPosition);
                    return((compoundPart.parent != null) ? compoundPart.parent.transform.InverseTransformPoint(worldPosition) : worldPosition);
                }
                else
                {
                    return(part.transform.localPosition);
                }
            }
            else
            {
                if (targetActive)
                {
                    return(compoundPart.transform.TransformPoint(compoundPart.targetPosition));
                }
                else
                {
                    return(part.transform.position);
                }
            }
        }
示例#7
0
        public static Quaternion GetRotation(Part part, Space space, bool compoundTargetSelected)
        {
            bool         targetActive = IsTargetActive(part, compoundTargetSelected);
            CompoundPart compoundPart = null;

            if (targetActive)
            {
                compoundPart = (CompoundPart)part;
            }

            if (space == Space.Self)
            {
                if (targetActive)
                {
                    return(compoundPart.transform.localRotation * compoundPart.targetRotation);
                }
                else
                {
                    return(part.transform.localRotation);
                }
            }
            else
            {
                if (targetActive)
                {
                    return(compoundPart.transform.rotation * compoundPart.targetRotation);
                }
                else
                {
                    return(part.transform.rotation);
                }
            }
        }
 public CompoundPartGeoUpdater(CompoundPart part, GeometryPartModule geoModule)
 {
     this.part = part;
     this.geoModule = geoModule;
     lastAttachState = part.attachState;
     lastTarget = part.target;
 }
 public CompoundPartGeoUpdater(CompoundPart part, GeometryPartModule geoModule)
 {
     this.part       = part;
     this.geoModule  = geoModule;
     lastAttachState = part.attachState;
     lastTarget      = part.target;
 }
示例#10
0
        public static void Rotate(CompoundPart part, Vector3 eulerAngles, Space space, bool targetSelected)
        {
            bool targetActive = IsTargetActive(part, targetSelected);

            CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
            if (targetActive)
            {
                RotateTarget(part, eulerAngles, space);
            }
            else
            {
                part.transform.Rotate(eulerAngles, space);
                part.onEditorEndTweak();
            }
            UpdateEditorGizmo(part, targetActive);
            GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartRotated, part);

            if (part.symMethod == SymmetryMethod.Mirror)
            {
                RotateMirrorSymmetryCounterparts(part, eulerAngles, space, targetActive);
            }
            else if (part.symMethod == SymmetryMethod.Radial)
            {
                RotateRadialSymmetryCounterparts(part, eulerAngles, space, targetActive);
            }

            EditorLogic.fetch.SetBackup();
        }
        public override void OnStart(PartModule.StartState state)
        {
            if (state != StartState.Editor)
            {
                cPart = GetComponent<CompoundPart>();

            }
        }
        private void ToggleCompound()
        {
            CompoundPart compoundPart = (CompoundPart)part;

            if (compoundTargetSelected || compoundPart.target != null)
            {
                compoundTargetSelected = !compoundTargetSelected;
            }
            SaveCfgValue("ANCHOR", compoundTargetSelected ? "target" : "source");
        }
示例#13
0
        private static void RotateTarget(CompoundPart part, Vector3 axis, float angle, Space space)
        {
            CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
            bool oldTweakingTarget = module.TweakingTarget;

            module.TweakingTarget = true;
            module.targetAnchor.Rotate(axis, angle, space);
            module.targetAnchor.hasChanged = true;
            module.OnTargetUpdate();
            module.TweakingTarget = oldTweakingTarget;
        }
示例#14
0
        private static void SetTargetPosition(CompoundPart part, Vector3 position)
        {
            CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
            bool oldTweakingTarget = module.TweakingTarget;

            module.TweakingTarget          = true;
            module.targetAnchor.position   = position;
            module.targetAnchor.hasChanged = true;
            module.OnTargetUpdate();
            module.TweakingTarget = oldTweakingTarget;
        }
示例#15
0
        static void RepositionPart(CompoundPart part, Part startPart, Vector3 startPosition, Vector3 destPosition)
        {
            part.transform.position = startPosition;
            part.transform.up       = startPart.transform.up;
            part.transform.forward  = startPart.transform.forward;
            part.transform.LookAt(destPosition);             //this rotates the strut base towards the target, need to keep it flush with the parent
            part.transform.Rotate(0, 90, 0);

            Vector3 localDirToTarget = part.transform.InverseTransformDirection((destPosition - startPosition).normalized);

            Log.Debug("final direction: " + localDirToTarget.ToString());

            part.raycastTarget(localDirToTarget);
        }
示例#16
0
        void AlignCompoundPart(CompoundPart part, bool snapHeights)
        {
            if (part.target != null && part.parent != null)
            {
                CompoundPartUtil.AlignCompoundPart(part, snapHeights);

                List <Part> symParts = part.symmetryCounterparts;
                //move any symmetry siblings/counterparts
                foreach (CompoundPart symPart in symParts)
                {
                    CompoundPartUtil.AlignCompoundPart(symPart, snapHeights);
                }
                AddUndo();
            }
        }
示例#17
0
 private void PartLinked(CompoundPart cpart)
 {
     if (cpart.target != null)
     {
         Log("Compound part target: " + cpart.target.name + ", mission ID: " + cpart.target.missionID.ToString() + ", part mid: " + cpart.missionID);
         if (cpart.target.missionID != cpart.missionID)
         {
             cpart.missionID = cpart.target.missionID;
             Log("Fixed mission ID for vessel: " + cpart.vessel.GetDisplayName() + " and part: " + cpart.name, LogLevel.INFO);
         }
     }
     else
     {
         Log("CompoundPart Linked: " + cpart.name + " - no target");
     }
 }
示例#18
0
        void CompoundPartAttachStateSorter(CompoundPart part, List <Part> attached, List <Part> notAttached)
        {
            if (part.attachState == CompoundPart.AttachState.Detached || part.attachState == CompoundPart.AttachState.Attaching)
            {
                notAttached.Add(part);
                return;
            }

            if (part.target == part.parent)
            {
                notAttached.Add(part);
                return;
            }

            attached.Add(part);
        }
        void CompoundPartInfo(CompoundPart part)
        {
            AddLabel("name", part.name);
            AddLabel("direction", part.direction.ToString(vectFormat));
            AddLabel("position", part.transform.position.ToString(vectFormat));
            AddLabel("localPosition", part.transform.localPosition.ToString(vectFormat));
            AddLabel("maxLength", part.maxLength.ToString("F3"));
            AddLabel("attachState", part.attachState.ToString());

            if (part.target != null)
            {
                AddLabel("target", part.target.name);
                AddLabel("targetPosition", part.targetPosition.ToString(vectFormat));
                AddLabel("targetRotation", part.targetRotation.ToString(vectFormat));
            }
        }
示例#20
0
 private static void UpdateRadialSymmetryCounterpartsPosition(CompoundPart part, Vector3 localPosition, bool targetActive)
 {
     foreach (CompoundPart symmetryCounterpart in part.symmetryCounterparts)
     {
         if (targetActive)
         {
             Vector3 newPosition = symmetryCounterpart.transform.TransformPoint(localPosition);
             SetTargetPosition(symmetryCounterpart, newPosition);
         }
         else
         {
             symmetryCounterpart.transform.Translate(localPosition);
         }
         UpdateEditorGizmo(symmetryCounterpart, targetActive);
         GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartOffset, symmetryCounterpart);
     }
 }
示例#21
0
        //get distance: Vector3.Distance(object1.transform.position, object2.transform.position);
        //Physics.Raycast(part.transform.position, part.transform.TransformDirection(dir), out HIT, this.maxLength, EditorLogic.LayerMask)

        /// <summary>
        /// Align compount part, leave in starting position but center and level to target
        /// </summary>
        /// <param name="part">Part</param>
        public static void AlignCompoundPart(CompoundPart part, bool snapHeights)
        {
            if (part.parent == null || part.target == null)
            {
                Log.Debug("Part is not fully connected");
                return;
            }

            if (snapHeights)
            {
                AlignCompoundPartSnapped(part);
            }
            else
            {
                AlignCompoundPartLevel(part);
            }
        }
示例#22
0
        static void AlignCompoundPartLevel(CompoundPart part)
        {
            Part startPart  = part.parent;
            Part targetPart = part.target;

            Vector3 startPosition = startPart.transform.position;
            Vector3 destPosition  = targetPart.transform.position;

            GetCollisionPointOnAxis(startPart, destPosition, part.transform.localPosition.y, out startPosition);

            destPosition   = startPart.transform.InverseTransformPoint(destPosition); //get local pos
            destPosition.y = part.transform.localPosition.y;                          //level out
            destPosition   = startPart.transform.TransformPoint(destPosition);        //back to global pos

            Log.Debug(string.Format("new level startPosition: {0} destPosition: {1}", startPosition.ToString(), destPosition.ToString()));

            RepositionPart(part, startPart, startPosition, destPosition);
        }
示例#23
0
 static public void dumpPartModule(PartModule pm)
 {
     AAprint("pm: " + pm.moduleName);
     AAprint("pm.enabled: " + pm.enabled.ToString() + "/" + pm.isEnabled);
     AAprint("pm.gettype: " + pm.GetType().ToString());
     if (pm.moduleName == "CModuleFuelLine")
     {
         AAprint("FUEL LINE!");
         CompoundPart cp = (CompoundPart)pm.part;
         if (cp.target == null)
         {
             print("target is null");
         }
         else
         {
             printPart("target", cp.target);
         }
     }
 }
示例#24
0
        public static bool PartIsStrutOrFuelLine(CompoundPart part)
        {
            if (!HighLogic.CurrentGame.Parameters.CustomParams <KLFCustomParams2>().allowStrutFuelFailures)
            {
                return(false);
            }

            if (part.name != "fuelLine" && part.name != "strutConnector")
            {
                return(false);
            }
            if (part.attachState == CompoundPart.AttachState.Detached || part.attachState == CompoundPart.AttachState.Attaching)
            {
                return(false);
            }
            if (part.target == part.parent)
            {
                return(false);
            }
            return(true);
        }
示例#25
0
        private static void UpdateEditorGizmo(CompoundPart part, bool targetActive)
        {
            if (part == EditorLogic.SelectedPart)
            {
                Vector3    position;
                Quaternion rotation;
                if (targetActive)
                {
                    CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
                    position = module.targetAnchor.position;
                    rotation = module.targetAnchor.rotation;
                }
                else
                {
                    position = part.transform.position;
                    rotation = part.transform.rotation;
                }

                var gizmoOffset = HighLogic.FindObjectOfType <EditorGizmos.GizmoOffset>();
                if (gizmoOffset != null)
                {
                    gizmoOffset.transform.position = position;
                    if (gizmoOffset.CoordSpace == Space.Self)
                    {
                        gizmoOffset.transform.rotation = rotation;
                    }
                }

                var gizmoRotate = HighLogic.FindObjectOfType <EditorGizmos.GizmoRotate>();
                if (gizmoRotate != null)
                {
                    gizmoRotate.transform.position = position;
                    if (gizmoRotate.CoordSpace == Space.Self)
                    {
                        gizmoRotate.transform.rotation = rotation;
                    }
                }
            }
        }
示例#26
0
        private static void RotateMirrorSymmetryCounterparts(CompoundPart part, Vector3 eulerAngles, Space space, bool targetActive)
        {
            if (space == Space.Self)
            {
                if (targetActive)
                {
                    CompoundParts.CModuleLinkedMesh module = part.FindModuleImplementing <CompoundParts.CModuleLinkedMesh>();
                    eulerAngles = module.targetAnchor.TransformDirection(eulerAngles);
                }
                else
                {
                    eulerAngles = part.transform.TransformDirection(eulerAngles);
                }
            }

            eulerAngles = EditorLogic.RootPart.transform.InverseTransformDirection(eulerAngles);
            Quaternion rotation = Quaternion.Euler(eulerAngles);

            rotation.ToAngleAxis(out float angle, out Vector3 axis);
            Vector3 mirrorAxis = new Vector3(-axis.x, axis.y, axis.z);

            mirrorAxis = EditorLogic.RootPart.transform.TransformDirection(mirrorAxis);

            foreach (CompoundPart symmetryCounterpart in part.symmetryCounterparts)
            {
                if (targetActive)
                {
                    RotateTarget(symmetryCounterpart, mirrorAxis, -angle, Space.World);
                }
                else
                {
                    symmetryCounterpart.transform.Rotate(mirrorAxis, -angle, Space.World);
                    symmetryCounterpart.onEditorEndTweak();
                }
                UpdateEditorGizmo(symmetryCounterpart, targetActive);
                GameEvents.onEditorPartEvent.Fire(ConstructionEventType.PartRotated, symmetryCounterpart);
            }
        }
示例#27
0
        static void AlignCompoundPartSnapped(CompoundPart part)
        {
            Part startPart  = part.parent;
            Part targetPart = part.target;

            Log.Debug("Getting parentLocalHeight");
            float parentLocalHeight = GetCompoundPartPositionHeight(part, part.parent);

            //float parentLocalHeight = SnapCompoundPartHeight(part, part.parent);
            Log.Debug("Getting targetLocalHeight");
            float targetLocalHeight = GetCompoundPartPositionHeight(part, part.target);
            //float targetLocalHeight = SnapCompoundPartHeight(part, part.target);

            Vector3 startPosition = startPart.transform.position;
            Vector3 destPosition  = targetPart.transform.position;

            Log.Debug(string.Format("startPosition: {0} destPosition: {1}", startPosition.ToString(), destPosition.ToString()));

            GetCollisionPointOnAxis(startPart, destPosition, parentLocalHeight, out startPosition);
            GetCollisionPointOnAxis(targetPart, startPosition, targetLocalHeight, out destPosition);
            Log.Debug(string.Format("new collider startPosition: {0} destPosition: {1}", startPosition.ToString(), destPosition.ToString()));

            RepositionPart(part, startPart, startPosition, destPosition);
        }
 private bool StrutsGoHigher(CompoundPart strut, int startingStage, Func<CompoundPart, Part> partSelector)
 {
     return partSelector(strut).inverseStage < startingStage;
 }
 private bool StrutsGoHigher(CompoundPart strut, int startingStage, Func <CompoundPart, Part> partSelector)
 {
     return(partSelector(strut).inverseStage < startingStage);
 }
示例#30
0
        public override void OnRender()
        {
            try
            {
                List <Part> parts = EditorLogic.fetch.ship != null ? EditorLogic.fetch.ship.Parts : new List <Part>();

                this.highlight.BeginTracking();

                GUILayout.BeginVertical();

#if false
                // If Blizzy's toolbar is available, give the user the option to pick the stock toolbar.
                if (ToolbarManager.ToolbarAvailable)
#endif
                {
                    //bool stockToolbar = PartWizardPlugin.ToolbarIsStock;
                    bool stockToolbar = GUILayout.Toggle(PartWizardPlugin.ToolbarIsStock, Localized.UseStockToolbar, GUILayout.Width(200));
                    if (stockToolbar != PartWizardPlugin.ToolbarIsStock)
                    {
#if false
                        PartWizardPlugin.ToolbarTypeToggleActive = true;
#endif
                        PartWizardPlugin.ToolbarIsStock = stockToolbar;
                        PartWizardPlugin.Instance.SaveToolbarConfiguration();
                    }
                }

                #region Display Mode Control

                GUILayout.BeginHorizontal();
                this.viewType = (ViewType)GUIControls.HorizontalToggleSet((int)this.viewType, this.viewTypeContents, this.selectedViewTypeStyle, this.unselectedViewTypeStyle);
                GUILayout.EndHorizontal();

                GUILayout.BeginHorizontal();
                GUILayout.Label("Sort by:");
                this.sortBy = (SortBy)GUIControls.HorizontalToggleSet((int)this.sortBy, this.sortTypeContents, this.selectedViewTypeStyle, this.unselectedViewTypeStyle);
                GUILayout.EndHorizontal();

                List <Part> buyableParts = null;

                if (this.viewType == ViewType.Hidden)
                {
                    parts = parts.FindAll((p) => { return(p.partInfo.category == PartCategories.none); });
                }
                else if (this.viewType == ViewType.Unavailable)
                {
                    parts = parts.FindAll((p) => {
                        bool result = false;

                        // Get the R&D technology state for the current part.
                        ProtoTechNode techState = ResearchAndDevelopment.Instance.GetTechState(p.partInfo.TechRequired);

                        // If there is a state or the technology is locked or the part hasn't been purchased...
                        if (techState == null || techState.state != RDTech.State.Available || !techState.partsPurchased.Contains(p.partInfo))
                        {
                            // ...add it to the list.
                            result = true;
                        }

                        return(result);
                    });
                    Debug.Log("total # buyable part: " + parts.Count.ToString());
                    // Stash the filtered list in to the buyable list.
                    buyableParts = parts;
                    // Create a new collection with a copy of all the buyable parts.
                    parts = new List <Part>(buyableParts);
                    // Create a hash set to act as a filter for duplicate parts.
                    HashSet <string> duplicatePartFilter = new HashSet <string>();
                    // Remove each part that has already been added to the hash filter.
                    parts.RemoveAll((p) => !duplicatePartFilter.Add(p.name));

                    // Here parts is a list of unique buyable parts and buyableParts is all of the buyable parts, including duplicates.
                    Debug.Log("total # buyable part after dup filter: " + parts.Count.ToString());
                }

                #endregion
                if (parts != null && parts.Count > 0)
                {
                    switch (sortBy)
                    {
                    case SortBy.Name:
                        parts.Sort((p, q) => p.partInfo.title.CompareTo(q.partInfo.title));
                        break;

                    case SortBy.StageAsc:
                        if (this.viewType != ViewType.Unavailable)
                        {
                            parts.Sort((p, q) => p.inverseStage.CompareTo(q.inverseStage));
                        }
                        else
                        {
                            parts.Sort((p, q) => p.partInfo.title.CompareTo(q.partInfo.title));
                        }
                        break;

                    case SortBy.StageDesc:
                        if (this.viewType != ViewType.Unavailable)
                        {
                            parts.Sort((q, p) => p.inverseStage.CompareTo(q.inverseStage));
                        }
                        else
                        {
                            parts.Sort((p, q) => p.partInfo.title.CompareTo(q.partInfo.title));
                        }
                        break;
                    }
                }
                #region Part List

                GUILayout.BeginVertical(GUIControls.PanelStyle);

                this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, false, false);

                int totalEntryCost   = 0;
                int visiblePartCount = 0;
                int lastStage        = 0;
                if (parts != null && parts.Count > 0)
                {
                    lastStage = parts[0].inverseStage;
                }

                if (this.viewType == ViewType.Category)
                {
                    if (GUILayout.Button(Localized.ViewAll))
                    {
                        for (int i = 0; i < visibleCategories.Length; i++)
                        {
                            visibleCategories[i] = true;
                        }
                    }
                    if (GUILayout.Button(Localized.Clear))
                    {
                        for (int i = 0; i < visibleCategories.Length; i++)
                        {
                            visibleCategories[i] = false;
                        }
                    }

                    for (PartCategories partCategories = PartCategories.Propulsion; partCategories < PartCategories.Coupling; partCategories++)
                    {
                        // Need to add one to the PartCategories because "none" is a -1, and some parts have a category = none
                        visibleCategories[(int)partCategories + 1] = GUILayout.Toggle(visibleCategories[(int)partCategories + 1], partCategories.ToString(), toggleStyle);
                    }
                }
                else if (this.viewType == ViewType.Resources)
                {
                    if (GUILayout.Button(Localized.ViewAll))
                    {
                        foreach (ResourceInfo resourceInfo in this.availableResources.Values)
                        {
                            resourceInfo.Visible = true;
                        }
                    }

                    if (GUILayout.Button(Localized.Clear))
                    {
                        foreach (ResourceInfo resourceInfo in this.availableResources.Values)
                        {
                            resourceInfo.Visible = false;
                        }
                    }

                    foreach (string availableResource in this.availableResources.Keys)
                    {
                        bool resourceVisible = GUILayout.Toggle(this.availableResources[availableResource].Visible, availableResource, toggleStyle);

                        this.availableResources[availableResource].Visible = resourceVisible;
                    }
                }
                else
                {
                    foreach (Part part in parts)
                    {
                        // Reset part name label color to default; some conditions may change the color to indicate various things.
                        labelStyle.normal.textColor = PartWizardWindow.DefaultPartNameColor;
                        // Check if this part's category is currently visible.
                        // Need to add one to the PartCategories because "none" is a -1, and some parts have a category = none
                        if (visibleCategories[(int)part.partInfo.category + 1])
                        {
                            // The part's category is visible, now check resource conditions to determine final visibility.
                            bool partVisible = false;

                            if (this.availableResources[Localized.ShowPartsWithoutResources].Visible && part.Resources.Count == 0)
                            {
                                partVisible = true;
                            }
                            else
                            {
                                foreach (PartResource partResource in part.Resources)
                                {
                                    if (this.availableResources[partResource.resourceName].Visible)
                                    {
                                        partVisible = true;
                                        break;
                                    }
                                }
                            }
                            if (partVisible)
                            {
                                totalEntryCost += part.partInfo.entryCost;
                                visiblePartCount++;

                                GUIControls.BeginMouseOverHorizontal();

                                bool actionEditorPartButtonMouseOver = false;

                                #region Part Label

                                if (sortBy == SortBy.StageAsc || sortBy == SortBy.StageDesc)
                                {
                                    if (lastStage != part.inverseStage)
                                    {
                                        lastStage = part.inverseStage;
                                    }
                                    GUILayout.Label(lastStage.ToString() + ": ");
                                }
                                if (EditorLogic.fetch.editorScreen != EditorScreen.Actions)
                                {
                                    // Check compound parts for integrity.
                                    if (part is CompoundPart)
                                    {
                                        CompoundPart compoundPart = (CompoundPart)part;
                                        if (compoundPart.attachState == CompoundPart.AttachState.Detached || compoundPart.attachState == CompoundPart.AttachState.Attaching || compoundPart.target == compoundPart.parent)
                                        {
                                            labelStyle.normal.textColor = Color.red;
                                        }
                                    }
                                    labelStyle.fixedWidth = 250;
                                    GUILayout.Label(new GUIContent(part.partInfo.title, part.partInfo.name), labelStyle);
                                }
                                else
                                {
                                    Log.Write("EditorScreen.Actions, part: " + part.partInfo.title);
                                    if (GUIControls.MouseOverButton(new GUIContent(part.partInfo.title, part.partInfo.name), out actionEditorPartButtonMouseOver, this.actionEditorModePartButtonStyle))
                                    {
                                        // Each part gets the EditorActionPartSelector added to it when the editor switches to the Actions screen. (And it
                                        // gets taken away when leaving that screen.)
                                        EditorActionPartSelector selector = part.GetComponent <EditorActionPartSelector>();

                                        // Make sure we have it...
                                        if (selector != null)
                                        {
                                            // ...and select it.
                                            selector.Select();

                                            Log.Write("Action editor selecting part {0}.", part.name);
                                        }
                                    }
                                }

                                #endregion

                                // Adds space between the part name and the buttons (if any) associated with the part.
                                GUILayout.FlexibleSpace();

                                // Only enable the following buttons if there is no actively selected part, but we want to have them drawn.
                                GUI.enabled = EditorLogic.SelectedPart == null;

                                bool deleted = false;                   // Will be set to true if the delete button was pressed.
                                bool bought  = false;                   // Will be set to true if the buy button was pressed.

                                bool breakSymmetryMouseOver = false;    // Will be set to true if the mouse is over the part's break symmetry button.
                                bool deleteButtonMouseOver  = false;    // Will be set to true if the mouse is over the part's delete button.
                                bool buyButtonMouseOver     = false;    // Will be set to true if the mouse is over the part's buy button.

                                string deleteTooltip = default(string);
                                string buyTooltip    = default(string);

                                if (this.viewType == ViewType.All || this.viewType == ViewType.Hidden)
                                {
                                    #region Break Symmetry Button

                                    string breakabilityReport = default(string);
                                    GUI.enabled = EditorLogic.SelectedPart == null && EditorLogic.fetch.editorScreen == EditorScreen.Parts && PartWizard.HasBreakableSymmetry(part, out breakabilityReport);

                                    string breakSymmetryTooltip = GUI.enabled ? Localized.BreakSymmetryDescription : default(string);

                                    breakSymmetryMouseOver = false;
                                    if (GUIControls.MouseOverButton(new GUIContent(Localized.BreakSymmetryButtonText, breakSymmetryTooltip), out breakSymmetryMouseOver, Configuration.PartActionButtonWidth))
                                    {
                                        this.symmetryEditorWindow.Part = part;

                                        if (!this.symmetryEditorWindow.Visible)
                                        {
                                            this.symmetryEditorWindow.Show(this);

                                            // Short circuit the mouse over for breaking symmetry when showing the Symmetry Editor in case it appears over top of this
                                            // button and immediately begins highlighting parts. This would cause *this* window's highlighting to be stuck on the part.
                                            breakSymmetryMouseOver = false;
                                        }
                                    }

                                    breakSymmetryMouseOver &= GUI.enabled;  // Clear mouse over flag if the symmetry button was disabled.

                                    #endregion

                                    #region Delete Button

                                    GUI.enabled = EditorLogic.SelectedPart == null && EditorLogic.fetch.editorScreen == EditorScreen.Parts && PartWizard.IsDeleteable(part);

                                    deleteTooltip = GUI.enabled
                                        ? ((part.symmetryCounterparts.Count == 0) ? Localized.DeletePartSingularDescription : Localized.DeletePartPluralDescription)
                                        : default(string);

                                    if (GUIControls.MouseOverButton(new GUIContent(Localized.DeletePartButtonText, deleteTooltip), out deleteButtonMouseOver, Configuration.PartActionButtonWidth))
                                    {
                                        PartWizard.Delete(part);

                                        // Set a flag so additional GUI logic can decide what to do in the case where a part is deleted.
                                        deleted = true;
                                    }

                                    deleteButtonMouseOver &= GUI.enabled;   // Clear mouse over flag if the delete button was disabled.

                                    #endregion
                                }
                                else // this.viewType == ViewType.Unavailable
                                {
                                    #region Buy Button

                                    GUI.enabled = EditorLogic.SelectedPart == null && (double)part.partInfo.entryCost <= Funding.Instance.Funds && PartWizard.IsBuyable(part);

                                    buyTooltip = GUI.enabled ? string.Format(Localized.BuyPartDescriptionTextFormat, part.partInfo.entryCost) : default(string);

                                    if (GUIControls.MouseOverButton(new GUIContent(Localized.BuyPartButtonText, buyTooltip), out buyButtonMouseOver, Configuration.PartActionButtonWidth))
                                    {
                                        Log.Write("Buying part {0}.", part.name);

                                        PartWizard.Buy(part, true);

                                        // Set a flag so additional GUI logic can decide what to do in the case where a part is bought.
                                        bought = true;
                                    }

                                    buyButtonMouseOver &= GUI.enabled;  // Clear mouse over flag if the buy button was disabled.

                                    #endregion
                                }

                                GUI.enabled = true;

                                bool groupMouseOver = false;
                                GUIControls.EndMouseOverHorizontal(out groupMouseOver);     // End of row for this part.

                                // If we deleted a part, then just jump out of the loop since the parts list has been modified.
                                if (deleted || bought)
                                {
                                    break;
                                }

                                #region Part Highlighting Control

                                if (breakSymmetryMouseOver)
                                {
                                    this.highlight.Add(part, Configuration.HighlightColorEditableSymmetryRoot, Configuration.HighlightColorEditableSymmetryCounterparts, true);
                                }
                                else if (deleteButtonMouseOver)
                                {
                                    this.highlight.Add(part, Configuration.HighlightColorDeletablePart, Configuration.HighlightColorDeletableCounterparts, true);
                                }
                                else if (buyButtonMouseOver)
                                {
                                    // TODO: Duplicate code!
                                    buyableParts.ForEach((p) => {
                                        if (part.name == p.name)
                                        {
                                            this.highlight.Add(p, Configuration.HighlightColorBuyablePart);
                                        }
                                    });
                                }
                                else if (groupMouseOver)
                                {
                                    if (viewType != ViewType.Unavailable)
                                    {
                                        Color highlightColor            = (part == EditorLogic.RootPart) ? Configuration.HighlightColorRootPart : Configuration.HighlightColorSinglePart;
                                        Color counterpartHighlightColor = Configuration.HighlightColorCounterparts;

                                        if (EditorLogic.fetch.editorScreen == EditorScreen.Actions)
                                        {
                                            highlightColor            = Configuration.HighlightColorActionEditorTarget;
                                            counterpartHighlightColor = Configuration.HighlightColorActionEditorTarget;
                                        }

                                        this.highlight.Add(part, highlightColor, counterpartHighlightColor, false);
                                    }
                                    else
                                    {
                                        // TODO: Duplicate code!
                                        buyableParts.ForEach((p) => {
                                            if (part.name == p.name)
                                            {
                                                Log.Write("Highlighting 2 part: " + part.partInfo.title);
                                                this.highlight.Add(p, Configuration.HighlightColorBuyablePart, false);
                                            }
                                        });
                                    }
                                }
                                else if (actionEditorPartButtonMouseOver)
                                {
                                    Log.Write("Highlighting part: " + part.partInfo.title);
                                    this.highlight.Add(part, Configuration.HighlightColorActionEditorTarget, Configuration.HighlightColorActionEditorTarget);
                                }

                                #endregion
                            }
                        }
                    }
                }

                GUILayout.EndScrollView();

                GUILayout.EndVertical();

                if (viewType == ViewType.Unavailable)
                {
                    int  buyableEntryCost = 0;
                    bool enableBulkBuy    = false;

                    foreach (Part p in parts)
                    {
                        buyableEntryCost += p.partInfo.entryCost;

                        enableBulkBuy |= PartWizard.IsBuyable(p);
                    }

                    GUI.enabled = parts.Count > 0 && (double)buyableEntryCost <= Funding.Instance.Funds && enableBulkBuy;

                    bool buyAllMouseOver = false;
                    if (GUIControls.MouseOverButton(new GUIContent(string.Format(Localized.BuyAllButtonTextFormat, buyableEntryCost)), out buyAllMouseOver))
                    {
                        foreach (Part part in parts)
                        {
                            if (PartWizard.IsBuyable(part))
                            {
                                Log.Write("Buying part {0}.", part.name);

                                PartWizard.Buy(part, false);
                            }
                        }

                        PartWizard.SaveGame();
                    }

                    // TODO: Highlight all parts that will be bought by clicking Buy All.
                    if (buyAllMouseOver)
                    {
                        buyableParts.ForEach((p) => {
                            this.highlight.Add(p, Configuration.HighlightColorBuyablePart);
                        });
                    }

                    GUI.enabled = true;
                }

                #endregion

                #region Status Area

                // Push everything above this up, otherwise it will be centered vertically.
                GUILayout.FlexibleSpace();

                if (viewType == ViewType.All || viewType == ViewType.Hidden || viewType == ViewType.Unavailable)
                {
                    string status = default(string);

                    if (!string.IsNullOrEmpty(GUI.tooltip))
                    {
                        if (parts.Count != 1)
                        {
                            status = string.Format(CultureInfo.CurrentCulture, Localized.StatusLabelPluralTooltipTextFormat, visiblePartCount, GUI.tooltip, parts.Count - visiblePartCount);
                        }
                        else
                        {
                            status = string.Format(CultureInfo.CurrentCulture, Localized.StatusLabelSingularTooltipTextFormat, visiblePartCount, GUI.tooltip, parts.Count - visiblePartCount);
                        }
                    }
                    else
                    {
                        if (parts.Count != 1)
                        {
                            status = string.Format(CultureInfo.CurrentCulture, Localized.StatusLabelPluralTextFormat, visiblePartCount, parts.Count - visiblePartCount);
                        }
                        else
                        {
                            status = string.Format(CultureInfo.CurrentCulture, Localized.StatusLabelSingularTextFormat, visiblePartCount, parts.Count - visiblePartCount);
                        }
                    }

                    GUILayout.Label(status, this.tooltipLabelStyle);
                }

                #endregion

                GUILayout.EndVertical();

                if (this.Visible && this.mouseOver)
                {
                    this.highlight.EndTracking();
                }
                else
                {
                    this.highlight.CancelTracking();
                }
            }
            catch (Exception e)
            {
                Log.Write("PartWizardWindow.OnRender() unexpected exception caught.");

                Log.Write(e.Message);
                Log.Write(e.StackTrace);

                this.highlight.CancelTracking();

                throw;
            }
            finally
            {
                GUI.DragWindow();
            }
        }
示例#31
0
 private static bool IsTargetActive(CompoundPart part, bool targetSelected)
 {
     return(targetSelected && part.target != null);
 }
示例#32
0
        static float GetCompoundPartPositionHeight(CompoundPart part, Part target)
        {
            Log.Debug(string.Format("Getting new position height for {0} on {1}", part.name, target.name));

            //lengthwise position on parent (extents, +/- from center)
            float localHeight  = 0f;
            float parentHeight = 0f;

            if (part.parent == target)
            {
                localHeight  = part.transform.localPosition.y;
                parentHeight = part.parent.GetPartRendererBound().extents.y;
            }
            else if (part.target == target)
            {
                Vector3 targetPos = part.transform.TransformPoint(part.targetPosition);
                targetPos    = target.transform.InverseTransformPoint(targetPos);
                localHeight  = targetPos.y;
                parentHeight = target.GetPartRendererBound().extents.y;
            }
            else
            {
                Log.Warn("Unable to identify part");
            }

            Log.Debug(string.Format("localHeight: {0} parentHeight: {1}", localHeight.ToString("F3"), parentHeight.ToString("F3")));

            //offset strut when attaching to top/bottom of parent
            const float strutOffset = 0.15f;
            //threshold for small parent parts
            const float parentSizeCutoff = 0.5f;

            float heightPct = localHeight / parentHeight;

            Log.Debug("Attachment height%: " + (heightPct * 100f).ToString("F0"));
            Log.Debug("Original localHeight: " + localHeight.ToString());

            //+1 up, -1 down
            float upOrDown = 1f;

            if (localHeight < 0f)
            {
                upOrDown = -1f;
            }

            if (parentHeight < parentSizeCutoff)
            {
                //for small parts, just center on them
                Log.Debug("Parent is small, defaulting to center");
                localHeight = 0f;
            }
            else if (parentHeight >= 1.5f)
            {
                //only do quarter snapping for parts >= 3.0 total height
                if (Math.Abs(localHeight) < parentHeight * 0.125f)
                {
                    //middle 25% of parent, snap to center (12.5% of extent)
                    Log.Debug("Centering on parent");
                    localHeight = 0f;
                }
                else if (Math.Abs(localHeight) < parentHeight * 0.7f)
                {
                    //top/bottom quarter (70% of extent)
                    Log.Debug("Centering quarter on parent");
                    localHeight = parentHeight / 2 * upOrDown;
                }
                else
                {
                    //top/bottom edge
                    Log.Debug("Aligning to edge of parent");
                    localHeight = (parentHeight - strutOffset) * upOrDown;
                }
            }
            else if (Math.Abs(localHeight) < parentHeight * 0.5f)
            {
                //middle 50% of parent, snap to center
                Log.Debug("Centering on parent");
                localHeight = 0f;
            }
            else
            {
                //top/bottom edge
                Log.Debug("Aligning to edge of parent");
                localHeight = (parentHeight - strutOffset) * upOrDown;
            }


            Log.Debug("new localHeight: " + localHeight.ToString());
            return(localHeight);
        }