///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary> Executes the Kerbal status change action and if the Kerbal is found to be dead or MIA
        ///           then apply the reputation penalty.</summary>
        ///
        /// <param name="p">		  A ProtoCrewMember to process.</param>
        /// <param name="status_from"> The status from.</param>
        /// <param name="status_to">   The status to.</param>
        private void OnKerbalStatusChange(ProtoCrewMember p, ProtoCrewMember.RosterStatus status_from, ProtoCrewMember.RosterStatus status_to)
        {
            if (SpaceProgramFunding.Instance == null)
            {
                return;
            }

            if (SpaceProgramFunding.Instance.settings.kerbalDeathPenalty > 0)
            {
                return;
            }

            if (status_to != ProtoCrewMember.RosterStatus.Dead && status_to != ProtoCrewMember.RosterStatus.Missing)
            {
                return;
            }

            if (Reputation.CurrentRep < SpaceProgramFunding.Instance.settings.minimumRep)
            {
                return;
            }

            var actual_penalty = SpaceProgramFunding.Instance.settings.kerbalDeathPenalty * (p.experienceLevel + 1);

            if (actual_penalty > 0)
            {
                Reputation.Instance.AddReputation(-actual_penalty, TransactionReasons.ContractPenalty);
            }

            // Don't lower reputation below minimum
            if (Reputation.CurrentRep < SpaceProgramFunding.Instance.settings.minimumRep)
            {
                Reputation.Instance.SetReputation(SpaceProgramFunding.Instance.settings.minimumRep, TransactionReasons.Cheating);
            }
        }
Esempio n. 2
0
        private void OnKerbalStatusChange(ProtoCrewMember pcm, ProtoCrewMember.RosterStatus oldStatus, ProtoCrewMember.RosterStatus newStatus)
        {
            if (oldStatus == ProtoCrewMember.RosterStatus.Assigned && newStatus == ProtoCrewMember.RosterStatus.Available)
            {
                FlightLog tmpLog = new FlightLog();
                foreach (FlightLog.Entry entry in pcm.careerLog.Entries.Union(pcm.flightLog.Entries))
                {
                    tmpLog.AddEntry(entry);
                }

                float xp  = KerbalRoster.CalculateExperience(pcm.careerLog);
                float xp2 = KerbalRoster.CalculateExperience(tmpLog);

                float amount = (xp2 - xp) * multiplier;

                if (currency == Currency.Funds)
                {
                    Funding.Instance.AddFunds(amount, TransactionReasons.Strategies);
                }
                else if (currency == Currency.Reputation)
                {
                    Reputation.Instance.AddReputation(amount, TransactionReasons.Strategies);
                }
                else if (currency == Currency.Science)
                {
                    ResearchAndDevelopment.Instance.AddScience(amount, TransactionReasons.Strategies);
                }

                CurrencyPopup.Instance.AddPopup(currency, amount, TransactionReasons.Strategies, Parent.Config.Title, false);
            }
        }
