internal static void cache_game_parts()
        {
            CraftManager.log("caching game parts");
            locked_parts.Clear();
            List <string> part_names = new List <string>();

            foreach (AvailablePart part in PartLoader.LoadedPartsList)
            {
                if (!part_data.ContainsKey(part.name))
                {
                    part_data.Add(part.name, part);
                }
                part_names.AddUnique(part.name);
                if (!ResearchAndDevelopment.PartTechAvailable(part))
                {
                    locked_parts.AddUnique(part.name);
                }
            }
            //Make a string containing all the installed parts and the data from LoaderInfo in the save file and
            //then generate a checksum from it.  This is used as a signature of the installed setup which will change
            //if the installed mods are changed enabling craft to disregard cached data after a change in mod setup.
            part_names.Sort();
            string s  = String.Join("", part_names.ToArray());
            string lf = "";

            try{
                ConfigNode save_data   = ConfigNode.Load(Paths.joined(CraftManager.ksp_root, "saves", HighLogic.SaveFolder, "persistent.sfs"));
                ConfigNode loader_info = save_data.GetNode("GAME").GetNode("LoaderInfo");
                lf = loader_info.ToString();
            }
            catch (Exception e) {
                CraftManager.log("Failed to read loaderinfo " + e.Message);
            }
            installed_part_sig = Checksum.digest(s + lf);
        }
        public override bool MeetRequirements()
        {
            AvailablePart ap1 = PartLoader.getPartInfoByName("tarsierSpaceTelescope");
            AvailablePart ap2 = PartLoader.getPartInfoByName("tarsierAdvSpaceTelescope");

            return(ResearchAndDevelopment.PartTechAvailable(ap1) || ResearchAndDevelopment.PartTechAvailable(ap2));
        }
Esempio n. 3
0
        public override bool RequirementMet(ConfiguredContract contract)
        {
            foreach (string tech in techs)
            {
                ProtoTechNode techNode = ResearchAndDevelopment.Instance.GetTechState(tech);
                if (techNode == null || techNode.state != RDTech.State.Available)
                {
                    return(false);
                }
            }

            foreach (string partModule in partModules)
            {
                bool hasModule = false;
                foreach (AvailablePart part in PartLoader.LoadedPartsList)
                {
                    if (part.partPrefab == null || part.partPrefab.Modules == null)
                    {
                        continue;
                    }

                    if (ResearchAndDevelopment.PartTechAvailable(part))
                    {
                        hasModule = true;
                        break;
                    }
                }

                if (!hasModule)
                {
                    return(false);
                }
            }

            foreach (string partModuleType in partModuleTypes)
            {
                bool hasType = false;
                foreach (AvailablePart part in PartLoader.LoadedPartsList)
                {
                    if (part.partPrefab == null || part.partPrefab.Modules == null)
                    {
                        continue;
                    }

                    if (part.partPrefab.HasValidContractObjective(partModuleType) && ResearchAndDevelopment.PartTechAvailable(part))
                    {
                        hasType = true;
                        break;
                    }
                }

                if (!hasType)
                {
                    return(false);
                }
            }

            return(true);
        }
Esempio n. 4
0
 static bool PartResearched(AvailablePart p)
 {
     if (p == null)
     {
         return(false);
     }
     return(ResearchAndDevelopment.PartTechAvailable(p) && ResearchAndDevelopment.PartModelPurchased(p));
 }
Esempio n. 5
0
        bool IsPartUnlocked(string name)
        {
            AvailablePart part = PartLoader.getPartInfoByName(name);

            if (part != null && ResearchAndDevelopment.PartTechAvailable(part))
            {
                return(true);
            }
            return(false);
        }
