public void Update(Vessel vessel) { this.currentStats = RecordingVesselStats.GetStats(this, vessel); this.vessel = vessel; // Set launch-values: if (this.status == FlightRecordingStatus.PRELAUNCH) { this.launchCost = this.currentStats.cost; this.launchMass = this.currentStats.mass; if (this.currentStats.hasCrew) { this.mustReturn = true; } else { this.mustReturn = false; } } // When in orbit, set the maximum altitude for future missions: if (this.status == FlightRecordingStatus.ASCENDING) { if (vessel.situation == Vessel.Situations.ORBITING && vessel.orbit.referenceBody.bodyName == launchBodyName) { this.maxAltitude = vessel.orbit.PeA; // Current periapsis } else { this.maxAltitude = 0; } } }
// Gathers all important current stats for the given vessel (eg its mass, price, etc): public static RecordingVesselStats GetStats(FlightRecording recording, Vessel vessel) { RecordingVesselStats stats = new RecordingVesselStats(); stats.hasCrew = vessel.GetCrewCount() > 0; stats.payloadResources = new Dictionary <string, PayloadResource>(); stats.dockingPortTypes = new List <string>(); foreach (Part part in vessel.parts) { string partName = SanitizeParteName(part.name); // Check for modules which enable the vessel to perform certain actions: List <ModuleDockingNode> dockingNodes = part.FindModulesImplementing <ModuleDockingNode>(); if (dockingNodes.Count() > 0) { stats.hasDockingPort = true; foreach (ModuleDockingNode dockingNode in dockingNodes) { if (!stats.dockingPortTypes.Contains(dockingNode.nodeType.ToString())) { stats.dockingPortTypes.Add(dockingNode.nodeType.ToString()); // Docking-nodes have differnt sizes, like "node0", "node1", etc } } } if (part.FindModulesImplementing <ModuleDecouple>().Count() > 0) { stats.hasSeperator = true; } if (part.FindModulesImplementing <ModuleAnchoredDecoupler>().Count() > 0) { stats.hasSeperator = true; } if (part.FindModulesImplementing <ModuleRCS>().Count() > 0) { stats.hasRCS = true; } // Mass of the part and its resources: stats.mass += part.mass + part.resourceMass; // Sum up all the parts resources: double resourceCost = 0; double resourceCostMax = 0; foreach (PartResource resource in part.Resources) { PartResourceDefinition resourceDefinition = null; if (!KSTS.resourceDictionary.TryGetValue(resource.resourceName.ToString(), out resourceDefinition)) { Debug.LogError("[KSTS] RecordingVesselStats.GetStats(): resource '" + resource.resourceName.ToString() + "' not found in dictionary"); } else { // Cost: resourceCost += (double)(resource.amount * resourceDefinition.unitCost); resourceCostMax += (double)(resource.maxAmount * resourceDefinition.unitCost); // Track remaining amout for payload delivery (only resources which have a weight): if (resourceDefinition.density > 0 && resource.amount > 0) { PayloadResource payloadResource = null; if (stats.payloadResources.TryGetValue(resource.resourceName.ToString(), out payloadResource)) { stats.payloadResources.Remove(resource.resourceName.ToString()); payloadResource.amount += resource.amount; } else { payloadResource = new PayloadResource(); payloadResource.amount = resource.amount; payloadResource.name = resource.resourceName.ToString(); payloadResource.mass = resourceDefinition.density; } stats.payloadResources.Add(resource.resourceName.ToString(), payloadResource); } } } stats.cost += resourceCost; // The cost of the part is only available in the AvailablePart-class: AvailablePart availablePart = null; if (!KSTS.partDictionary.TryGetValue(partName, out availablePart)) { Debug.LogError("[KSTS] RecordingVesselStats.GetStats(): part '" + partName + "' not found in dictionary"); } else { // The cost of the part already includes the resource-costs, when completely filled: double dryCost = availablePart.cost - resourceCostMax; stats.cost += dryCost; } } // Find all crewed parts: List <string> crewedPartIds = new List <string>(); foreach (ProtoCrewMember crewMember in vessel.GetVesselCrew()) { if (crewMember.seat == null || crewMember.seat.part == null) { continue; } if (crewedPartIds.Contains(crewMember.seat.part.flightID.ToString())) { continue; } crewedPartIds.Add(crewMember.seat.part.flightID.ToString()); } // Find all valid subassemblies, which can be detached from the control-part: stats.payloadAssemblies = new Dictionary <string, PayloadAssembly>(); stats.FindPayloadAssemblies(recording, vessel.rootPart, null, crewedPartIds); return(stats); }