Esempio n. 3
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary> Executes the Kerbal status change action and if the Kerbal is found to be dead or MIA
        ///           then apply the reputation penalty.</summary>
        ///
        /// <param name="p">		  A ProtoCrewMember to process.</param>
        /// <param name="statusFrom"> The status from.</param>
        /// <param name="statusTo">   The status to.</param>
        private void OnKerbalStatusChange(ProtoCrewMember p, ProtoCrewMember.RosterStatus statusFrom, ProtoCrewMember.RosterStatus statusTo)
        {
            if (BudgetSettings.Instance == null)
            {
                return;
            }

            if (!BudgetSettings.Instance.isKerbalDeathPenalty)
            {
                return;
            }

            if (statusTo != ProtoCrewMember.RosterStatus.Dead && statusTo != ProtoCrewMember.RosterStatus.Missing)
            {
                return;
            }

            var max_penalty    = Reputation.CurrentRep - BudgetSettings.Instance.minimumRep;
            var actual_penalty = Math.Min(BudgetSettings.Instance.kerbalDeathPenalty * (p.experienceLevel + 1), max_penalty);

            actual_penalty = Math.Max(actual_penalty, 0);
            if (actual_penalty > 0)
            {
                Reputation.Instance.AddReputation(-actual_penalty, TransactionReasons.VesselLoss);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Event triggered when any kerbal status changes (kerbal dies, etc)
        /// </summary>
        public void StatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus previousStatus, ProtoCrewMember.RosterStatus newStatus)
        {
            //Revert kerbal status in case we are setting it as dead/missing in KSC
            if (HighLogic.LoadedScene == GameScenes.SPACECENTER && newStatus > ProtoCrewMember.RosterStatus.Assigned)
            {
                System.SetKerbalStatusWithoutTriggeringEvent(kerbal, previousStatus);
            }

            if (previousStatus != newStatus)
            {
                var vesselId = System.FindVesselForKerbal(kerbal);

                if (vesselId == Guid.Empty)
                {
                    return;
                }

                if (vesselId == VesselLoader.ReloadingVesselId || LockSystem.LockQuery.UnloadedUpdateLockBelongsToPlayer(vesselId, SettingsSystem.CurrentSettings.PlayerName))
                {
                    System.SetKerbalStatusWithoutTriggeringEvent(kerbal, newStatus);
                    System.MessageSender.SendKerbal(kerbal);
                }
                else
                {
                    System.SetKerbalStatusWithoutTriggeringEvent(kerbal, previousStatus);
                }
            }
        }
Esempio n. 5
0
 public static void LogAchievement(Achievement achievement, ProtoCrewMember kerbal,
                                   ProtoCrewMember.RosterStatus oldState, ProtoCrewMember.RosterStatus newState)
 {
     Debug.Log("FF: ribbon achievement (roster status)");
     LogAchievement(achievement);
     Debug.Log("  - old state: " + oldState);
     Debug.Log("  - new state: " + newState);
     Debug.Log("+ - end -");
 }
Esempio n. 6
0
        /// <summary>
        /// Sets the kerbal status without triggering the event (usefull when receiveing kerbals from other clients)
        /// </summary>
        public void SetKerbalStatusWithoutTriggeringEvent(ProtoCrewMember crew, ProtoCrewMember.RosterStatus newStatus)
        {
            if (crew == null)
            {
                return;
            }

            KerbalStatusField?.SetValue(crew, newStatus);
        }
Esempio n. 7
0
 private void PotentialKerbalDeath(ProtoCrewMember crewMember, ProtoCrewMember.RosterStatus statusFrom, ProtoCrewMember.RosterStatus statusTo)
 {
     if (HighLogic.CurrentGame.Mode != Game.Modes.CAREER)
     {
         return;
     }
     //No need to check if the Kerbal hasn't died. Kerbals always go missing before they go dead, so just check for Missing.
     if (statusTo != ProtoCrewMember.RosterStatus.Missing)
     {
         return;
     }
     CrewManager.Instance.ProcessDeadKerbal(crewMember);
 }
Esempio n. 8
0
 private void OnKerbalStatusChange(ProtoCrewMember kerbal,
                                   ProtoCrewMember.RosterStatus old_status, ProtoCrewMember.RosterStatus new_status)
 {
     // Kerbals regularly change to Available, then back to Assigned
     // when in space, so can't use this method to track Kerbals in service
     if (new_status == ProtoCrewMember.RosterStatus.Dead ||
         new_status == ProtoCrewMember.RosterStatus.Missing)
     {
         Log("Call -> OnKerbalStatusChange(..) " + kerbal.name + ": " + old_status.ToString() + " -> " + new_status.ToString());
         Log("Clearing EVA LS info for " + kerbal.name);
         evals_info.Remove(kerbal.name);
     }
 }
Esempio n. 9
0
            private void CheckAchievementsForRosterStatus(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus oldState,
                                                          ProtoCrewMember.RosterStatus newState)
            {
                Log.Detail("EventObserver:: checkArchivements for roster status");
                Stopwatch sw = new Stopwatch();

                sw.Start();

                CheckAchievementsForRosterStatus(kerbal, oldState, newState, true);
                CheckAchievementsForRosterStatus(kerbal, oldState, newState, false);

                Log.Detail("EventObserver:: checkArchivements done in " + sw.ElapsedMilliseconds + " ms");
            }
Esempio n. 10
0
        /// <summary>
        /// Event triggered when any kerbal status changes (kerbal dies, etc)
        /// </summary>
        public void StatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus previousStatus, ProtoCrewMember.RosterStatus newStatus)
        {
            if (previousStatus != newStatus)
            {
                if (!LockSystem.LockQuery.CanEditKerbal(kerbal.name, SettingsSystem.CurrentSettings.PlayerName))
                {
                    System.SetKerbalStatusWithoutTriggeringEvent(kerbal, previousStatus);
                    return;
                }

                System.SetKerbalStatusWithoutTriggeringEvent(kerbal, newStatus);
                System.MessageSender.SendKerbal(kerbal);
            }
        }
