示例#1
0
        public void AddPartCourses(AvailablePart ap, bool isKCTExperimentalNode = false)
        {
            if (ap.partPrefab.isVesselEVA || ap.name.StartsWith("kerbalEVA", StringComparison.OrdinalIgnoreCase) ||
                ap.partPrefab.Modules.Contains <KerbalSeat>() ||
                ap.partPrefab.Modules.Contains <LaunchClamp>() || ap.partPrefab.HasTag("PadInfrastructure"))
            {
                return;
            }

            TrainingDatabase.SynonymReplace(ap.name, out string name);
            if (!_partSynsHandled.TryGetValue(name, out var coursePair))
            {
                bool isPartUnlocked = !isKCTExperimentalNode && ResearchAndDevelopment.GetTechnologyState(ap.TechRequired) == RDTech.State.Available;

                CourseTemplate profCourse = GenerateCourseProf(ap, !isPartUnlocked);
                AppendToPartTooltip(ap, profCourse);
                CourseTemplate missionCourse = null;
                if (isPartUnlocked && IsMissionTrainingEnabled)
                {
                    missionCourse = GenerateCourseMission(ap);
                    AppendToPartTooltip(ap, missionCourse);
                }
                _partSynsHandled.Add(name, new Tuple <CourseTemplate, CourseTemplate>(profCourse, missionCourse));
            }
            else
            {
                CourseTemplate pc = coursePair.Item1;
                CourseTemplate mc = coursePair.Item2;
                AppendToPartTooltip(ap, pc);
                if (mc != null)
                {
                    AppendToPartTooltip(ap, mc);
                }
            }
        }
示例#2
0
        private CourseTemplate GenerateCourseMission(AvailablePart ap)
        {
            var  n     = new ConfigNode("FS_COURSE");
            bool found = TrainingDatabase.SynonymReplace(ap.name, out string name);

            n.AddValue("id", "msn_" + name);
            n.AddValue("name", "Mission: " + (found ? name : ap.title));
            n.AddValue("time", 1 + TrainingDatabase.GetTime(name + "-Mission") * Config.hoursPerDay * 3600);
            n.AddValue("isTemporary", false);
            n.AddValue("timeUseStupid", true);
            n.AddValue("seatMax", ap.partPrefab.CrewCapacity * 2);
            n.AddValue("expiration", Settings.trainingMissionExpirationDays * Config.hoursPerDay * 3600);
            n.AddValue("preReqs", $"{TrainingType_Proficiency}:{name}");

            ConfigNode r = n.AddNode("REWARD");
            ConfigNode l = r.AddNode("FLIGHTLOG");

            l.AddValue("0", $"{TrainingType_Mission},{name}");

            var c = new CourseTemplate(n);

            c.PopulateFromSourceNode();
            OfferedCourses.Add(c);

            return(c);
        }
示例#3
0
        private CourseTemplate GenerateCourseProf(AvailablePart ap, bool isTemporary)
        {
            var  n     = new ConfigNode("FS_COURSE");
            bool found = TrainingDatabase.SynonymReplace(ap.name, out string name);

            n.AddValue("id", "prof_" + name);
            n.AddValue("name", "Proficiency: " + (found ? name : ap.title));
            n.AddValue("time", 1d + (TrainingDatabase.GetTime(name) * Config.hoursPerDay * 3600));
            n.AddValue("isTemporary", isTemporary);
            n.AddValue("conflicts", $"{TrainingType_Proficiency}:{name}");

            ConfigNode r = n.AddNode("REWARD");

            r.AddValue("XPAmt", Settings.trainingProficiencyXP);
            ConfigNode l = r.AddNode("FLIGHTLOG");

            l.AddValue("0", $"{TrainingType_Proficiency},{name}");

            var c = new CourseTemplate(n);

            c.PopulateFromSourceNode();
            OfferedCourses.Add(c);

            return(c);
        }
