public void CleanManifest() { if (CrewAssignmentDialog.Instance != null) { VesselCrewManifest originalVesselManifest = CrewAssignmentDialog.Instance.GetManifest(); IList <PartCrewManifest> partCrewManifests = originalVesselManifest.GetCrewableParts(); if (partCrewManifests != null && partCrewManifests.Count > 0) { PartCrewManifest partManifest = partCrewManifests[0]; foreach (ProtoCrewMember crewMember in partManifest.GetPartCrew()) { if (crewMember != null) { // Clean the root part partManifest.RemoveCrewFromSeat(partManifest.GetCrewSeat(crewMember)); } } if (CrewRandRSettings.Instance != null && CrewRandRSettings.Instance.AssignCrews) { partManifest.AddCrewToOpenSeats(CrewRandR.Instance.GetCrewForPart(partManifest.PartInfo.partPrefab, new List <ProtoCrewMember>(), true)); } } CrewAssignmentDialog.Instance.RefreshCrewLists(originalVesselManifest, true, true); } }
private Crewable(Part part, PartCrewManifest manifest, int capacity) { this.part = part; this.manifest = manifest; Capacity = capacity; crewSlots = CrewSlot.GetSlots(part, manifest); }
//only run the following block in the editor; it updates the crew-assignment GUI private void UpdateCrewManifest() { Log.dbg("UpdateCrewManifest {0}", this.InstanceID); #if !CREW_SCALE_UP // Small safety guard. if (part.CrewCapacity >= this.scaler.prefab.CrewCapacity) { return; } #endif try // Preventing this thing triggering an eternal loop on the event handling! { VesselCrewManifest vcm = ShipConstruction.ShipManifest; if (vcm == null) { return; } PartCrewManifest pcm = vcm.GetPartCrewManifest(part.craftID); if (pcm == null) { return; } int len = pcm.partCrew.Length; //int newLen = Math.Min(part.CrewCapacity, _prefabPart.CrewCapacity); int newLen = part.CrewCapacity; if (len == newLen) { return; } Log.dbg("UpdateCrewManifest current {0}; new {1}", len, newLen); this.scaler.part.CrewCapacity = newLen; #if CREW_SCALE_UP #if PREFAB_SCALE_HACK // Workaround to try to force KSP to accept bigger crew manifests at editting time, as apparently it only respects the prefab's value, bluntly ignoring the part's data! this.scaler.prefab.CrewCapacity = Math.Max(this.scaler.prefab.CrewCapacity, this.scaler.part.CrewCapacity); #endif #else this.scaler.part.CrewCapacity = Math.Min(this.scaler.part.CrewCapacity, this.scaler.prefab.CrewCapacity); #endif if (EditorLogic.fetch.editorScreen == EditorScreen.Crew) { EditorLogic.fetch.SelectPanelParts(); } this.SetCrewManifestSize(pcm, newLen); ShipConstruction.ShipManifest.SetPartManifest(part.craftID, pcm); } catch (Exception e) { Log.error(e, this); } }
/// <summary> /// Copies crew assignments from the dialog to the ship construct. /// </summary> private void CopyCrew() { VesselCrewManifest dialogVessel = CurrentDialogContents; if (dialogVessel == null) { Logging.Error("No dialog manifest, can't copy"); return; } VesselCrewManifest currentVessel = ShipConstruction.ShipManifest; List <PartCrewManifest> dialogParts = dialogVessel.GetCrewableParts(); List <PartCrewManifest> currentParts = currentVessel.GetCrewableParts(); if (dialogParts.Count != currentParts.Count) { Logging.Error("Crew dialog has " + dialogParts.Count + " crewable parts, but vessel has only " + currentParts.Count + ". Can't copy."); return; } for (int partIndex = 0; partIndex < dialogParts.Count; ++partIndex) { PartCrewManifest dialogPart = dialogParts[partIndex]; PartCrewManifest currentPart = currentParts[partIndex]; ProtoCrewMember[] dialogCrew = dialogPart.GetPartCrew(); ProtoCrewMember[] currentCrew = currentPart.GetPartCrew(); if ((dialogPart.PartID != currentPart.PartID) || (dialogCrew.Length != currentCrew.Length)) { Logging.Error("Mismatched manifests at index " + partIndex + ", can't copy."); return; } for (int slotIndex = 0; slotIndex < dialogCrew.Length; ++slotIndex) { ProtoCrewMember dialogMember = dialogCrew[slotIndex]; ProtoCrewMember currentMember = currentCrew[slotIndex]; if (!AreSame(dialogMember, currentMember)) { Logging.Log("Crew change in " + currentPart.PartInfo.title + " slot " + slotIndex + ": " + DescribeCrew(currentMember) + " -> " + DescribeCrew(dialogMember)); currentPart.RemoveCrewFromSeat(slotIndex); if (dialogMember != null) { if (currentVessel.Contains(dialogMember)) { PartCrewManifest previousPart = currentVessel.GetPartForCrew(dialogMember); previousPart.RemoveCrewFromSeat(previousPart.GetCrewSeat(dialogMember)); } currentPart.AddCrewToSeat(dialogMember, slotIndex); } } // if there's an assignment difference } // for each slot in the part } // for each crewable part in the vessel }
private void UpdateCrewManifest() { if (!HighLogic.LoadedSceneIsEditor) { return; } //only run the following block in the editor; it updates the crew-assignment GUI VesselCrewManifest vcm = ShipConstruction.ShipManifest; if (vcm == null) { return; } PartCrewManifest pcm = vcm.GetPartCrewManifest(part.craftID); if (pcm == null) { return; } int len = pcm.partCrew.Length; int newLen = Math.Min(part.CrewCapacity, _prefabPart.CrewCapacity); if (len == newLen) { return; } if (EditorLogic.fetch.editorScreen == EditorScreen.Crew) { EditorLogic.fetch.SelectPanelParts(); } for (int i = 0; i < len; i++) { pcm.RemoveCrewFromSeat(i); } pcm.partCrew = new string[newLen]; for (int i = 0; i < newLen; i++) { pcm.partCrew[i] = string.Empty; } ShipConstruction.ShipManifest.SetPartManifest(part.craftID, pcm); }
/// <summary> /// Gets the crew slots for the specified part & manifest. /// </summary> /// <param name="part"></param> /// <param name="manifest"></param> /// <returns></returns> public static List <CrewSlot> GetSlots(Part part, PartCrewManifest manifest) { Assignment[] assignments = Assignment.GetSlotAssignments(part); int capacity = manifest.GetPartCrew().Length; if (assignments.Length != capacity) { throw new Exception("Mismatched capacity when making slots"); } List <CrewSlot> slots = new List <CrewSlot>(capacity); for (int index = 0; index < capacity; ++index) { slots.Add(new CrewSlot(assignments[index], manifest, index)); } return(slots); }
/// <summary> /// Copies crew assignments from the dialog to the ship construct. /// </summary> private void CopyCrew() { VesselCrewManifest dialogVessel = CurrentDialogContents; if (dialogVessel == null) { return; } VesselCrewManifest currentVessel = ShipConstruction.ShipManifest; List <PartCrewManifest> dialogParts = dialogVessel.GetCrewableParts(); List <PartCrewManifest> currentParts = currentVessel.GetCrewableParts(); if (dialogParts.Count != currentParts.Count) { return; } for (int partIndex = 0; partIndex < dialogParts.Count; ++partIndex) { PartCrewManifest dialogPart = dialogParts[partIndex]; PartCrewManifest currentPart = currentParts[partIndex]; ProtoCrewMember[] dialogCrew = dialogPart.GetPartCrew(); ProtoCrewMember[] currentCrew = currentPart.GetPartCrew(); if ((dialogPart.PartID != currentPart.PartID) || (dialogCrew.Length != currentCrew.Length)) { return; } for (int slotIndex = 0; slotIndex < dialogCrew.Length; ++slotIndex) { ProtoCrewMember dialogMember = dialogCrew[slotIndex]; ProtoCrewMember currentMember = currentCrew[slotIndex]; if (!AreSame(dialogMember, currentMember)) { currentPart.RemoveCrewFromSeat(slotIndex); if (dialogMember != null) { if (currentVessel.Contains(dialogMember)) { PartCrewManifest previousPart = currentVessel.GetPartForCrew(dialogMember); previousPart.RemoveCrewFromSeat(previousPart.GetCrewSeat(dialogMember)); } currentPart.AddCrewToSeat(dialogMember, slotIndex); } } // if there's an assignment difference } // for each slot in the part } // for each crewable part in the vessel }
/// <summary> /// Given a ship construct from the editor, get a list of crewables. Throws if /// there's an error. /// </summary> /// <param name="construct"></param> /// <returns></returns> public static List <Crewable> List(ShipConstruct construct) { // Get all the parts that are crewable List <Part> parts = new List <Part>(); foreach (Part part in construct.parts) { if (part.CrewCapacity > 0) { parts.Add(part); } } // Get all the crewable parts from the vessel manifest and hope like hell that they're in the same order List <PartCrewManifest> manifests = ShipConstruction.ShipManifest.GetCrewableParts(); if (parts.Count != manifests.Count) { throw new Exception("Mismatched lists: " + parts.Count + " crewable parts (out of " + construct.parts.Count + " total), " + manifests.Count + " part manifests"); } List <Crewable> crewables = new List <Crewable>(parts.Count); for (int index = 0; index < parts.Count; ++index) { Part part = parts[index]; PartCrewManifest manifest = manifests[index]; String partName = part.partInfo.name; String manifestName = manifest.PartInfo.name; if (!partName.Equals(manifestName)) { throw new Exception("Mismatch at index " + index + ": " + partName + " versus " + manifestName); } int partCapacity = part.CrewCapacity; int manifestCapacity = manifest.GetPartCrew().Length; if (partCapacity != manifestCapacity) { throw new Exception("Mismatched capacity for " + partName + ": " + partCapacity + " for part, " + manifestCapacity + " for manifest"); } crewables.Add(new Crewable(part, manifest, partCapacity)); } return(crewables); }
private void SetCrewManifestSize(PartCrewManifest pcm, int crewCapacity) { string[] newpartCrew = new string[crewCapacity]; { for (int i = 0; i < newpartCrew.Length; ++i) { newpartCrew[i] = string.Empty; } int SIZE = Math.Min(pcm.partCrew.Length, newpartCrew.Length); for (int i = 0; i < SIZE; ++i) { newpartCrew[i] = pcm.partCrew[i]; } for (int i = SIZE; i < pcm.partCrew.Length; ++i) { pcm.RemoveCrewFromSeat(i); } } pcm.partCrew = newpartCrew; }
public static IEnumerable <ProtoCrewMember> AddCrewToOpenSeats(this PartCrewManifest crewManifest, IEnumerable <ProtoCrewMember> crewMembers) { // crewManifest.GetPartCrew() is a statically-sized array with null elements IEnumerable <int> openSeatIndexes = crewManifest.GetPartCrew().Select((x, index) => new { x, index }).Where(x => x.x == null).Select(x => x.index); // Need to know the number of excluded elements int openSeatIndexesCount = openSeatIndexes.ToArray().Length; // Get the members we are going to assign IEnumerator <ProtoCrewMember> crewEnumerator = crewMembers.Take(openSeatIndexesCount).GetEnumerator(); #if DEBUG Logging.Debug("indexLength:" + openSeatIndexes.ToArray().Length); foreach (int i in openSeatIndexes) { Logging.Debug("indexes:" + i); } foreach (ProtoCrewMember crew in crewMembers.Take(openSeatIndexesCount)) { Logging.Debug("crew:" + crew.name); } #endif foreach (int index in openSeatIndexes) { if (crewEnumerator.MoveNext()) { crewManifest.AddCrewToSeat(crewEnumerator.Current, index); } else { return(crewMembers.Skip(openSeatIndexesCount));; } } // return the remainders return(crewMembers.Skip(openSeatIndexesCount));; }
private void SetupCrewManifest() { // Restores the original Crew Capacity, as the Pregab is mangled. this.scaler.part.CrewCapacity = this.OriginalCrewCapacity; VesselCrewManifest vcm = ShipConstruction.ShipManifest; if (vcm == null) { return; } PartCrewManifest pcm = vcm.GetPartCrewManifest(part.craftID); if (pcm == null) { return; } if (pcm.partCrew.Length != this.scaler.part.CrewCapacity) { this.SetCrewManifestSize(pcm, this.scaler.part.CrewCapacity); } }
void ScaleCrewCapacity() { // scale crew capacity (balancing: conserve mass/kerbal) var cOld = part.CrewCapacity; var cNew = (int)(_prefabPart.CrewCapacity * MassScale); if (cOld == cNew) { Debug.Log("CrewCapacity: old=new=" + cNew.ToString()); return; } part.CrewCapacity = cNew; if (HighLogic.LoadedSceneIsFlight) { return; } var manifests = ShipConstruction.ShipManifest.GetCrewableParts(); PartCrewManifest crew = null; for (int i = 0; i < manifests.StupidCount(); i++) { if (manifests[i].PartID == part.craftID) { crew = manifests[i]; break; } } if (crew == null) { Tools.LogWf("No PartManifest found!"); return; } if (cOld != crew.GetPartCrew().Count()) { Debug.Log("Crew mismatch: part=" + cOld + ", crew=" + crew.GetPartCrew().Count().ToString()); } //else Debug.Log("Manifest found"); // clear seats (just for safety) for (int i = 0; i < crew.GetPartCrew().Count(); i++) { if (crew.GetPartCrew()[i] != null) { Debug.Log("Removing seat:" + i.ToString() + crew.GetPartCrew()[i].name); crew.RemoveCrewFromSeat(i); } } //Debug.Log("Cleared seats"); // close crew tab (otherwise it will not update correctly) if (EditorLogic.fetch.editorScreen == EditorScreen.Crew) { EditorLogic.fetch.SelectPanelParts(); } FieldInfo[] fields = typeof(PartCrewManifest).GetFields(BindingFlags.NonPublic | BindingFlags.Instance); foreach (FieldInfo f in fields) { if (f.Name == "partCrew") { f.SetValue(crew, new string[cNew]); } } ShipConstruction.ShipManifest.SetPartManifest(part.craftID, crew); }
private CrewSlot(Assignment assignment, PartCrewManifest manifest, int index) { this.Assignment = assignment; this.manifest = manifest; this.slotIndex = index; }