Esempio n. 11
0
        void onKerbalStatusChange(ProtoCrewMember pcm, ProtoCrewMember.RosterStatus oldStatus, ProtoCrewMember.RosterStatus newStatus)
        {
            if (newStatus == oldStatus)
            {
                // KSP doesn't check before firing the event.
                return;
            }
            // Possible transitions (?):
            // Assigned->Available
            // Missing->Available
            // Available->Assigned
            // Missing->Dead
            // Assigned->Dead
            // Available->Dead (in theory. not in stock KSP)
            var      kerbal = ProgenyScenario.current.GetKerbal(kerbal_ids[pcm.name]);
            Location location;

            switch (newStatus)
            {
            case ProtoCrewMember.RosterStatus.Available:
                if (oldStatus == ProtoCrewMember.RosterStatus.Assigned)
                {
                    // Status gets thrashed a little while transfering
                    // (board, alight, transfer)
                    // Check the kerbal's status again next frame. If it
                    // is still Available, then the kerbal has been
                    // recovered
                    KerbalStats.current.StartCoroutine(WaitAndCheckStatus(pcm));
                    return;
                }
                // Look what the cat dragged in.
                break;

            case ProtoCrewMember.RosterStatus.Assigned:
                // Let onCrewTransferred or onVesselCreate handle it.
                // Mostly because there is no information on where the
                // kerbal has been assigned.
                break;

            case ProtoCrewMember.RosterStatus.Missing:
                location = ProgenyScenario.current.GetLocation("Wilds");
                kerbal.SetLocation(location);
                break;

            case ProtoCrewMember.RosterStatus.Dead:
                location = ProgenyScenario.current.GetLocation("Tomb");
                kerbal.SetLocation(location);
                break;
            }
        }
Esempio n. 12
0
 void onKerbalStatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus old_status, ProtoCrewMember.RosterStatus new_status)
 {
     if (kerbal.name == null || kerbal.name == "")
     {
         // premature event: the kerbal is still in the process of being
         // created by KSP
         return;
     }
     if (new_status == ProtoCrewMember.RosterStatus.Dead)
     {
         double UT = Planetarium.GetUniversalTime();
         ExperienceTracker.instance.FinishAllTasks(kerbal, UT);
     }
 }
Esempio n. 13
0
        /// <summary>
        /// Event triggered when any kerbal status changes (kerbal dies, etc)
        /// </summary>
        public void StatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus previousStatus, ProtoCrewMember.RosterStatus newStatus)
        {
            if (previousStatus != newStatus)
            {
                //This is the case when we are removing a vessel from another player. This status change event will be called
                if (LockSystem.LockQuery.KerbalLockExists(kerbal.name) && !LockSystem.LockQuery.KerbalLockBelongsToPlayer(kerbal.name, SettingsSystem.CurrentSettings.PlayerName))
                {
                    System.SetKerbalStatusWithoutTriggeringEvent(kerbal, previousStatus);
                    return;
                }

                System.SetKerbalStatusWithoutTriggeringEvent(kerbal, newStatus);
                System.MessageSender.SendKerbal(kerbal);
                System.RefreshCrewDialog();
            }
        }
Esempio n. 14
0
 private void CheckAchievementsForRosterStatus(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus oldState,
                                               ProtoCrewMember.RosterStatus newState, bool hasToBeFirst)
 {
     foreach (Ribbon ribbon in RibbonPool.Instance())
     {
         Achievement achievement = ribbon.GetAchievement();
         if (achievement.Check(kerbal, oldState, newState))
         {
             // record crew member only
             if (kerbal.IsCrew())
             {
                 recorder.Record(ribbon, kerbal);
             }
         }
     }
 }
