KerbalEngineer.VesselSimulator.PartSim.New C# (CSharp) Method

New() public static method

public static New ( Part p, int id, double atmosphere, LogMsg log ) : PartSim
p Part
id int
atmosphere double
log LogMsg
return PartSim
        public static PartSim New(Part p, int id, double atmosphere, LogMsg log)
        {
            PartSim partSim = pool.Borrow();

            partSim.part = p;
            partSim.centerOfMass = p.transform.TransformPoint(p.CoMOffset);
            partSim.partId = id;
            partSim.name = p.partInfo.name;

            if (log != null) log.AppendLine("Create PartSim for ", partSim.name);

            partSim.parent = null;
            partSim.parentAttach = p.attachMode;
            partSim.fuelCrossFeed = p.fuelCrossFeed;
            partSim.noCrossFeedNodeKey = p.NoCrossFeedNodeKey;
            partSim.decoupledInStage = partSim.DecoupledInStage(p);
            partSim.isFuelLine = p.HasModule<CModuleFuelLine>();
            partSim.isSepratron = partSim.IsSepratron();
            partSim.inverseStage = p.inverseStage;
            if (log != null) log.AppendLine("inverseStage = ", partSim.inverseStage);
            partSim.resPriorityOffset = p.resourcePriorityOffset;
            partSim.resPriorityUseParentInverseStage = p.resourcePriorityUseParentInverseStage;
            partSim.resRequestRemainingThreshold = p.resourceRequestRemainingThreshold;

            partSim.baseCost = p.GetCostDry();

            if (log != null) log.AppendLine("Parent part = ", (p.parent == null ? "null" : p.parent.partInfo.name))
                                .AppendLine("physicalSignificance = ", p.physicalSignificance)
                                .AppendLine("PhysicsSignificance = ", p.PhysicsSignificance);

            // Work out if the part should have no physical significance
            // The root part is never "no physics"
            partSim.isNoPhysics = p.physicalSignificance == Part.PhysicalSignificance.NONE ||
                                    p.PhysicsSignificance == 1;

            if (p.HasModule<LaunchClamp>())
            {
                partSim.realMass = 0d;
                if (log != null) log.AppendLine("Ignoring mass of launch clamp");
            }
            else
            {
                partSim.realMass = p.mass;
                if (log != null) log.AppendLine("Using part.mass of ", p.mass);
            }

            partSim.postStageMassAdjust = 0f;
            if (log != null) log.AppendLine("Calculating postStageMassAdjust, prefabMass = ", p.prefabMass);
            int count = p.Modules.Count;
            for (int i = 0; i < count; i++)
            {
                if (log != null) log.AppendLine("Module: ", p.Modules[i].moduleName);
                IPartMassModifier partMassModifier = p.Modules[i] as IPartMassModifier;
                if (partMassModifier != null)
                {
                    if (log != null) log.AppendLine("ChangeWhen = ", partMassModifier.GetModuleMassChangeWhen());
                    if (partMassModifier.GetModuleMassChangeWhen() == ModifierChangeWhen.STAGED)
                    {
                        float preStage = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.UNSTAGED);
                        float postStage = partMassModifier.GetModuleMass(p.prefabMass, ModifierStagingSituation.STAGED);
                        if (log != null) log.AppendLine("preStage = ", preStage, "   postStage = ", postStage);
                        partSim.postStageMassAdjust += (postStage - preStage);
                    }
                }
            }
            if (log != null) log.AppendLine("postStageMassAdjust = ", partSim.postStageMassAdjust);

            for (int i = 0; i < p.Resources.Count; i++)
            {
                PartResource resource = p.Resources[i];

                // Make sure it isn't NaN as this messes up the part mass and hence most of the values
                // This can happen if a resource capacity is 0 and tweakable
                if (!Double.IsNaN(resource.amount))
                {
                    if (log != null) log.AppendLine(resource.resourceName, " = ", resource.amount);

                    partSim.resources.Add(resource.info.id, resource.amount);
                    partSim.resourceFlowStates.Add(resource.info.id, resource.flowState ? 1 : 0);
                }
                else
                {
                    if (log != null) log.AppendLine(resource.resourceName, " is NaN. Skipping.");
                }
            }

            partSim.hasVessel = (p.vessel != null);
            partSim.isLanded = partSim.hasVessel && p.vessel.Landed;
            if (partSim.hasVessel)
            {
                partSim.vesselName = p.vessel.vesselName;
                partSim.vesselType = p.vesselType;
            }
            partSim.initialVesselName = p.initialVesselName;

            partSim.hasMultiModeEngine = p.HasModule<MultiModeEngine>();
            partSim.hasModuleEngines = p.HasModule<ModuleEngines>();

            partSim.isEngine = partSim.hasMultiModeEngine || partSim.hasModuleEngines;

            if (log != null) log.AppendLine("Created ", partSim.name, ". Decoupled in stage ", partSim.decoupledInStage);

            return partSim;
        }

Usage Example

