// 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(List <Part> parts, double theGravity, double theAtmosphere = 0, double theMach = 0, bool dumpTree = false, bool vectoredThrust = false, bool fullThrust = false)
{
LogMsg log = null;
if (SimManager.logOutput)
{
log = new LogMsg();
log.buf.AppendLine("PrepareSimulation started");
dumpTree = true;
}
this._timer.Start();
// Store the parameters in members for ease of access in other functions
this.partList = parts;
this.gravity = theGravity;
this.atmosphere = theAtmosphere;
this.mach = theMach;
this.lastStage = Staging.lastStage;
//MonoBehaviour.print("lastStage = " + lastStage);
// Clear the lists for our simulation parts
this.allParts.Clear();
this.allFuelLines.Clear();
this.drainingParts.Clear();
this.allEngines.Clear();
this.activeEngines.Clear();
this.drainingResources.Clear();
// A dictionary for fast lookup of Part->PartSim during the preparation phase
partSimLookup.Clear();
if (this.partList.Count > 0 && this.partList[0].vessel != null)
{
this.vesselName = this.partList[0].vessel.vesselName;
this.vesselType = this.partList[0].vessel.vesselType;
}
//MonoBehaviour.print("PrepareSimulation pool size = " + PartSim.pool.Count());
// First we create a PartSim for each Part (giving each a unique id)
int partId = 1;
for (int i = 0; i < this.partList.Count; i++)
{
Part part = this.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.buf.AppendLine("Part " + part.name + " appears in vessel list more than once");
}
continue;
}
// Create the PartSim
PartSim partSim = PartSim.New(part, partId, this.atmosphere, log);
// Add it to the Part lookup dictionary and the necessary lists
partSimLookup.Add(part, partSim);
this.allParts.Add(partSim);
if (partSim.isFuelLine)
{
this.allFuelLines.Add(partSim);
}
if (partSim.isEngine)
{
partSim.CreateEngineSims(this.allEngines, this.atmosphere, this.mach, vectoredThrust, fullThrust, log);
}
partId++;
}
this.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 < this.allParts.Count; i++)
{
PartSim partSim = this.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 < this.allFuelLines.Count; i++)
{
PartSim partSim = this.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.buf.AppendLine("Fuel line target is " + targetSim.name + ":" + targetSim.partId);
}
targetSim.fuelTargets.Add(partSim.parent);
}
else
{
if (log != null)
{
log.buf.AppendLine("No PartSim for fuel line target (" + partSim.part.partInfo.name + ")");
}
}
}
else
{
if (log != null)
{
log.buf.AppendLine("Fuel line target is null");
}
}
}
}
//MonoBehaviour.print("SetupAttachNodes and count stages");
for (int i = 0; i < this.allParts.Count; i++)
{
PartSim partSim = this.allParts[i];
partSim.SetupAttachNodes(partSimLookup, log);
if (partSim.decoupledInStage >= this.lastStage)
{
this.lastStage = partSim.decoupledInStage + 1;
}
}
// And finally release the Part references from all the PartSims
//MonoBehaviour.print("ReleaseParts");
for (int i = 0; i < this.allParts.Count; i++)
{
PartSim partSim = this.allParts[i];
partSim.ReleasePart();
}
// And dereference the core's part list
this.partList = null;
this._timer.Stop();
if (log != null)
{
log.buf.AppendLine("PrepareSimulation: " + this._timer.ElapsedMilliseconds + "ms");
log.Flush();
}
if (dumpTree)
{
this.Dump();
}
return(true);
}