Esempio n. 15
0
        public CrewMember(Type type, Roster rosterStatus, string name, Gender gender, string trait, bool veteran, bool isBadass, float courage, float stupidity, int experienceLevel, int activity = 0) : base(type, name)
        {
            Debug.Log("CrewMember", "new CrewMember (" + name + ") from stats");

            this.type            = type;
            this.rosterStatus    = rosterStatus;
            this.name            = name;
            this.gender          = gender;
            this.trait           = trait;
            this.veteran         = veteran;
            this.isBadass        = isBadass;
            this.courage         = courage;
            this.stupidity       = stupidity;
            this.experienceLevel = experienceLevel;
            this.activity        = activity;
        }
Esempio n. 16
0
 /// <summary>
 /// Event triggered when any kerbal status changes (kerbal dies, etc)
 /// </summary>
 public void StatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus previousStatus, ProtoCrewMember.RosterStatus newStatus)
 {
     if (previousStatus != newStatus)
     {
         var vesselId = System.FindVesselForKerbal(kerbal);
         if (vesselId == VesselLoader.ReloadingVesselId || LockSystem.LockQuery.UpdateLockBelongsToPlayer(vesselId, SettingsSystem.CurrentSettings.PlayerName) ||
             LockSystem.LockQuery.UnloadedUpdateLockBelongsToPlayer(vesselId, SettingsSystem.CurrentSettings.PlayerName))
         {
             System.SetKerbalStatusWithoutTriggeringEvent(kerbal, newStatus);
             System.MessageSender.SendKerbal(kerbal);
         }
         else
         {
             System.SetKerbalStatusWithoutTriggeringEvent(kerbal, previousStatus);
         }
     }
 }
        internal static void DisplaySelectState()
        {
            GUILayout.BeginHorizontal();
            // at first initialization in Create Mode, Selected Kerbal is null...
            _rosterStatus = SelectedKerbal == null ? ProtoCrewMember.RosterStatus.Available : SelectedKerbal.Status;
            if (SelectedKerbal != null && SelectedKerbal.SalaryContractDispute)
            {
                GUI.enabled = false;
            }
            GUILayout.Label("Status:", GUILayout.Width(80));

            var isAvailable = RosterStatus == ProtoCrewMember.RosterStatus.Available.ToString();

            isAvailable = GUILayout.Toggle(isAvailable, ProtoCrewMember.RosterStatus.Available.ToString(), GUILayout.Width(70));
            if (isAvailable)
            {
                _rosterStatus = ProtoCrewMember.RosterStatus.Available;
            }

            var isAssigned = RosterStatus == ProtoCrewMember.RosterStatus.Assigned.ToString();

            isAssigned = GUILayout.Toggle(isAssigned, ProtoCrewMember.RosterStatus.Assigned.ToString(), GUILayout.Width(70));
            if (isAssigned)
            {
                _rosterStatus = ProtoCrewMember.RosterStatus.Assigned;
            }

            var isMissing = RosterStatus == ProtoCrewMember.RosterStatus.Missing.ToString();

            isMissing = GUILayout.Toggle(isMissing, ProtoCrewMember.RosterStatus.Missing.ToString(), GUILayout.Width(70));
            if (isMissing)
            {
                _rosterStatus = ProtoCrewMember.RosterStatus.Missing;
            }

            var isDead = RosterStatus == ProtoCrewMember.RosterStatus.Dead.ToString();

            isDead = GUILayout.Toggle(isDead, ProtoCrewMember.RosterStatus.Dead.ToString(), GUILayout.Width(70));
            if (isDead)
            {
                _rosterStatus = ProtoCrewMember.RosterStatus.Dead;
            }

            GUI.enabled = true;
            GUILayout.EndHorizontal();
        }
        private static void RemoveOldVesselAndItsDebris(Vessel vessel, ProtoCrewMember.RosterStatus kerbalStatus)
        {
            if (vessel == null)
            {
                return;
            }

            if (FlightGlobals.ActiveVessel.isEVA)
            {
                var kerbal = HighLogic.CurrentGame.CrewRoster[FlightGlobals.ActiveVessel.vesselName];
                if (kerbal != null)
                {
                    kerbal.rosterStatus = kerbalStatus;
                }

                System.KillVessel(FlightGlobals.ActiveVessel.id, true, "Revert. Active vessel is a kerbal");
                System.MessageSender.SendVesselRemove(FlightGlobals.ActiveVessel);
            }

            //We detected a revert, now pick all the vessel parts (debris) that came from our main active
            //vessel and remove them both from our game and server
            var vesselsToRemove = FlightGlobals.Vessels
                                  .Where(v => v != null && v.rootPart && v.rootPart.missionID == vessel.rootPart.missionID && v.id != vessel.id).Distinct();

            foreach (var vesselToRemove in vesselsToRemove)
            {
                if (vesselToRemove.isEVA)
                {
                    var kerbal = HighLogic.CurrentGame.CrewRoster[vesselToRemove.vesselName];
                    if (kerbal != null)
                    {
                        kerbal.rosterStatus = kerbalStatus;
                    }
                }

                System.MessageSender.SendVesselRemove(vesselToRemove);

                //We consider this vessel removed but we let KSP do the remove of the vessel
                System.RemovedVessels.TryAdd(vesselToRemove.id, DateTime.Now);
                VesselCommon.RemoveVesselFromSystems(vesselToRemove.id);
            }
        }
