/// <summary> /// This is called on each physics frame for the active vessel by reflection-magic from KSP. /// </summary> public void FixedUpdate() { if (!this.vessel.loaded) { return; } List <IPksCrewRequirement> allCrewableParts = this.vessel .FindPartModulesImplementing <IPksCrewRequirement>(); List <IPksCrewRequirement> activatedParts = allCrewableParts .Where(p => p.IsRunning) .ToList(); List <ProtoCrewMember> kspCrew = this.vessel.GetVesselCrew(); var crew = kspCrew.Select(c => new SkilledCrewman(c)).ToList(); int hash = activatedParts.Aggregate(0, (accumulator, part) => accumulator ^ part.RequiredEffect.GetHashCode() ^ part.RequiredLevel.GetHashCode()); hash = kspCrew.Aggregate(hash, (accumulator, kerbal) => accumulator ^ kerbal.GetHashCode()); if (hash == this.hashAtLastCheck) { return; } List <IPksCrewRequirement> unstaffableParts = CrewRequirement.FindUnstaffableParts(activatedParts, crew); if (unstaffableParts.Count > 0) { foreach (var part in activatedParts) { part.IsStaffed = !unstaffableParts.Contains(part); } } else { foreach (var part in activatedParts) { part.IsStaffed = true; } } this.hashAtLastCheck = hash; }
internal static IEnumerable <WarningMessage> CheckHasProperCrew(List <IPksCrewRequirement> parts, List <SkilledCrewman> crew) { List <IPksCrewRequirement> unstaffedParts = CrewRequirement.FindUnderstaffedParts(parts, crew).ToList(); if (unstaffedParts.Count > 0) { string list = string.Join(", ", unstaffedParts .Select(part => part.RequiredEffect) .Distinct() .SelectMany(effect => GameDatabase.Instance.ExperienceConfigs.GetTraitsWithEffect(effect)) .Distinct() .OrderBy(s => s) .ToArray()); yield return(new WarningMessage { Message = $"The ship doesn't have enough crew or insufficiently experienced crew to operate all its parts - add crew with these traits: {list}", IsClearlyBroken = false, FixIt = null }); } }