Exemple #1
0
        public static void StartPointer(Part rootPart, KIS_Item item,
                                        OnPointerClick pClick, OnPointerState pState,
                                        Transform from = null)
        {
            if (!running)
            {
                DebugEx.Fine("StartPointer()");
                customRot        = Vector3.zero;
                aboveDistance    = 0;
                partToAttach     = rootPart;
                sourceTransform  = from;
                running          = true;
                SendPointerClick = pClick;
                SendPointerState = pState;

                if (rootPart)
                {
                    MakePointer(rootPart);
                }
                else
                {
                    VariantsUtils.ExecuteAtPartVariant(
                        item.availablePart,
                        VariantsUtils.GetCurrentPartVariant(item.availablePart, item.partNode),
                        MakePointer);
                    pointer.transform.localScale *=
                        KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(item.partNode);
                }

                LockUI();
                allowedAttachmentParts = allowedAttachmentParts; // Apply selection.
                SendPointerState(PointerTarget.Nothing, PointerState.OnPointerStarted, null, null);
            }
        }
Exemple #2
0
 public void EnableIcon(int resolution)
 {
     DisableIcon();
     icon = new KIS_IconViewer(
         availablePart, resolution,
         VariantsUtils.GetCurrentPartVariant(availablePart, partNode));
 }
Exemple #3
0
        /// <summary>Returns the part's model.</summary>
        /// <remarks>The returned model is a copy from the part prefab.</remarks>
        /// <param name="avPart">The part proto to get the model from.</param>
        /// <param name="variant">
        /// The part's variant to apply. If <c>null</c>, then variant will be extracted from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent state. It's used to extract the external scale modifiers and part's
        /// variant. It can be <c>null</c>.
        /// </param>
        /// <returns>The model of the part. Don't forget to destroy it when not needed.</returns>
        public GameObject GetPartModel(
            AvailablePart avPart,
            PartVariant variant = null, ConfigNode partNode = null)
        {
            if (variant == null && partNode != null)
            {
                variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode);
            }
            GameObject modelObj = null;

            VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => {
                var partPrefabModel = Hierarchy.GetPartModelTransform(p).gameObject;
                modelObj            = UnityEngine.Object.Instantiate(partPrefabModel);
                modelObj.SetActive(true);
            });

            // Handle TweakScale settings.
            if (partNode != null)
            {
                var scale = KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(partNode);
                if (Math.Abs(1.0 - scale) > double.Epsilon)
                {
                    DebugEx.Fine("Applying TweakScale size modifier: {0}", scale);
                    var scaleRoot = new GameObject("TweakScale");
                    scaleRoot.transform.localScale = new Vector3((float)scale, (float)scale, (float)scale);
                    modelObj.transform.SetParent(scaleRoot.transform, worldPositionStays: false);
                    modelObj = scaleRoot;
                }
            }

            return(modelObj);
        }
Exemple #4
0
        /// <summary>Calculates part's dry cost given the config and the variant.</summary>
        /// <param name="avPart">The part's proto.</param>
        /// <param name="variant">
        /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent config. It will be looked up for the various cost modifiers.
        /// </param>
        /// <returns>The dry cost of the part.</returns>
        public double GetPartDryCost(
            AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null)
        {
            // TweakScale compatibility
            if (partNode != null)
            {
                var tweakScale = KISAPI.PartNodeUtils.GetTweakScaleModule(partNode);
                if (tweakScale != null)
                {
                    var tweakedCost = ConfigAccessor.GetValueByPath <double>(tweakScale, "DryCost");
                    if (tweakedCost.HasValue)
                    {
                        // TODO(ihsoft): Get back to this code once TweakScale supports variants.
                        return(tweakedCost.Value);
                    }
                    DebugEx.Error("No dry cost specified in a tweaked part {0}:\n{1}", avPart.name, tweakScale);
                }
            }
            var itemCost = avPart.cost;

            if (variant == null && partNode != null)
            {
                variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode);
            }
            VariantsUtils.ExecuteAtPartVariant(avPart, variant,
                                               p => itemCost += p.GetModuleCosts(avPart.cost));
            return(itemCost);
        }
Exemple #5
0
 public KIS_IconViewer(Part part, int resolution)
 {
     if (part.Modules.OfType <KerbalEVA>().Any())
     {
         MakeKerbalAvatar(part, resolution);
     }
     else
     {
         MakePartIcon(part.partInfo, resolution, VariantsUtils.GetCurrentPartVariant(part));
     }
 }
Exemple #6
0
 public KIS_IconViewer(Part part, int resolution)
 {
     if (part.vessel != null && part.vessel.isEVA)
     {
         MakeKerbalAvatar(part, resolution);
     }
     else
     {
         MakePartIcon(part.partInfo, resolution, VariantsUtils.GetCurrentPartVariant(part));
     }
 }
Exemple #7
0
        /// <summary>Calculates part's dry mass given the config and the variant.</summary>
        /// <param name="avPart">The part's proto.</param>
        /// <param name="variant">
        /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent config. It will be looked up for the variant if it's not specified.
        /// </param>
        /// <returns>The dry cost of the part.</returns>
        public double GetPartDryMass(
            AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null)
        {
            var itemMass = avPart.partPrefab.mass;

            if (variant == null && partNode != null)
            {
                variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode);
            }
            VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => itemMass += p.GetModuleMass(p.mass));
            return(itemMass);
        }