Esempio n. 19
0
            private void OnKerbalStatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus oldState,
                                              ProtoCrewMember.RosterStatus newState)
            {
                if (kerbal == null)
                {
                    return;
                }
                Log.Info("kerbal status change: " + kerbal.name + " from " + oldState + " to " + newState + " at time " +
                         Planetarium.GetUniversalTime());
                HallOfFame.Instance().Refresh();
                //
                // check for achievements caused by status changes
                // (crew member only)

                /* not working because of the way KSP handles cre respawning
                 * if (kerbal.IsCrew())
                 * {
                 * Log.Detail("kerbal with status change is crew member");
                 * CheckAchievementsForRosterStatus(kerbal, oldState, newState);
                 * }*/
            }
Esempio n. 20
0
        public void onKerbalStatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus fromStatus, ProtoCrewMember.RosterStatus toStatus)
        {
            using (PooledStringBuilder sb = this.getStringBuilder())
            {
                string item;

                if (kerbal != null)
                {
                    item = kerbal.name;
                }
                else
                {
                    item = "null";
                }

                sb.AppendFormat("\n\tKerbal: {0}", item);

                sb.AppendFormat("\n\tfromStatus: {0}", Enum.GetName(typeof(ProtoCrewMember.RosterStatus), fromStatus));

                sb.AppendFormat("\n\ttoStatus: {0}", Enum.GetName(typeof(ProtoCrewMember.RosterStatus), toStatus));

                Debug.Log(sb.ToString());
            }
        }
Esempio n. 21
0
            private void DrawStatus(ProtoCrewMember kerbal)
            {
                ProtoCrewMember.RosterStatus status = kerbal.rosterStatus;
                string tooltip;

                switch (status)
                {
                case ProtoCrewMember.RosterStatus.Dead:
                case ProtoCrewMember.RosterStatus.Missing:
                    tooltip = kerbal.name + " is dead";
                    GUILayout.Label(new GUIContent(textureKilled, tooltip), styleKerbalStatus);
                    break;

                case ProtoCrewMember.RosterStatus.Assigned:
                    tooltip = kerbal.name + " is currently on a mission";
                    GUILayout.Label(new GUIContent(textureAssigned, tooltip), styleKerbalStatus);
                    break;

                default:
                    tooltip = kerbal.name + " is available for next mission";
                    GUILayout.Label(new GUIContent(textureAvailable, tooltip), styleKerbalStatus);
                    break;
                }
            }
            private void DrawStatus(ProtoCrewMember kerbal)
            {
                ProtoCrewMember.RosterStatus status = kerbal.rosterStatus;
                String tooltip;

                switch (status)
                {
                case ProtoCrewMember.RosterStatus.Dead:
                case ProtoCrewMember.RosterStatus.Missing:
                    tooltip = kerbal.name + " is dead";
                    GUILayout.Label(new GUIContent(TEXTURE_KILLED, tooltip), STYLE_KERBAL_STATUS);
                    break;

                case ProtoCrewMember.RosterStatus.Assigned:
                    tooltip = kerbal.name + " is currently on a mission";
                    GUILayout.Label(new GUIContent(TEXTURE_ASSIGNED, tooltip), STYLE_KERBAL_STATUS);
                    break;

                default:
                    tooltip = kerbal.name + " is available for next mission";
                    GUILayout.Label(new GUIContent(TEXTURE_AVAILABLE, tooltip), STYLE_KERBAL_STATUS);
                    break;
                }
            }