Esempio n. 6
0
        public override bool MeetRequirements()
        {
            AvailablePart ap1 = PartLoader.getPartInfoByName("tarsierChemCam");

            if (ap1 != null)
            {
                return(ResearchAndDevelopment.PartTechAvailable(ap1));
            }
            Utilities.Log("It appears the TST ChemCam part is missing. Cannot check Contract Requirements");
            return(false);
        }
 public override bool RequirementMet(ConfiguredContract contract)
 {
     foreach (AvailablePart part in parts)
     {
         if (!ResearchAndDevelopment.PartTechAvailable(part))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 8
0
 bool AllUnlocked(HashSet <string> set)
 {
     foreach (string entry in set)
     {
         AvailablePart part = PartLoader.getPartInfoByName(entry);
         if (!(ResearchAndDevelopment.PartTechAvailable(part) && ResearchAndDevelopment.PartModelPurchased(part)))
         {
             return(false);
         }
     }
     return(true);
 }
Esempio n. 9
0
        public override bool MeetRequirements()
        {
            AvailablePart ap = PartLoader.getPartInfoByName("Impact Spectrometer");

            if (ap != null)
            {
                if (ResearchAndDevelopment.PartTechAvailable(ap))
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 10
0
 bool AllUnlocked(HashSet <string> set)
 {
     foreach (string entry in set)
     {
         AvailablePart part = PartLoader.getPartInfoByName(entry);
         if (!(ResearchAndDevelopment.PartTechAvailable(part) /*&& ResearchAndDevelopment.PartModelPurchased(part)*/))
         {
             //In career mode I certainly don't purchase parts until I need them to fulfil a contract
             //And if you can't get the contracts until you have purchased them...
             return(false);
         }
     }
     return(true);
 }
Esempio n. 11
0
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            // Group our stuff in the engine's menu
            foreach (BaseField f in Fields)
            {
                f.group.name        = guiGroup;
                f.group.displayName = guiGroupDisplayName;
            }
            foreach (BaseEvent e in Events)
            {
                e.group.name        = guiGroup;
                e.group.displayName = guiGroupDisplayName;
            }

            if (state == StartState.Editor) // This is an upgrade, so don't give it to an already in flight vessel that doesn't have it
            {
                researchPartName = researchPartName.Replace("_", ".");
                var ap = PartLoader.getPartInfoByName(researchPartName);

                if (ap == null)
                {
                    Log.Error("researchPartName = " + researchPartName + "; Part not found.");
                    // set isResearched to false here?
                }
                else
                {
                    isResearched = ResearchAndDevelopment.PartModelPurchased(ap) && ResearchAndDevelopment.PartTechAvailable(ap);
                    if (!isResearched)
                    {
                        if (!ResearchAndDevelopment.PartModelPurchased(ap))
                        {
                            Log.Info("SmartSRB not available due to PartModel not being purchased");
                        }

                        if (!ResearchAndDevelopment.PartTechAvailable(ap))
                        {
                            Log.Info("SmartSRB not available due to PartTech not being available");
                        }
                    }
                }
            }
            moduleIsEnabled = isResearched;
            updateButtons();

            //GameEvents.onEngineActiveChange.Add(onEngineActiveChange);
            //StartCoroutine(GuiUpdate());
        }
Esempio n. 12
0
        public override bool MeetRequirements()
        {
            // stop checking when requirements are met
            if (!meet_requirements)
            {
                var greenhouse = PartLoader.getPartInfoByName("kerbalism-greenhouse");

                meet_requirements =
                    greenhouse != null &&                                   // greenhouse part is present
                    greenhouse.tags.Contains("_kerbalism") &&               // greenhouse part is enabled
                    ResearchAndDevelopment.PartTechAvailable(greenhouse) && // greenhouse part unlocked
                    !DB.landmarks.space_harvest;                            // greenhouse never harvested in space before
            }
            return(meet_requirements);
        }
Esempio n. 13
0
        public override bool MeetRequirements()
        {
            // stop checking when requirements are met
            if (!meet_requirements)
            {
                var lab = PartLoader.getPartInfoByName("Large_Crewed_Lab");

                meet_requirements =
                    Features.Science &&                                                           // science is enabled
                    lab != null &&                                                                // lab part is present
                    ResearchAndDevelopment.PartTechAvailable(lab) &&                              // lab part is unlocked
                    !DB.landmarks.space_analysis;                                                 // never analyzed samples in space before
            }
            return(meet_requirements);
        }
Esempio n. 14
0
        // List available experiments
        private void GetExperiments()
        {
            unlockedExperiments.Clear();
            availableExperiments.Clear();

            List <AvailablePart> parts = PartLoader.Instance.loadedParts;

            // EVA Reports available from the beginning
            unlockedExperiments.Add(ResearchAndDevelopment.GetExperiment("evaReport"));

            // Don't check RnD level to determine if surface samples are available, in case another mod messes with the Facility Levels.
            //Instead just check the experiment is available directly.
            if (ResearchAndDevelopment.GetExperiment("surfaceSample").IsUnlocked())
            {
                unlockedExperiments.Add(ResearchAndDevelopment.GetExperiment("surfaceSample"));
            }

            foreach
            (
                AvailablePart part in parts.Where
                (
                    x => ResearchAndDevelopment.PartTechAvailable(x) &&
                    !excludedManufacturers.Contains(x.manufacturer) &&
                    ResearchAndDevelopment.PartModelPurchased(x)
                )
            )
            {
                // Part has some modules
                if (part.partPrefab.Modules != null)
                {
                    // Check science modules
                    foreach (ModuleScienceExperiment ex in part.partPrefab.Modules.OfType <ModuleScienceExperiment>())
                    {
                        if (ex.experimentID == null)
                        {
                            Log.Error("part's " + part.name + " experimentID is null");
                            continue;
                        }
                        // Remove experiments with empty ids, by [Kerbas-ad-astra](https://github.com/Kerbas-ad-astra)
                        // Remove Surface Experiments Pack experiments not meant to run in atmosphere
                        if (ex.experimentID != "" && !excludedExperiments.Contains(ex.experimentID))
                        {
                            unlockedExperiments.AddUnique <ScienceExperiment>(ResearchAndDevelopment.GetExperiment(ex.experimentID));
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        public static List <AvailablePart> getAvailableExperimentParts(string type, bool includeExperimental = false)
        {
            string[]             partsRegistry = null;
            List <AvailablePart> list          = null;

            switch (type)
            {
            case OMS_EXPERIMENTS:
                partsRegistry = omsRegistry;
                break;

            case KEMINI_EXPERIMENTS:
                //partsRegistry = keminiRegistry;
                partsRegistry = getKeminiRegister();
                break;

            default:
                return(list);
            }
            // Avoid multiple allocations; the collection is small enough that the memory overhead is better than the reallocation overhead
            list = new List <AvailablePart>(partsRegistry.Length);

            for (int idx = 0, count = partsRegistry.Length; idx < count; idx++)
            {
                AvailablePart part = PartLoader.getPartInfoByName(partsRegistry[idx]);
                if (part == null)
                {
                    continue;
                }

                /*
                 * bool isPurchased = ResearchAndDevelopment.PartModelPurchased (part);
                 * bool isTechAvailable = ResearchAndDevelopment.PartTechAvailable (part);
                 * bool isExperimental = ResearchAndDevelopment.IsExperimentalPart (part);
                 * NE_Helper.log ("Part " + part.name +
                 *  " techlevel: [" + isTechAvailable + "]" +
                 *  " experimental: [" + isExperimental + "]" +
                 *  " purchased: [" + isPurchased + "]");
                 */
                if (ResearchAndDevelopment.PartModelPurchased(part) ||
                    (includeExperimental && ResearchAndDevelopment.PartTechAvailable(part)))
                {
                    list.Add(part);
                }
            }

            return(list);
        }
Esempio n. 16
0
        // List available experiments
        private void GetExperiments()
        {
            unlockedExperiments.Clear();
            availableExperiments.Clear();

            List <AvailablePart> parts = PartLoader.Instance.loadedParts;

            // EVA Reports available from the beginning
            unlockedExperiments.Add(ResearchAndDevelopment.GetExperiment("evaReport"));

            // To take surface samples from other worlds you need to upgrade Astronaut Complex and R&D
            // But to take surface samples from home you need to only upgrade R&D
            if (ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.ResearchAndDevelopment) > 0.0)
            {
                unlockedExperiments.Add(ResearchAndDevelopment.GetExperiment("surfaceSample"));
            }

            foreach
            (
                AvailablePart part in parts.Where
                (
                    x => ResearchAndDevelopment.PartTechAvailable(x) &&
                    !excludedManufacturers.Contains(x.manufacturer) &&
                    ResearchAndDevelopment.PartModelPurchased(x)
                )
            )
            {
                // Part has some modules
                if (part.partPrefab.Modules != null)
                {
                    // Check science modules
                    foreach (ModuleScienceExperiment ex in part.partPrefab.Modules.OfType <ModuleScienceExperiment>())
                    {
                        if (ex.experimentID == null)
                        {
                            Log("part's " + part.name + " experimentID is null");
                            continue;
                        }
                        // Remove experiments with empty ids, by [Kerbas-ad-astra](https://github.com/Kerbas-ad-astra)
                        // Remove Surface Experiments Pack experiments not meant to run in atmosphere
                        if (ex.experimentID != "" && !excludedExperiments.Contains(ex.experimentID))
                        {
                            unlockedExperiments.AddUnique <ScienceExperiment> (ResearchAndDevelopment.GetExperiment(ex.experimentID));
                        }
                    }
                }
            }
        }
 private static void addParts(List <string> partNames, List <ExperimentData> list)
 {
     foreach (string pn in partNames)
     {
         AvailablePart part = PartLoader.getPartInfoByName(pn);
         if (part != null)
         {
             if (ResearchAndDevelopment.PartTechAvailable(part))
             {
                 Part pPf = part.partPrefab;
                 NE_ExperimentModule exp = pPf.GetComponent <NE_ExperimentModule>();
                 float mass = pPf.mass;
                 list.Add(getExperiment(exp.type, mass));
             }
         }
     }
 }
Esempio n. 18
0
        public static bool haveTechnology(string tech)
        {
            tech = tech.Replace('_', '.');
            AvailablePart ap = PartLoader.getPartInfoByName(tech);

            if (ap != null)
            {
                if (ResearchAndDevelopment.PartTechAvailable(ap))
                {
                    return(true);
                }
            }
            else
            {
                Debug.LogWarning("Fine Print: Attempted to check for nonexistent technology: \"" + tech + "\".");
            }

            return(false);
        }
Esempio n. 19
0
        public static List <LabEquipment> getAvailableRacks()
        {
            List <LabEquipment> list = new List <LabEquipment>();

            foreach (KeyValuePair <EquipmentRacks, string> p in racks)
            {
                AvailablePart part = PartLoader.getPartInfoByName(p.Value);
                if (part != null)
                {
                    Part pPf = part.partPrefab;
                    LabEquipmentModule lem = pPf.GetComponent <LabEquipmentModule>();
                    if (ResearchAndDevelopment.PartTechAvailable(part))
                    {
                        list.Add(getLabEquipment(part.partPrefab, p.Key));
                    }
                }
            }

            return(list);
        }
Esempio n. 20
0
        public override bool MeetRequirements()
        {
            AvailablePart ap1 = PartLoader.getPartInfoByName("tarsierSpaceTelescope");
            AvailablePart ap2 = PartLoader.getPartInfoByName("tarsierAdvSpaceTelescope");

            if (ap1 != null && ap2 != null)
            {
                return(ResearchAndDevelopment.PartTechAvailable(ap1) || ResearchAndDevelopment.PartTechAvailable(ap2));
            }
            if (ap1 != null && ap2 == null)
            {
                return(ResearchAndDevelopment.PartTechAvailable(ap1));
            }
            if (ap1 == null && ap2 != null)
            {
                return(ResearchAndDevelopment.PartTechAvailable(ap2));
            }
            Utilities.Log("It appears the TST telescope parts are missing. Cannot check Contract Requirements");
            return(false);
        }
Esempio n. 21
0
        public override bool RequirementMet(ConfiguredContract contract)
        {
            foreach (string partModuleType in partModuleTypes)
            {
                foreach (AvailablePart part in PartLoader.LoadedPartsList)
                {
                    if (part.partPrefab == null || part.partPrefab.Modules == null)
                    {
                        continue;
                    }

                    if (part.partPrefab.HasValidContractObjective(partModuleType) && ResearchAndDevelopment.PartTechAvailable(part) && ResearchAndDevelopment.PartModelPurchased(part))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Esempio n. 22
0
        private static bool partResearched(AvailablePart ap)
        {
            if (ResearchAndDevelopment.Instance == null)
            {
                ASPConsoleStuff.AAprint("no ResearchAndDevelopment.Instance, must be sandbox mode");
                return(true);
            }
            if (!ResearchAndDevelopment.PartTechAvailable(ap))
            {
                ASPConsoleStuff.AAprint(ap.name + ".PartTechAvailable()==false");
                return(false);
            }

            if (!ResearchAndDevelopment.PartModelPurchased(ap))
            {
                ASPConsoleStuff.AAprint(ap.name + ".PartModelPurchased()==false");
                return(false);
            }
            return(true);
        }
Esempio n. 23
0
            private static bool GetPartCost(ConfigNode part, out float total, bool includeFuel = true)
            {
                string name = GetPartName(part);
                float  dryCost, fuelCost, mass;

                total = 0;
                var aP = GetAvailablePart(name);

                if (aP == null)
                {
                    return(false);
                }
                //ShipConstruction.GetPartCostsAndMass
                total = ShipConstruction.GetPartCostsAndMass(part, aP, out dryCost, out fuelCost, out mass, out mass);
                if (!includeFuel)
                {
                    total = dryCost;
                }
                return(ResearchAndDevelopment.PartTechAvailable(aP));
            }
Esempio n. 24
0
        protected override bool Generate()
        {
            bool havePod = false;

            foreach (AvailablePart p in PartLoader.LoadedPartsList)
            {
                if (p.partPrefab.CrewCapacity > 0 && ResearchAndDevelopment.PartTechAvailable(p))
                {
                    havePod = true;
                    break;
                }
            }
            // return false iff we have no crew pods AND we've not reached orbit
            // so you should get this if you've reached orbit, even if you haven't researched any pods yet.
            if (!havePod && !ProgressTracking.Instance.NodeComplete("Kerbin", "Orbit")) // SQUAD Y U HARDCODE
            {
                return(false);
            }
            // one at a time
            if (base.ContractState != State.Active)
            {
                HSFEarthOrbital[] currentContracts = ContractSystem.Instance.GetCurrentContracts <HSFEarthOrbital>();
                for (int i = 0; i < currentContracts.Length; i++)
                {
                    if (currentContracts[i].ContractState == State.Offered || currentContracts[i].ContractState == State.Active)
                    {
                        return(false);
                    }
                }
            }
            prestige = Contract.ContractPrestige.Exceptional;

            AddParameter(new Contracts.Parameters.HSFOrbital(Planetarium.fetch.Home), null);
            base.AddKeywords(new string[] { "HSF" });
            expiryType   = Contract.DeadlineType.None;
            deadlineType = Contract.DeadlineType.None;
            // RP-0 scale funds by 0.1x
            base.SetFunds(10000f, 50000f, null);
            base.SetReputation(480f, null);
            return(true);
        }
        public override void OnUpdate()
        {
            base.OnUpdate();
            MerillData.log(" research onUpdate " + part.name + " with info: " + part.partInfo);
            if (loaded && !change)
            {
                //evolve if we are researched (TODO: test when it's necessary to do this: only 1 time?)
                MerillData.log(" research onload " + part.name + " with info: " + part.partInfo);
                if (part.partInfo != null && ResearchAndDevelopment.PartTechAvailable(this.part.partInfo))
                {
                    MerillData.log(" research onload " + part.name + ", i'm researched for " + PartLoader.getPartInfoByName(initialPart));

                    AvailablePart partToEvolve = PartLoader.getPartInfoByName(initialPart);
                    if (partToEvolve != null && partToEvolve.partPrefab != null)
                    {
                        evolve(partToEvolve);
                    }
                }
                change = true;
            }
        }
Esempio n. 26
0
        /// <summary>
        /// Returns TRUE if the part technology is available.
        /// </summary>
        /// <returns><c>true</c>, if part technology available, <c>false</c> otherwise.</returns>
        /// <param name="name">Name.</param>
        public static bool IsPartTechAvailable(string name)
        {
            AvailablePart part = PartLoader.getPartInfoByName(name);

            return(part != null && ResearchAndDevelopment.PartTechAvailable(part));
        }
Esempio n. 27
0
 public static bool PartResearched(AvailablePart p)
 {
     return(ResearchAndDevelopment.PartTechAvailable(p) && ResearchAndDevelopment.PartModelPurchased(p));
 }
        // Add stub part into research node
        // Add exp part if in a researched node (from stub part)
        private void addExperimentalParts()
        {
            if (base.dateAccepted == 0)
            {
                MerillData.log("mun mission: can't add exp part: date accepted=" + dateAccepted);
            }
            try
            {
                //add mandatory parts
                addExperimentalPart("MerillnlineCockpitLander");

                //add part from stubs
                foreach (AvailablePart aPart in PartLoader.Instance.parts)
                {
                    if (aPart.partPrefab != null && aPart.partPrefab.Modules != null)
                    {
                        //MerillData.log("part " + aPart.name);
                        foreach (PartModule pm in aPart.partPrefab.Modules)
                        {
                            if (pm.moduleName.Equals("MerillMissionStub"))
                            {
                                if (((MerillMissionStub)pm).missionName.Equals(this.GetType().Name))
                                {
                                    MerillData.log(" RD find a part " + pm.name);
                                    MerillData.log(" RD purchased? " + ResearchAndDevelopment.PartModelPurchased(aPart));
                                    MerillData.log(" RD available? " + ResearchAndDevelopment.PartTechAvailable(aPart));
                                    MerillData.log(" RD mi " + aPart.moduleInfo);
                                    MerillData.log(" RD tech required: " + aPart.TechRequired);
                                    MerillData.log(" RD tech Really required: " + ((MerillMissionStub)pm).techRequired);
                                    MerillData.log(" RD tech Really required purchased? : "
                                                   + ResearchAndDevelopment.GetTechnologyState(((MerillMissionStub)pm).techRequired));
                                    //already set, and already researched?
                                    if (ResearchAndDevelopment.GetTechnologyState(
                                            ((MerillMissionStub)pm).techRequired) == RDTech.State.Available &&
                                        aPart.TechRequired == ((MerillMissionStub)pm).techRequired)
                                    {
                                        MerillData.log(" RD find a part with r&d node " + pm.name);
                                        //check if already experimental
                                        if (!ResearchAndDevelopment.IsExperimentalPart(
                                                PartLoader.getPartInfoByName(((MerillMissionStub)pm).partUnlock)))
                                        {
                                            addExperimentalPart(((MerillMissionStub)pm).partUnlock);
                                        }
                                    }
                                    // not set
                                    else if (aPart.TechRequired == "specializedControl")
                                    {
                                        try {
                                            //try to attach the stub to a research node
                                            MerillData.log(" RD find a part without r&d node " + pm.name);

                                            RDTech tech = AssetBase.RnDTechTree.FindTech(
                                                ((MerillMissionStub)pm).techRequired);
                                            if (tech != null)
                                            {
                                                //Set it
                                                MerillData.log(" RD find good tech " + tech.name);
                                                aPart.TechRequired = ((MerillMissionStub)pm).techRequired;
                                                tech.partsAssigned.Add(aPart);
                                                MerillData.log(" RD find tech assigned ");

                                                MerillData.log(" RD good tech purchased? " + tech.state
                                                               + " , " + tech.enabled + ", ");
                                                //already researched?
                                                if (ResearchAndDevelopment.GetTechnologyState(((MerillMissionStub)pm).techRequired) == RDTech.State.Available)
                                                {
                                                    addExperimentalPart(((MerillMissionStub)pm).partUnlock);
                                                }
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            MerillData.log(" RD Exeption:  " + e);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                //TODO: made this auto + add stub in tree
                //if (ResearchAndDevelopment.PartModelPurchased(PartLoader.getPartInfoByName("MerillCheapFuelTank1-2Stub")))
                //	addExperimentalPart("MerillCheapFuelTank1-2");


                //if (ResearchAndDevelopment.PartModelPurchased(PartLoader.getPartInfoByName("MerillCheapFuelTank3-2Stub")))
                //	addExperimentalPart("MerillCheapFuelTank3-2");

                //if (ResearchAndDevelopment.PartModelPurchased(PartLoader.getPartInfoByName("MerillLinearRcsExperimental")))
                //	addExperimentalPart("MerillLinearRcsExperimental");
            }
            catch (Exception e)
            {
                MerillData.log(" exception at contract OnAccepted:" + e);
            }
        }
        public override void OnAwake()
        {
            base.OnAwake();

            GameEvents.onGameSceneLoadRequested.Add(this.GameSceneLoadHandler);
            GameEvents.OnPartPurchased.Add(this.PartPurchasedHandler);

            if (this.part.tryGetFirstModuleOfType <ModuleSAS>(out this.sasModule))
            {
                this.SASServiceLevel = this.sasModule.SASServiceLevel;
            }

            if (researchedPartsLoaded)
            {
                this.SASServiceLevel = maxSASServiceLevel;
                return;
            }

            if (HighLogic.CurrentGame == null || PartLoader.LoadedPartsList == null)
            {
                return;
            }

            switch (HighLogic.CurrentGame.Mode)
            {
            case Game.Modes.CAREER:
                this.Fields["SASServiceLevel"].guiActiveEditor = true;
                break;

            default:
                this.Fields["SASServiceLevel"].guiActiveEditor = false;

                Array apModes = Enum.GetValues(typeof(AutopilotSkill.Skills));
                int   autopilotMode;
                for (int idx = 0; idx < apModes.Length; idx++)
                {
                    try
                    {
                        autopilotMode = (int)apModes.GetValue(idx);

                        maxSASServiceLevel = Math.Max(maxSASServiceLevel, autopilotMode);
                    }
                    catch
                    {
                        this.LogDebug(
                            "Failed converting {0}.{1} to int.",
                            typeof(AutopilotSkill.Skills).GetType().Name,
                            Enum.GetName(typeof(AutopilotSkill.Skills), apModes.GetValue(idx))
                            );
                    }
                }

                researchedPartsLoaded = true;

                this.LogDebug("Sandbox mode: maxSASServiceLevel = {0}", maxSASServiceLevel);

                return;
            }

            this.LogDebug("Searching for researched parts with SAS modules...");

            using (var logger = PooledDebugLogger.New(this))
            {
                AvailablePart part;
                for (int idx = 0; idx < PartLoader.LoadedPartsList.Count; idx++)
                {
                    part = PartLoader.LoadedPartsList[idx];

                    logger.AppendFormat("Checking {0}...", part.title);

                    if (ResearchAndDevelopment.PartTechAvailable(part))
                    {
                        logger.Append(" researched...");

                        ModuleSAS sasModule;

                        if (part.partPrefab.tryGetFirstModuleOfType(out sasModule))
                        {
                            logger.Append(" has SAS module, adding to list.");

                            researchedSASParts.Add(part);

                            maxSASServiceLevel = Math.Max(sasModule.SASServiceLevel, maxSASServiceLevel);

                            logger.AppendFormat(" \n\tmaxSASServiceLevel = {0}.", maxSASServiceLevel);
                        }
                    }
                                        #if DEBUG
                    else
                    {
                        logger.Append(" not researched!");
                    }
                                        #endif

                    logger.Append('\n');
                }

                logger.Append("Researched SAS parts loaded.");

                logger.Print();
            }

            researchedPartsLoaded = true;
        }
        protected void removeExperimentalParts()
        {
            try
            {
                //remove mandatory parts
                removeExperimentalPart("MerillnlineCockpitLander");

                foreach (AvailablePart aPart in PartLoader.Instance.parts)
                {
                    if (aPart.partPrefab != null && aPart.partPrefab.Modules != null)
                    {
                        foreach (PartModule pm in aPart.partPrefab.Modules)
                        {
                            if (pm.moduleName.Equals("MerillMissionStub"))
                            {
                                if (((MerillMissionStub)pm).missionName.Equals(this.GetType().Name))
                                {
                                    MerillData.log(" RD find a part " + pm.name);
                                    MerillData.log(" RD purchased? " + ResearchAndDevelopment.PartModelPurchased(aPart));
                                    MerillData.log(" RD available? " + ResearchAndDevelopment.PartTechAvailable(aPart));
                                    MerillData.log(" RD mi '" + aPart.moduleInfo + "'");
                                    MerillData.log(" RD tech required: " + aPart.TechRequired);
                                    MerillData.log(" RD tech Really required: " + ((MerillMissionStub)pm).techRequired);
                                    //research and set
                                    if (ResearchAndDevelopment.GetTechnologyState(((MerillMissionStub)pm).techRequired) == RDTech.State.Available &&
                                        aPart.TechRequired == ((MerillMissionStub)pm).techRequired)
                                    {
                                        MerillData.log(" RD purchased, is experimental? "
                                                       + ResearchAndDevelopment.IsExperimentalPart(
                                                           PartLoader.getPartInfoByName(((MerillMissionStub)pm).partUnlock)));
                                        //check if experimental
                                        if (ResearchAndDevelopment.IsExperimentalPart(
                                                PartLoader.getPartInfoByName(((MerillMissionStub)pm).partUnlock)))
                                        {
                                            removeExperimentalPart(((MerillMissionStub)pm).partUnlock);
                                        }
                                        //remove from tech
                                        RDTech tech = AssetBase.RnDTechTree.FindTech(aPart.TechRequired);
                                        if (tech != null)
                                        {
                                            MerillData.log(" RD find good tech " + tech.name);
                                            aPart.TechRequired = "specializedControl";
                                            tech.partsAssigned.Remove(aPart);
                                        }
                                    }
                                    //set? ==((MerillMissionStub)pm).techRequired
                                    else if (aPart.TechRequired != "specializedControl")
                                    {
                                        try {
                                            //try to remove the stub to a research node
                                            MerillData.log(" RD find a part with r&d node " + pm.name);

                                            RDTech tech = AssetBase.RnDTechTree.FindTech(aPart.TechRequired);
                                            if (tech != null)
                                            {
                                                MerillData.log(" RD find good tech " + tech.name);
                                                aPart.TechRequired = "specializedControl";
                                                tech.partsAssigned.Remove(aPart);
                                                MerillData.log(" RD find tech assigned ");
                                                if (ResearchAndDevelopment.GetTechnologyState(((MerillMissionStub)pm).techRequired) == RDTech.State.Available)
                                                {
                                                    removeExperimentalPart(((MerillMissionStub)pm).partUnlock);
                                                }
                                            }
                                        }
                                        catch (Exception e)
                                        {
                                            MerillData.log(" RD Exeption:  " + e);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                MerillData.log(" exception at contract OnAccepted:" + e);
            }
        }