private void OnPartVariantApplied(Part p, PartVariant variant) { if (p == part) { StartCoroutine(OnPartVariantAppliedCR()); } }
private TextureSet getSet(PartVariant variant) { string setName = variant.GetExtraInfoValue("textureSet"); TextureSet set = null; if (!string.IsNullOrEmpty(setName)) { set = TexturesUnlimitedLoader.getTextureSet(setName); textureSet = setName; modelShaderSet = string.Empty; return(set); } setName = variant.GetExtraInfoValue("modelShader"); if (!string.IsNullOrEmpty(setName)) { set = TexturesUnlimitedLoader.getModelShaderTextureSet(setName); modelShaderSet = setName; textureSet = string.Empty; return(set); } //if nothing found, clear out references if (TexturesUnlimitedLoader.logErrors || TexturesUnlimitedLoader.logAll) { MonoBehaviour.print("Could not load texture set for part variant: " + variant?.Name + " for part: " + part.name); } modelShaderSet = textureSet = string.Empty; return(null); }
private string GetVariantToApply(string variantName, Part p) { ConfigNode[] partNodes = GameDatabase.Instance.GetConfigNodes("CONSISTENT_VARIANT"); for (int i = 0; i < partNodes.Length; i++) { ConfigNode partNode = partNodes.ElementAt(i); if (partNode.GetValue("PartName") != p.name) { continue; } ConfigNode[] variantNodes = partNode.GetNodes("VARIANT"); for (int variantCount = 0; variantCount < variantNodes.Length; variantCount++) { ConfigNode selectedVariantNode = variantNodes.ElementAt(variantCount); if (selectedVariantNode.GetValue("Theme") != variantName) { continue; } return(selectedVariantNode.GetValue("VariantName")); } } for (int i = 0; i < p.variants.variantList.Count; i++) { PartVariant pv = p.variants.variantList.ElementAt(i); if (pv.DisplayName == fallbackVariant) { return(pv.Name); } } return(null); }
public void OnVariantApplied(Part appliedPart, PartVariant variant) { if (appliedPart == part) { UpdateStretch(); } }
protected void OnVariantApplied(Part eventPart, PartVariant variant) { if (_isAttached && eventPart == part.parent) { UpdateTargets(); } }
private void ProcessBase(Part oPart, PartVariant oVariant) { string sDebug = ""; string sValue; if (IsDebug) { sDebug = "Base Part Fields [Part]:\r\n"; } foreach (BaseField oField in oPart.Fields) { if (IsDebug) { sDebug += oField.name + "\r\n"; } sValue = oVariant.GetExtraInfoValue("Part/" + oField.name); if (!string.IsNullOrEmpty(sValue)) { oField.SetValue(Convert.ChangeType(sValue, oField.FieldInfo.FieldType), oField.host); if (IsDebug) { sDebug += " Applied: " + oField.name + " = " + sValue + "\r\n"; } } } if (IsDebug) { Debug.Log(sDebug); } }
private void onVariantApplied(Part variantPart, PartVariant variant) { if (!variantPart != part) { return; } }
/// <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); }
/// <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); }
private bool shouldRespondToAppliedVariant(Part variantPart, PartVariant variant) { if (part == null || variantPart == null) { return(false); } /* This could get complicated real quick. Stock doesn't appear to respond to part varant events unless they come from the same part. * if (variantPart == part.parent || part.children.Contains(variantPart)) * { * string meshSet = variant.GetExtraInfoValue("meshSet"); * if (!string.IsNullOrEmpty(meshSet) && !string.IsNullOrEmpty(meshSets) && meshSets.Contains(meshSet)) * return true; * } */ if (variantPart != part) { return(false); } if (string.IsNullOrEmpty(moduleID)) { return(false); } // Part variant events can fire before the part module has been started. Let's ignore them until we're initialized. if (!isInitialized) { return(false); } return(true); }
private void onVariantApplied(Part variantPart, PartVariant variant) { if (variantPart != part) { return; } if (string.IsNullOrEmpty(resourceName)) { return; } if (!part.Resources.Contains(resourceName)) { return; } string amountString = variant.GetExtraInfoValue(resourceName); if (string.IsNullOrEmpty(amountString)) { return; } double amount = 0; if (double.TryParse(amountString, out amount)) { part.Resources[resourceName].maxAmount = amount; if (!updateMaxOnly) { part.Resources[resourceName].amount = amount; } MonoUtilities.RefreshContextWindows(part); GameEvents.onPartResourceListChange.Fire(part); } }
private void onEditorVariantApplied(Part part, PartVariant variant) { // This should never be called in flight, but somehow it was, so just // have a check to be safe if (HighLogic.LoadedSceneIsFlight) { return; } if (part != base.part || part == null) { return; } if (variant == null || variant.DisplayName == null) { return; } ModSegSRBs.GetExtraInfo(variant, ref this.part.segmentHeight, ref this.part.segmentWidth); RecalculateFuelAndMass(); var f = GetMaxThrust(); if (baseEngine != null) { baseEngine.ScheduleSegmentUpdate("MSSRB_Fuel_Segment.onEditorVariantApplied", 5); } #if true MonoUtilities.RefreshContextWindows(part); #else MonoUtilities.RefreshPartContextWindow(part); #endif }
public void OnEditorVariantApplied(Part part, PartVariant variant) { if (part == this.part) { ApplySettings(); } }
void MakePartIcon(AvailablePart avPart, int resolution, PartVariant variant) { // Instantiate part icon iconPrefab = KISAPI.PartUtils.GetIconPrefab(avPart, variant); // Command Seat Icon Fix (Temporary workaround until squad fix the broken shader) Shader fixShader = Shader.Find("KSP/Alpha/Cutoff Bumped"); foreach (Renderer r in iconPrefab.GetComponentsInChildren <Renderer>(true)) { foreach (Material m in r.materials) { if (m.shader.name == "KSP/Alpha/Cutoff") { m.shader = fixShader; } } } // Icon Camera GameObject camGo = new GameObject("KASCamItem" + cameraGlobalShift); camGo.transform.position = new Vector3(cameraGlobalShift, IconPosY, 0); camGo.transform.rotation = Quaternion.identity; camera = camGo.AddComponent <Camera>(); camera.orthographic = true; camera.orthographicSize = CameraZoom; camera.clearFlags = CameraClearFlags.Color; camera.enabled = false; // Render texture RenderTexture tex = new RenderTexture(resolution, resolution, 8); texture = tex; //light if (iconLight == null && HighLogic.LoadedSceneIsFlight) { GameObject lightGo = new GameObject("KASLight"); iconLight = lightGo.AddComponent <Light>(); iconLight.cullingMask = 1 << CameraLayer; iconLight.type = LightType.Directional; iconLight.intensity = LightIntensity; iconLight.shadows = LightShadows.None; iconLight.renderMode = LightRenderMode.ForcePixel; } // Layer camera.cullingMask = 1 << CameraLayer; SetLayerRecursively(iconPrefab, CameraLayer); // Texture camera.targetTexture = tex; camera.ResetAspect(); // Cam index cameraShift = cameraGlobalShift; cameraGlobalShift += 2; ResetPos(); }
public void OnVariantApplied(Part appliedPart, PartVariant variant) { // I dont know why changing part variants resets all the materials to their as-loaded state, but it does if (appliedPart == this.part) { UpdateAllMaterials(); } }
/// <summary> /// Here when a variant is applied in the editor. /// </summary> /// <param name="part"></param> /// <param name="variant"></param> private void OnEditorVariantApplied(Part part, PartVariant variant) { ModuleSimpleFuelSwitch module = ModuleSimpleFuelSwitch.TryFind(part); if (module != null) { module.OnVariantApplied(variant); } }
/// <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 model = GetPartModel(avPart, variant: variant, partNode: partNode); var boundsSize = model.GetRendererBounds().size; UnityEngine.Object.DestroyImmediate(model); return(boundsSize.x * boundsSize.y * boundsSize.z * 1000f); }
internal PartVariant SetVariant(PartVariant partVariant) { Log.dbg("VariantPartScaler.SetVariant {0}", partVariant.DisplayName); PartVariant r = this.previousVariant; this.previousVariant = this.currentVariant; this.currentVariant = partVariant; return(r); }
public void OnVariantApplied(Part p, PartVariant pv) { if (p is Part && this.part == p) { // Applying a PartVariant moves the attachment nodes around. Reinitialize them. Debug.Log($"{ModTag} OnVariantApplied(Part {p}, PartVariant {pv?.Name}) from {this}/{part}"); shape.InitializeAttachmentNodes(); FixStackAttachments(); } }
private void DefaultVariantSet(AvailablePart part, PartVariant variant) { string themeToApply = DefineDefaultTheme(variant.Name, part.partPrefab.name); if (themeToApply != null) { UpdateDefaultTheme(themeToApply); } fallbackVariant = variant.Name; }
public void SetDefaultVariant(Part part, PartVariant variant) { string themeToApply = DefineDefaultTheme(variant.Name, part.name); if (themeToApply != null) { UpdateDefaultTheme(themeToApply); } fallbackVariant = variant.Name; }
internal void EditorVariantAppliedHandler(Part part, PartVariant partVariant) { foreach (VariantPartScaler ps in this.listeners) { if (ps.enabled && ps.IsMine(part)) { ps.OnEditorVariantApplied(part, partVariant); } } }
/// <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) { float itemMass = avPart.partPrefab.mass; if (variant == null && partNode != null) { variant = GetCurrentPartVariant(avPart, partNode); } ExecuteAtPartVariant(avPart, variant, p => itemMass += p.GetModuleMass(p.mass)); return(itemMass); }
private void VariantAppliedEventHandler(Part oPart, PartVariant oVariant) { if (oPart == null || oVariant == null) { return; } ProcessResources(oPart, oVariant); ProcessModules(oPart, oVariant); UpdateUI(oPart); }
private void ProcessModules(Part oPart, PartVariant oVariant) { string sValue; string sDebug = ""; sValue = oVariant.GetExtraInfoValue("AddModule1"); for (int i = 2; !string.IsNullOrEmpty(sValue); i++) { oPart.AddModule(sValue); sValue = oVariant.GetExtraInfoValue("AddModule" + i.ToString()); } List <string> oRemoveModuleList = new List <string>(); sValue = oVariant.GetExtraInfoValue("RemoveModule1"); for (int i = 2; !string.IsNullOrEmpty(sValue); i++) { oRemoveModuleList.Add(sValue); sValue = oVariant.GetExtraInfoValue("RemoveModule" + i.ToString()); } foreach (PartModule oModule in oPart.Modules) { if (Debug.developerConsoleVisible) { sDebug = "Module Fields [" + oModule.moduleName + "]:\r\n"; } foreach (BaseField oField in oModule.Fields) { if (Debug.developerConsoleVisible) { sDebug += oField.name + "\r\n"; } sValue = oVariant.GetExtraInfoValue(oModule.moduleName + "/" + oField.name); if (!string.IsNullOrEmpty(sValue)) { oField.SetValue(Convert.ChangeType(sValue, oField.FieldInfo.FieldType), oField.host); if (Debug.developerConsoleVisible) { sDebug += " Appled: " + oField.name + " = " + sValue + "\r\n"; } } } if (Debug.developerConsoleVisible) { Debug.Log(sDebug); } } }
/// <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 the 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 static double CalculatePartVolume(AvailablePart avPart, PartVariant variant = null, ConfigNode partNode = null) { ModuleEquipmentItem itemModule = avPart.partPrefab?.Modules.OfType <ModuleEquipmentItem>().FirstOrDefault(); if (itemModule != null && itemModule.volume > 0) { return(itemModule.volume); // Ignore geometry } Vector3 boundsSize = GetPartBounds(avPart, variant, partNode); return(boundsSize.x * boundsSize.y * boundsSize.z * 1000); }
static internal void GetExtraInfo(PartVariant variant, ref float segmentHeight, ref float segmentWidth) { string strSegmentHeight = variant.GetExtraInfoValue("segmentHeight"); string strSegmentWidth = variant.GetExtraInfoValue("segmentWidth"); if (string.IsNullOrEmpty(strSegmentHeight) || string.IsNullOrEmpty(strSegmentWidth)) { return; } segmentHeight = float.Parse(strSegmentHeight); segmentWidth = float.Parse(strSegmentWidth); }
/// <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 the 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 double 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 boundsSize = GetPartBounds(avPart, variant: variant, partNode: partNode); return(boundsSize.x * boundsSize.y * boundsSize.z * 1000f); }
private void ReCalculateCostAndMass() { Log.dbg("VariantPartScaler.ReCalculateCostAndMass"); float costFactor = (float)this.ts.DryCostFactor; float massFactor = (float)this.ts.MassFactor; foreach (PartVariant p in this.part.variants.variantList) { PartVariant prefab = this.prefab.variants.variantList[this.prefab.variants.GetVariantIndex(p.Name)]; p.Cost = prefab.Cost * costFactor; p.Mass = prefab.Mass * massFactor; } }
private void onEditorVariantApplied(Part part, PartVariant variant) { if (part != base.part) { return; } ModSegSRBs.GetExtraInfo(variant, ref this.part.segmentHeight, ref this.part.segmentWidth); ScheduleSegmentUpdate("onEditorVariantApplied"); #if true MonoUtilities.RefreshContextWindows(part); #else MonoUtilities.RefreshPartContextWindow(part); #endif }