Esempio n. 23
0
 protected void OnKerbalStatusChange(ProtoCrewMember pcm, ProtoCrewMember.RosterStatus oldStatus, ProtoCrewMember.RosterStatus newStatus)
 {
     CheckStatus();
 }
Esempio n. 24
0
 internal Roster Parse(string s, Roster defaultValue)
 {
     try { return((Roster)Enum.Parse(typeof(Roster), s)); }
     catch { return(defaultValue); }
 }
Esempio n. 25
0
 private void OnKerbalStatusChange(ProtoCrewMember kerbal, ProtoCrewMember.RosterStatus oldState, ProtoCrewMember.RosterStatus newState)
 {
     Log.Info("kerbal status change: " + kerbal.name + " from " + oldState + " to " + newState);
     HallOfFame.Instance().UpdateKerbal(kerbal);
 }
Esempio n. 26
0
 public RMKerbal(double currentTime, ProtoCrewMember kerbal, bool isnew, bool modKerbal)
 {
     LastUpdate = currentTime;
     Kerbal     = kerbal;
     IsNew      = isnew;
     Name       = kerbal.name;
     if (isnew)
     {
         Trait      = kerbal.trait;
         Type       = kerbal.type;
         Status     = kerbal.rosterStatus;
         VesselId   = Guid.Empty;
         VesselName = string.Empty;
         double diceMinage = _rnd.Next(RMLifeSpan.Instance.RMGameSettings.MinimumAge - 3, RMLifeSpan.Instance.RMGameSettings.MinimumAge + 3); // Randomly set their age.
         Age = diceMinage;
         double diceMaxage = _rnd.Next(RMLifeSpan.Instance.RMGameSettings.MaximumAge - 5, RMLifeSpan.Instance.RMGameSettings.MaximumAge + 5); // Randomly set their age.
         Lifespan         = diceMaxage;
         TimelastBirthday = currentTime;
         TimeNextBirthday = BirthdayNextDue(currentTime);
         Timelastsalary   = currentTime;
         TimeSalaryDue    = SalaryNextDue(currentTime);
         Salary           = RMLifeSpan.Instance.RMGameSettings.DefaultSalary;
         if (Api.InstalledMods.IsDfInstalled)
         {
             if (kerbal.rosterStatus == ProtoCrewMember.RosterStatus.Dead && kerbal.type == ProtoCrewMember.KerbalType.Unowned) // if they are frozen store time frozen
             {
                 if (RMAddon.FrozenKerbals.ContainsKey(kerbal.name))
                 {
                     TimeDfFrozen = RMAddon.FrozenKerbals[kerbal.name].LastUpdate;
                 }
             }
         }
         Name       = kerbal.name;
         Stupidity  = kerbal.stupidity;
         Courage    = kerbal.courage;
         Badass     = kerbal.isBadass;
         Gender     = kerbal.gender;
         Suit       = kerbal.suit;
         Skill      = kerbal.experienceLevel;
         Experience = kerbal.experience;
         Kerbal     = kerbal;
     }
     if (!modKerbal)
     {
         return;
     }
     Stupidity = kerbal.stupidity;
     Courage   = kerbal.courage;
     Badass    = kerbal.isBadass;
     if (SalaryContractDispute)
     {
         RealTrait = kerbal.trait;
         Trait     = "Tourist";
         KerbalRoster.SetExperienceTrait(kerbal, Trait);
     }
     else
     {
         if (Status == ProtoCrewMember.RosterStatus.Assigned)
         {
             UnregisterExperienceTrait(this);
         }
         Trait     = kerbal.trait;
         RealTrait = kerbal.trait;
         KerbalRoster.SetExperienceTrait(kerbal, Trait);
         if (Status == ProtoCrewMember.RosterStatus.Assigned)
         {
             RegisterExperienceTrait(this);
         }
     }
     Gender     = kerbal.gender;
     Suit       = kerbal.suit;
     Skill      = kerbal.experienceLevel;
     Experience = kerbal.experience;
 }