public void Load(ConfigNode node) { if (node.name == "CONTENT" && node.HasValue("qty")) { pristine_count += int.Parse(node.GetValue("qty")); } else if (node.name == "CONTENT_PART" && node.HasValue("kas_total_mass")) { ConfigNode nodeD = new ConfigNode(); node.CopyTo(nodeD); // Backward compatibility: compute the cost and save it if (!nodeD.HasValue("kas_total_cost")) { var snapshot = KAS_Shared.LoadProtoPartSnapshot(nodeD); float dry_cost, fuel_cost; float total_cost = ShipConstruction.GetPartCosts(snapshot, part, out dry_cost, out fuel_cost); nodeD.AddValue("kas_total_cost", total_cost); } instance_mass += float.Parse(nodeD.GetValue("kas_total_mass")); instance_cost += float.Parse(nodeD.GetValue("kas_total_cost")); instances.Add(nodeD); } }
public static Part LoadPartSnapshot(Vessel vessel, ConfigNode node, Vector3 position, Quaternion rotation) { ProtoPartSnapshot snapshot = KAS_Shared.LoadProtoPartSnapshot(node); if (HighLogic.CurrentGame.flightState.ContainsFlightID(snapshot.flightID)) { snapshot.flightID = ShipConstruction.GetUniqueFlightID(HighLogic.CurrentGame.flightState); } snapshot.parentIdx = 0; snapshot.position = position; snapshot.rotation = rotation; snapshot.stageIndex = 0; snapshot.defaultInverseStage = 0; snapshot.seqOverride = -1; snapshot.inStageIndex = -1; snapshot.attachMode = (int)AttachModes.SRF_ATTACH; snapshot.attached = true; snapshot.flagURL = vessel.rootPart.flagURL; // Save properties that may be messed up by new colliders RigidbodyInertia rb_backup = new RigidbodyInertia(vessel.rootPart.rb); Part new_part = snapshot.Load(vessel, false); vessel.Parts.Add(new_part); if (vessel.packed) { GameEvents.onVesselWasModified.Fire(vessel); } else { // Request initialization as nonphysical to prevent explosions new_part.physicalSignificance = Part.PhysicalSignificance.NONE; // Disable all sub-objects with colliders List <Collider> re_enable = new List <Collider>(); foreach (var collider in new_part.GetComponentsInChildren <Collider>()) { if (collider.gameObject.activeSelf) { re_enable.Add(collider); collider.gameObject.SetActive(false); } } new_part.StartCoroutine(WaitAndUnpack(new_part, re_enable)); } rb_backup.Restore(vessel.rootPart.rb); return(new_part); }
public float GetModuleCost() { float result = 0.0f; Dictionary <string, PartContent> contents = this.GetContent(); // Iterate through the contents, of which there may be multiple of each part. foreach (PartContent partContent in contents.Values) { // Iterate through all of the instances of this part. (stateless = false) foreach (ConfigNode partConfigNode in partContent.instances) { ProtoPartSnapshot partSnapshot = KAS_Shared.LoadProtoPartSnapshot(partConfigNode); // Add the base cost and the calculated module costs for this specific instance, in case one or more modules need to // adjust the part's cost based on this instance's saved state. float instancedPartCost = partContent.part.cost + partSnapshot.moduleCosts; foreach (ProtoPartResourceSnapshot resourceSnapshot in partSnapshot.resources) { float amount = float.Parse(resourceSnapshot.resourceValues.GetValue("amount")); float maxAmount = float.Parse(resourceSnapshot.resourceValues.GetValue("maxAmount")); PartResourceDefinition resourceDefinition = PartResourceLibrary.Instance.GetDefinition(resourceSnapshot.resourceName); // Add the resource cost, which if amount != maxAmount will actually be a negative number because the base part cost // includes the cost of maxAmount of the resource. instancedPartCost += this.CalculateResourceCost(resourceDefinition, amount, maxAmount); } result += instancedPartCost; } // The rest of the parts are pristine and have a common base cost. float singlePartCost = partContent.part.cost + partContent.part.partPrefab.GetModuleCosts(); // And the pristine parts have a common resource cost. foreach (PartResource partResource in partContent.part.partPrefab.Resources) { // NOTE: See comment on the above CalculateResourceCost call. singlePartCost += this.CalculateResourceCost(partResource.info, (float)partResource.amount, (float)partResource.maxAmount); } // Tack on the total cost of the pristine parts. result += singlePartCost * partContent.pristine_count; } return(result); }
private List <ScienceData> RecoverScienceContent() { List <ScienceData> result = new List <ScienceData>(); Dictionary <string, PartContent> contents = this.GetContent(); // Iterate through the contents, of which there may be multiple of each part. foreach (PartContent partContent in contents.Values) { // Iterate through all of the instances of this part. (stateless = false) foreach (ConfigNode partConfigNode in partContent.instances) { ProtoPartSnapshot partSnapshot = KAS_Shared.LoadProtoPartSnapshot(partConfigNode); foreach (ProtoPartModuleSnapshot moduleSnapshot in partSnapshot.modules) { // In order to load the state of the module, it must be added to a part. Temporarily add it to this // module's host part and then remove it after it is evaluated. int moduleIndex = this.part.Modules.Count; part.AddModule(moduleSnapshot.moduleName); PartModule module = moduleSnapshot.Load(this.part, ref moduleIndex); // ModuleScienceExperiment and ModuleScienceContainer implement IScienceDataContainer. Also, because KASModuleContainer // now implements IScienceDataContainer, it is conceivable that nested KAS containers with science data will be properly // recovered. if (module is IScienceDataContainer) { IScienceDataContainer scienceDataContainer = (IScienceDataContainer)module; // Duplicate science experiments are OK, the science awards are evaluated correctly by KSP. result.AddRange(scienceDataContainer.GetData()); } this.part.RemoveModule(module); } } } return(result); }