Exemple #1
0
        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);
 }
Exemple #3
0
        //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
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        /// <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);
        }
Exemple #9
0
        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));;
        }
Exemple #11
0
        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);
            }
        }
Exemple #12
0
        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);
        }
Exemple #13
0
 private CrewSlot(Assignment assignment, PartCrewManifest manifest, int index)
 {
     this.Assignment = assignment;
     this.manifest   = manifest;
     this.slotIndex  = index;
 }