Exemple #8
0
        /// <summary>Returns part's boundary box basing on its geometrics.</summary>
        /// <remarks>The size is calculated from the part prefab model.</remarks>
        /// <param name="avPart">The part proto to get the models from.</param>
        /// <param name="variant">
        /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent config. It will be looked up for the variant if it's not specified.
        /// </param>
        /// <returns>The volume in liters.</returns>
        public Vector3 GetPartBounds(
            AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null)
        {
            var bounds = default(Bounds);

            if (variant == null && partNode != null)
            {
                variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode);
            }
            VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => {
                var partModel = GetSceneAssemblyModel(p).transform;
                bounds.Encapsulate(GetMeshBounds(partModel));
                UnityEngine.Object.DestroyImmediate(partModel.gameObject);
            });
            return(bounds.size);
        }
Exemple #9
0
        static void OnMouseEnterPart(Part hoverPart)
        {
            if (hoverPart == partToAttach)
            {
                return;
            }

            if (allowMount)
            {
                ModuleKISPartMount pMount = hoverPart.GetComponent <ModuleKISPartMount>();
                if (pMount)
                {
                    // Set current attach node
                    AttachNode an = attachNodes.Find(f => f.id == pMount.mountedPartNode);
                    if (an != null)
                    {
                        attachNodeIndex = attachNodes.IndexOf(an);
                        SetPointerVisible(false);
                    }
                    else
                    {
                        SetPointerVisible(true);
                    }
                    // Init attach node
                    foreach (KeyValuePair <AttachNode, List <string> > mount in pMount.GetMounts())
                    {
                        if (!mount.Key.attachedPart)
                        {
                            KIS_Shared.AssignAttachIcon(hoverPart, mount.Key, colorMountOk, "KISMount");
                        }
                    }
                }
            }
            if (allowStack && currentAttachNode.nodeType != AttachNode.NodeType.Surface)
            {
                var variant = VariantsUtils.GetCurrentPartVariant(hoverPart);
                if (variant != null)
                {
                    VariantsUtils.ApplyVariantOnAttachNodes(hoverPart, variant);
                }
                foreach (var an in KIS_Shared.GetAvailableAttachNodes(hoverPart, needSrf: false))
                {
                    KIS_Shared.AssignAttachIcon(hoverPart, an, colorStack);
                }
            }
            SendPointerState(pointerTarget, PointerState.OnMouseEnterPart, hoverPart, null);
        }
Exemple #10
0
        /// <summary>Returns part's volume basing on its geometrics.</summary>
        /// <remarks>
        /// The volume is calculated basing on the smallest boundary box that encapsulates all the meshes
        /// in the part. The deployable parts can take much more space in teh deployed state.
        /// </remarks>
        /// <param name="avPart">The part proto to get the models from.</param>
        /// <param name="variant">
        /// The part's variant. If it's <c>null</c>, then the variant will be attempted to read from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent config. It will be looked up for the variant if it's not specified.
        /// </param>
        /// <returns>The volume in liters.</returns>
        public float GetPartVolume(
            AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null)
        {
            var itemModule = avPart.partPrefab.Modules.OfType <KIS.ModuleKISItem>().FirstOrDefault();

            if (itemModule != null && itemModule.volumeOverride > 0)
            {
                return(itemModule.volumeOverride                                    // Ignore geometry.
                       * KISAPI.PartNodeUtils.GetTweakScaleSizeModifier(partNode)); // But respect TweakScale.
            }
            var bounds = default(Bounds);

            VariantsUtils.ExecuteAtPartVariant(avPart, variant, p => {
                var partModel = GetSceneAssemblyModel(p).transform;
                bounds.Encapsulate(GetMeshBounds(partModel));
                UnityEngine.Object.DestroyImmediate(partModel.gameObject);
            });
            var boundsSize = bounds.size;

            return(boundsSize.x * boundsSize.y * boundsSize.z * 1000f);
        }
Exemple #11
0
        /// <summary>Returns the part's model, used to make the perview icon.</summary>
        /// <remarks>
        /// Note, that this is not the actual part appearance. It's an optimized version, specifically
        /// made for the icon preview. In particular, the model is scaled to fit the icon's constrains.
        /// </remarks>
        /// <param name="avPart">The part proto to get the model from.</param>
        /// <param name="variant">
        /// The part's variant to apply. If <c>null</c>, then variant will be extracted from
        /// <paramref name="partNode"/>.
        /// </param>
        /// <param name="partNode">
        /// The part's persistent state. It's used to extract the part's variant. It can be <c>null</c>.
        /// </param>
        /// <param name="skipVariantsShader">
        /// Tells if the variant shaders must not be applied to the model. For the purpose of making a
        /// preview icon it's usually undesirable to have the shaders changed.
        /// </param>
        /// <returns>The model of the part. Don't forget to destroy it when not needed.</returns>
        public GameObject GetIconPrefab(
            AvailablePart avPart,
            PartVariant variant = null, ConfigNode partNode = null, bool skipVariantsShader = true)
        {
            var iconPrefab = UnityEngine.Object.Instantiate(avPart.iconPrefab);

            iconPrefab.SetActive(true);
            if (variant == null && partNode != null)
            {
                variant = VariantsUtils.GetCurrentPartVariant(avPart, partNode);
            }
            if (variant != null)
            {
                DebugEx.Fine(
                    "Applying variant to the iconPrefab: part={0}, variant={1}", avPart.name, variant.Name);
                ModulePartVariants.ApplyVariant(
                    null,
                    Hierarchy.FindTransformByPath(iconPrefab.transform, "**/model"),
                    variant,
                    KSP.UI.Screens.EditorPartIcon.CreateMaterialArray(iconPrefab),
                    skipVariantsShader);
            }
            return(iconPrefab);
        }