public ScienceContext(ScienceChecklistAddon Parent) { _parent = Parent; _logger = new Logger(this); //_logger.Trace( "Making ScienceContext" ); _bodyList = new Dictionary <CelestialBody, Body>(); //_logger.Trace( "Made _bodyList" ); _onboardScience = new Dictionary <string, List <ScienceData> >(); //_logger.Trace( "Made _onboardScience" ); _scienceSubjects = new Dictionary <string, ScienceSubject>(); //_logger.Trace( "Made _scienceSubjects" ); _experiments = new Dictionary <ScienceExperiment, ModuleScienceExperiment>(); //_logger.Trace( "Made _experiments" ); _kscBiomes = new List <string>(); //_logger.Trace( "Made _kscBiomes" ); _unlockedInstruments = new UnlockedInstrumentList(); //_logger.Trace( "Made _unlockedInstruments" ); _allScienceInstances = new List <ScienceInstance>(); //_logger.Trace( "Made _allScienceInstances" ); Reset(); //_logger.Trace( "Made ScienceContext" ); //workerThreads.Add(new Thread(() => { if (_bodyList.Count != FlightGlobals.Bodies.Count) UpdateBodies(); } )); //workerThreads.Add(new Thread(UpdateOnboardScience)); //workerThreads.Add(new Thread(UpdateScienceSubjects)); //workerThreads.Add(new Thread(UpdateExperiments)); //workerThreads.Add(new Thread(UpdateKscBiomes)); //workerThreads.Add(new Thread(RefreshExperimentCache)); //workerThreads.Add(new Thread(() => //{ // if (_bodyList.Count != FlightGlobals.Bodies.Count) // UpdateBodies(); // UpdateOnboardScience(); //})); //workerThreads.Add(new Thread(() => //{ // UpdateScienceSubjects(); // UpdateExperiments(); // UpdateKscBiomes(); // RefreshExperimentCache(); //})); //for (int i = 0; i < workerThreads.Count; i++) //{ // workerThreads[i].IsBackground = true; // workerThreads[i].Priority = System.Threading.ThreadPriority.Normal; //} }
/// <summary> /// Updates the IsUnlocked, CompletedScience, TotalScience, OnboardScience, and IsComplete fields. /// </summary> /// <param name="onboardScience">The total onboard ScienceData.</param> public void Update(ScienceContext Sci) { if (Sci.ScienceSubjects.ContainsKey(Id)) { ScienceSubject = Sci.ScienceSubjects[Id]; } else { ScienceSubject = new ScienceSubject(ScienceExperiment, Situation.ExperimentSituation, Situation.Body.CelestialBody, Situation.SubBiome ?? Situation.Biome ?? string.Empty); } IsUnlocked = UnlockedInstrumentList.IsUnlocked(ScienceExperiment.id) && (Situation.Body.Reached != null); CompletedScience = ScienceSubject.science * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; TotalScience = ScienceSubject.scienceCap * HighLogic.CurrentGame.Parameters.Career.ScienceGainMultiplier; IsComplete = CompletedScience > TotalScience || TotalScience - CompletedScience < 0.1; var multiplier = ScienceExperiment.baseValue / ScienceExperiment.scienceCap; OnboardScience = 0; if (Sci.OnboardScienceList.ContainsKey(ScienceSubject.id)) { var data = Sci.OnboardScienceList[ScienceSubject.id]; // var _logger = new Logger( "Experiment" ); // _logger.Trace( ScienceSubject.id + " found " + data.Count( ) + " items" ); foreach (var i in data) { var next = (TotalScience - (CompletedScience + OnboardScience)) * multiplier; OnboardScience += next; } } var AllCollectedScience = CompletedScience + OnboardScience; IsCollected = AllCollectedScience > TotalScience || TotalScience - AllCollectedScience < 0.1; }
public ScienceContext(ScienceChecklistAddon Parent) { _parent = Parent; _logger = new Logger(this); //_logger.Trace( "Making ScienceContext" ); _bodyList = new Dictionary <CelestialBody, Body>( ); //_logger.Trace( "Made _bodyList" ); _onboardScience = new Dictionary <string, List <ScienceData> >( ); //_logger.Trace( "Made _onboardScience" ); _scienceSubjects = new Dictionary <string, ScienceSubject>( ); //_logger.Trace( "Made _scienceSubjects" ); _experiments = new Dictionary <ScienceExperiment, ModuleScienceExperiment>( ); //_logger.Trace( "Made _experiments" ); _kscBiomes = new List <string>( ); //_logger.Trace( "Made _kscBiomes" ); _unlockedInstruments = new UnlockedInstrumentList( ); //_logger.Trace( "Made _unlockedInstruments" ); _allScienceInstances = new List <ScienceInstance>( ); //_logger.Trace( "Made _allScienceInstances" ); Reset( ); //_logger.Trace( "Made ScienceContext" ); }
/// <summary> /// Refreshes the experiment cache. THIS IS VERY EXPENSIVE. /// CB: Actually doesn't seem much worse than UpdateExperiments() /// </summary> public void RefreshExperimentCache( ) { // Init var StartTime = DateTime.Now; ScienceContext Sci = new ScienceContext( ); BodySituationFilter BodyFilter = new BodySituationFilter( ); // _logger.Info( "RefreshExperimentCache" ); // Quick check for things we depend on if (ResearchAndDevelopment.Instance == null || PartLoader.Instance == null) { _logger.Debug("ResearchAndDevelopment and PartLoader must be instantiated."); AllScienceInstances = new List <ScienceInstance>( ); UpdateFilter( ); return; } // Temporary experiment list var exps = new List <ScienceInstance>( ); // Unlocked experiment list UnlockedInstrumentList.Clear( ); // Loop around all experiments foreach (var X in Sci.Experiments) { var experiment = X.Key; //_logger.Trace( experiment.experimentTitle ); // Where the experiment is possible uint sitMask = experiment.situationMask; uint biomeMask = experiment.biomeMask; /* Need to look at * public bool BiomeIsRelevantWhile( ExperimentSituations situation ); * public bool IsAvailableWhile( ExperimentSituations situation, CelestialBody body ); * On ScienceExperiment */ // OrbitalScience support - where the experiment is possible if (sitMask == 0 && Sci.Experiments[experiment] != null) { var sitMaskField = Sci.Experiments[experiment].GetType( ).GetField("sitMask"); if (sitMaskField != null) { sitMask = (uint)(int)sitMaskField.GetValue(Sci.Experiments[experiment]); // _logger.Trace( "Setting sitMask to " + sitMask + " for " + experiment.experimentTitle ); } if (biomeMask == 0) { var biomeMaskField = Sci.Experiments[experiment].GetType( ).GetField("bioMask"); if (biomeMaskField != null) { biomeMask = (uint)(int)biomeMaskField.GetValue(Sci.Experiments[experiment]); // _logger.Trace( "Setting biomeMask to " + biomeMask + " for " + experiment.experimentTitle ); } } } List <ExperimentSituations> SituationList = Enum.GetValues(typeof(ExperimentSituations)).Cast <ExperimentSituations>( ).ToList <ExperimentSituations>( ); List <Body> BodyList = new List <Body>(Sci.BodyList.Values.ToList( )); // Check for CelestialBodyFilter if (Sci.Experiments[experiment] != null) { // _logger.Trace( Sci.Experiments[ experiment ].experimentID ); if (CelestialBodyFilters.Filters.HasValue(Sci.Experiments[experiment].experimentID)) { string FilterText = CelestialBodyFilters.Filters.GetValue(Sci.Experiments[experiment].experimentID); BodyFilter.Filter(BodyList, SituationList, FilterText); } } // Check this experiment in all biomes on all bodies foreach (var body in BodyList) { if (experiment.requireAtmosphere && !body.HasAtmosphere) { continue; // If the whole planet doesn't have an atmosphere, then there's not much point continuing. } foreach (var situation in SituationList) { if (situation == ExperimentSituations.SrfSplashed && !body.HasOcean) { continue; // Some planets don't have an ocean for us to be splashed down in. } if (situation == ExperimentSituations.SrfLanded && !body.HasSurface) { continue; // Jool and the Sun don't have a surface. } if ((situation == ExperimentSituations.FlyingHigh || situation == ExperimentSituations.FlyingLow) && !body.HasAtmosphere) { continue; // Some planets don't have an atmosphere for us to fly in. } if ((sitMask & (uint)situation) == 0) { continue; // This experiment isn't valid for our current situation. } if (body.Biomes.Any( ) && (biomeMask & (uint)situation) != 0) { foreach (var biome in body.Biomes) { exps.Add(new ScienceInstance(experiment, new Situation(body, situation, biome), Sci)); } } else { exps.Add(new ScienceInstance(experiment, new Situation(body, situation), Sci)); } } } // Can't really avoid magic constants here - Kerbin and Shores if (((sitMask & (uint)ExperimentSituations.SrfLanded) != 0) && ((biomeMask & (uint)ExperimentSituations.SrfLanded) != 0)) { if (Sci.Kerbin != null && Sci.KscBiomes.Count > 0) { if (BodyList.Contains(Sci.BodyList[Sci.Kerbin])) // If we haven't filtered it out { // _logger.Trace( "BabyBiomes " + experiment.experimentTitle + ": " + sitMask ); foreach (var kscBiome in Sci.KscBiomes) // Ew. { exps.Add(new ScienceInstance(experiment, new Situation(Sci.BodyList[Sci.Kerbin], ExperimentSituations.SrfLanded, "Shores", kscBiome), Sci)); } } } } } // Done replace the old list with the new one AllScienceInstances = exps; // We need to redo the filter UpdateFilter( ); var Elapsed = DateTime.Now - StartTime; _logger.Trace("RefreshExperimentCache Done - " + Elapsed.ToString( ) + "ms"); }