示例#4
0
        private void GenerateOfferedCourses()
        {
            Profiler.BeginSample("LRTR GenerateOfferedCourses");
            OfferedCourses.Clear();
            _partSynsHandled.Clear();

            if (!CurrentSceneAllowsCrewManagement)
            {
                return;                                       // Course UI is only available in those 2 scenes so no need to generate them for any other
            }
            //convert the saved configs to course offerings
            foreach (CourseTemplate template in CourseTemplates)
            {
                var duplicate = new CourseTemplate(template.sourceNode, true); //creates a duplicate so the initial template is preserved
                duplicate.PopulateFromSourceNode();
                if (duplicate.Available)
                {
                    OfferedCourses.Add(duplicate);
                }
            }

            foreach (AvailablePart ap in PartLoader.LoadedPartsList)
            {
                if (!ap.TechHidden && ap.partPrefab.CrewCapacity > 0 &&
                    ResearchAndDevelopment.GetTechnologyState(ap.TechRequired) == RDTech.State.Available)
                {
                    AddPartCourses(ap);
                }
            }
            Profiler.EndSample();
        }
示例#5
0
        private void GenerateOfferedCourses()
        {
            //convert the saved configs to course offerings
            foreach (CourseTemplate template in CourseTemplates)
            {
                var duplicate = new CourseTemplate(template.sourceNode, true); //creates a duplicate so the initial template is preserved
                duplicate.PopulateFromSourceNode();
                if (duplicate.Available)
                {
                    OfferedCourses.Add(duplicate);
                }
            }

            foreach (AvailablePart ap in PartLoader.LoadedPartsList)
            {
                if (ap.partPrefab.CrewCapacity > 0 &&
                    ResearchAndDevelopment.PartModelPurchased(ap))
                {
                    AddPartCourses(ap);
                }
            }
        }
示例#6
0
        private void GenerateCourseProf(AvailablePart ap, bool isTemporary)
        {
            var    n    = new ConfigNode("FS_COURSE");
            string name = TrainingDatabase.SynonymReplace(ap.name);

            n.AddValue("id", "prof_" + name);
            n.AddValue("name", "Proficiency: " + name);
            n.AddValue("time", 1d + (TrainingDatabase.GetTime(name) * 86400));
            n.AddValue("isTemporary", isTemporary);
            n.AddValue("conflicts", "TRAINING_proficiency:" + name);

            ConfigNode r = n.AddNode("REWARD");

            r.AddValue("XPAmt", Settings.trainingProficiencyXP);
            ConfigNode l = r.AddNode("FLIGHTLOG");

            l.AddValue("0", "TRAINING_proficiency," + name);

            var c = new CourseTemplate(n);

            c.PopulateFromSourceNode();
            OfferedCourses.Add(c);
        }
示例#7
0
        private void GenerateCourseMission(AvailablePart ap)
        {
            var    n    = new ConfigNode("FS_COURSE");
            string name = TrainingDatabase.SynonymReplace(ap.name);

            n.AddValue("id", "msn_" + name);
            n.AddValue("name", "Mission: " + name);
            n.AddValue("time", 1 + TrainingDatabase.GetTime(name + "-Mission") * 86400);
            n.AddValue("isTemporary", false);
            n.AddValue("timeUseStupid", true);
            n.AddValue("seatMax", ap.partPrefab.CrewCapacity * 2);
            n.AddValue("expiration", Settings.trainingMissionExpirationDays * 86400);
            n.AddValue("preReqs", "TRAINING_proficiency:" + name);

            ConfigNode r = n.AddNode("REWARD");
            ConfigNode l = r.AddNode("FLIGHTLOG");

            l.AddValue("0", "TRAINING_mission," + name);

            var c = new CourseTemplate(n);

            c.PopulateFromSourceNode();
            OfferedCourses.Add(c);
        }
示例#8
0
 public ActiveCourse(CourseTemplate template)
 {
     sourceNode = template.sourceNode;
     PopulateFromSourceNode(template.sourceNode);
 }
示例#9
0
 private static void AppendToPartTooltip(AvailablePart ap, CourseTemplate ct)
 {
     ct.PartsTooltip = ct.PartsTooltip == null ? $"Applies to parts: {ap.title}" :
                       $"{ct.PartsTooltip}, {ap.title}";
 }