private void BalanceIntakes() { Queue<Part> intakeQueue = new Queue<Part>( _editor.ship.Parts.Where( x => GetPartType( x ) == PartType.Intake ) // do not treat intakeandengine parts as intake but as engine .OrderByDescending( x => x.Modules.OfType<ModuleResourceIntake>().First().area ) ); // queue is easier to handle when distributing items to engines - this makes sure we can only handle a part once Utils.Log( "Intakes found: {0}", string.Join( ", ", intakeQueue.Select( x => x.partInfo.title + ": " + x.Modules.OfType<ModuleResourceIntake>().First().area ).ToArray() ) ); List<WeightedPartList> totalPartList = new List<WeightedPartList>(); // so far all jets have intakeair ratio of 15, so we treat jets, turbos and rapiers alike // TODO for future: take intakeair ratio into account. how exactly? I donno :) // handle engines grouped by type, so far its by placement order foreach ( Part part in _editor.ship.parts ) { if ( GetPartType( part ) == PartType.AirBreatherEngine ) { WeightedPartList wpl = new WeightedPartList(); wpl.AddPart( part ); totalPartList.Add( wpl ); } else if ( GetPartType( part ) == PartType.IntakeAndEngine ) { WeightedPartList wpl = new WeightedPartList(); wpl.IntakeAreaSum = part.Modules.OfType<ModuleResourceIntake>().First().area; // add intake area of part that has both intake and engine in one wpl.AddPart( part ); totalPartList.Add( wpl ); } } Utils.Log( "Jets found: {0}", string.Join( ", ", totalPartList.Select( x => x.PartList.First().partInfo.title ).ToArray() ) ); if ( intakeQueue.Count > 0 && totalPartList.Count > 0 ) { // strip ship from intakes and jets _editor.ship.parts.RemoveAll( x => intakeQueue.Contains( x ) ); Utils.Log( "removed intakes temporarily" ); _editor.ship.parts.RemoveAll( x => totalPartList.Select( y => y.PartList.First() ).Contains( x ) ); Utils.Log( "removed jets temporarily" ); int intakeCount = intakeQueue.Count; for ( int i = 0; i < intakeCount; i++ ) { Part part = intakeQueue.Dequeue(); totalPartList.Where( x => x.IntakeAreaSum == totalPartList.Min( y => y.IntakeAreaSum ) ).First().AddPart( part ); // WeightedPartList with the least IntakeAreaSum will get the next intake assigned } // go through all part lists, reverse them and add them back to ship foreach ( WeightedPartList partList in totalPartList ) { partList.PartList.Reverse(); _editor.ship.parts.AddRange( partList.PartList ); // add parts for engine and its intakes back to ship Utils.Log( "Intake/engine set: {0}, total intake area: {1}", string.Join( ", ", partList.PartList.Select( x => x.name ).ToArray() ), partList.IntakeAreaSum ); } Utils.Log( "Finished intakes - jets balance" ); } else { Utils.Log( "There are either no intakes or no engines" ); } }
private void BalanceIntakes() { Queue <Part> intakeQueue = new Queue <Part>(_editor.ship.Parts.Where(x => GetPartType(x) == PartType.Intake) // do not treat intakeandengine parts as intake but as engine .OrderByDescending(x => x.Modules.OfType <ModuleResourceIntake>().First().area)); // queue is easier to handle when distributing items to engines - this makes sure we can only handle a part once Utils.Log("Intakes found: {0}", string.Join(", ", intakeQueue.Select(x => x.partInfo.title + ": " + x.Modules.OfType <ModuleResourceIntake>().First().area).ToArray())); List <WeightedPartList> totalPartList = new List <WeightedPartList>(); // so far all jets have intakeair ratio of 15, so we treat jets, turbos and rapiers alike // TODO for future: take intakeair ratio into account. how exactly? I donno :) // handle engines grouped by type, so far its by placement order foreach (Part part in _editor.ship.parts) { if (GetPartType(part) == PartType.AirBreatherEngine) { WeightedPartList wpl = new WeightedPartList(); wpl.AddPart(part); totalPartList.Add(wpl); } else if (GetPartType(part) == PartType.IntakeAndEngine) { WeightedPartList wpl = new WeightedPartList(); wpl.IntakeAreaSum = part.Modules.OfType <ModuleResourceIntake>().First().area; // add intake area of part that has both intake and engine in one wpl.AddPart(part); totalPartList.Add(wpl); } } Utils.Log("Jets found: {0}", string.Join(", ", totalPartList.Select(x => x.PartList.First().partInfo.title).ToArray())); if (intakeQueue.Count > 0 && totalPartList.Count > 0) { // strip ship from intakes and jets _editor.ship.parts.RemoveAll(x => intakeQueue.Contains(x)); Utils.Log("removed intakes temporarily"); _editor.ship.parts.RemoveAll(x => totalPartList.Select(y => y.PartList.First()).Contains(x)); Utils.Log("removed jets temporarily"); int intakeCount = intakeQueue.Count; for (int i = 0; i < intakeCount; i++) { Part part = intakeQueue.Dequeue(); totalPartList.Where(x => x.IntakeAreaSum == totalPartList.Min(y => y.IntakeAreaSum)).First().AddPart(part); // WeightedPartList with the least IntakeAreaSum will get the next intake assigned } // go through all part lists, reverse them and add them back to ship foreach (WeightedPartList partList in totalPartList) { partList.PartList.Reverse(); _editor.ship.parts.AddRange(partList.PartList); // add parts for engine and its intakes back to ship Utils.Log("Intake/engine set: {0}, total intake area: {1}", string.Join(", ", partList.PartList.Select(x => x.name).ToArray()), partList.IntakeAreaSum); } Utils.Log("Finished intakes - jets balance"); } else { Utils.Log("There are either no intakes or no engines"); } }