コード例 #1
0
        // This function prepares the simulation by creating all the necessary data structures it will
        // need during the simulation.  All required data is copied from the core game data structures
        // so that the simulation itself can be run in a background thread without having issues with
        // the core game changing the data while the simulation is running.
        public bool PrepareSimulation(LogMsg _log, List <Part> parts, double theGravity, double theAtmosphere = 0, double theMach = 0, bool dumpTree = false, bool vectoredThrust = false, bool fullThrust = false)
        {
            log = _log;
            if (log != null)
            {
                log.AppendLine("PrepareSimulation started");
            }

            _timer.Reset();
            _timer.Start();

            // Store the parameters in members for ease of access in other functions
            partList   = parts;
            gravity    = theGravity;
            atmosphere = theAtmosphere;
            mach       = theMach;
            lastStage  = StageManager.LastStage;
            maxMach    = 1.0f;
            if (log != null)
            {
                log.AppendLine("lastStage = ", lastStage);
            }

            // Clear the lists for our simulation parts
            allParts.Clear();
            allFuelLines.Clear();
            drainingParts.Clear();
            allEngines.Clear();
            activeEngines.Clear();
            drainingResources.Clear();

            // A dictionary for fast lookup of Part->PartSim during the preparation phase
            partSimLookup.Clear();

            if (partList.Count > 0 && partList[0].vessel != null)
            {
                vesselName = partList[0].vessel.vesselName;
                vesselType = partList[0].vessel.vesselType;
            }
            // First we create a PartSim for each Part (giving each a unique id)
            int partId = 1;

            for (int i = 0; i < partList.Count; ++i)
            {
                Part part = partList[i];

                // If the part is already in the lookup dictionary then log it and skip to the next part
                if (partSimLookup.ContainsKey(part))
                {
                    if (log != null)
                    {
                        log.AppendLine("Part ", part.name, " appears in vessel list more than once");
                    }
                    continue;
                }

                // Create the PartSim
                PartSim partSim = PartSim.New(part, partId, atmosphere, log);

                // Add it to the Part lookup dictionary and the necessary lists
                partSimLookup.Add(part, partSim);
                allParts.Add(partSim);

                if (partSim.isFuelLine)
                {
                    allFuelLines.Add(partSim);
                }

                if (partSim.isEngine)
                {
                    partSim.CreateEngineSims(allEngines, atmosphere, mach, vectoredThrust, fullThrust, log);
                }

                if (partSim.isRCS)
                {
                    partSim.CreateRCSSims(allRCS, atmosphere, mach, vectoredThrust, fullThrust, log);
                }

                partId++;
            }

            for (int i = 0; i < allEngines.Count; ++i)
            {
                maxMach = Mathf.Max(maxMach, allEngines[i].maxMach);
            }

            UpdateActiveEngines();

            // Now that all the PartSims have been created we can do any set up that needs access to other parts
            // First we set up all the parent links
            for (int i = 0; i < allParts.Count; i++)
            {
                PartSim partSim = allParts[i];
                partSim.SetupParent(partSimLookup, log);
            }

            // Then, in the VAB/SPH, we add the parent of each fuel line to the fuelTargets list of their targets
            if (HighLogic.LoadedSceneIsEditor)
            {
                for (int i = 0; i < allFuelLines.Count; ++i)
                {
                    PartSim partSim = allFuelLines[i];

                    CModuleFuelLine fuelLine = partSim.part.GetModule <CModuleFuelLine>();
                    if (fuelLine.target != null)
                    {
                        PartSim targetSim;
                        if (partSimLookup.TryGetValue(fuelLine.target, out targetSim))
                        {
                            if (log != null)
                            {
                                log.AppendLine("Fuel line target is ", targetSim.name, ":", targetSim.partId);
                            }

                            targetSim.fuelTargets.Add(partSim.parent);
                        }
                        else
                        {
                            if (log != null)
                            {
                                log.AppendLine("No PartSim for fuel line target (", partSim.part.partInfo.name, ")");
                            }
                        }
                    }
                    else
                    {
                        if (log != null)
                        {
                            log.AppendLine("Fuel line target is null");
                        }
                    }
                }
            }

            if (log != null)
            {
                log.AppendLine("SetupAttachNodes and count stages");
            }
            for (int i = 0; i < allParts.Count; ++i)
            {
                PartSim partSim = allParts[i];

                partSim.SetupAttachNodes(partSimLookup, log);
                if (partSim.decoupledInStage >= lastStage)
                {
                    lastStage = partSim.decoupledInStage + 1;
                }
            }

            // And finally release the Part references from all the PartSims
            if (log != null)
            {
                log.AppendLine("ReleaseParts");
            }
            for (int i = 0; i < allParts.Count; ++i)
            {
                allParts[i].ReleasePart();
            }

            // And dereference the core's part list
            partList = null;

            _timer.Stop();
            if (log != null)
            {
                log.AppendLine("PrepareSimulation: ", _timer.ElapsedMilliseconds, "ms");
                log.Flush();
            }

            Dump();
            log = null;

            return(true);
        }
All Usage Examples Of KerbalEngineer.VesselSimulator.PartSim::New