예제 #1
0
        private void Start()
        {
            SYP = part.FindModuleImplementing <ModuleSYPartTracker>();
#if DEBUG
            Debug.Log("[UPFM]: UPFMEvents.Start" + SYP.ID);
#endif
        }
예제 #2
0
        private void Start()
        {
#if DEBUG
            Fields["displayChance"].guiActive       = true;
            Fields["displayChance"].guiActiveEditor = true;
            Fields["safetyRating"].guiActive        = true;
#endif
            if (HighLogic.LoadedSceneIsEditor)
            {
                hasFailed = false;
            }
            //find the ScrapYard Module straight away, as we can't do any calculations without it.
            SYP             = part.FindModuleImplementing <ModuleSYPartTracker>();
            chanceOfFailure = baseChanceOfFailure;
            //overrides are defined in each failue Module - stuff that the generic module can't handle.
            Overrides();
            //listen to ScrapYard Events so we can recalculate when needed
            ScrapYardEvents.OnSYTrackerUpdated.Add(OnSYTrackerUpdated);
            ScrapYardEvents.OnSYInventoryAppliedToVessel.Add(OnSYInventoryAppliedToVessel);
            ScrapYardEvents.OnSYInventoryAppliedToPart.Add(OnSYInventoryAppliedToPart);
            OhScrap = part.FindModuleImplementing <ModuleUPFMEvents>();
            //refresh part if we are in the editor and parts never been used before (just returns if not)
            OhScrap.RefreshPart();
            //Initialise the Failure Module.
            if (launched || HighLogic.LoadedSceneIsEditor)
            {
                Initialise();
            }
        }
예제 #3
0
        /// <summary>
        /// Applies the inventory to a vessel, specifically the part tracker module. Happens in the Editor
        /// </summary>
        /// <param name="input">The vessel as a list of parts</param>
        public static void ApplyInventoryToVessel(IEnumerable <Part> input)
        {
            PartInventory copy = ScrapYard.Instance.TheInventory.Copy();

            foreach (Part part in input)
            {
                //convert it to an inventorypart
                InventoryPart iPart = new InventoryPart(part);
                //find a corresponding one in the inventory and remove it

                InventoryPart inInventory = copy.RemovePart(iPart.ID);
                if (inInventory == null)
                {
                    inInventory = copy.RemovePart(iPart, ComparisonStrength.MODULES);
                }

                //if one was found...
                if (inInventory != null)
                {
                    Logging.DebugLog("Found a part in inventory for " + inInventory.Name);
                    //copy it's part tracker over
                    if (inInventory.TrackerModule != null && part.Modules?.Contains("ModuleSYPartTracker") == true)
                    {
                        ModuleSYPartTracker tracker = part.Modules["ModuleSYPartTracker"] as ModuleSYPartTracker;
                        tracker.TimesRecovered = inInventory.TrackerModule.TimesRecovered;
                        tracker.Inventoried    = inInventory.TrackerModule.Inventoried;
                        tracker.ID             = inInventory.ID;
                        Logging.Log($"Copied tracker. Recovered {tracker.TimesRecovered} times with id {tracker.ID}");
                    }
                }
            }

            ScrapYardEvents.OnSYInventoryAppliedToVessel.Fire();
            GameEvents.onEditorShipModified.Fire(EditorLogic.fetch.ship);
        }
예제 #4
0
        //Removes the parts from the trackers when they die.
        private void OnPartDie(Part part)
        {
            ModuleSYPartTracker SYP = part.FindModuleImplementing <ModuleSYPartTracker>();

            if (SYP == null)
            {
                return;
            }
            generations.Remove(SYP.ID);
#if DEBUG
            Debug.Log("[UPFM]: Stopped Tracking " + SYP.ID);
#endif
        }
예제 #5
0
 public void RefreshPart()
 {
     if (!HighLogic.LoadedSceneIsEditor || refreshed)
     {
         return;
     }
     SYP = part.FindModuleImplementing <ModuleSYPartTracker>();
     if (SYP.TimesRecovered == 0)
     {
         SYP.MakeFresh();
     }
     refreshed = true;
 }
예제 #6
0
        public float GetRandomisation(Part p)
        {
            ModuleSYPartTracker SYP = p.FindModuleImplementing <ModuleSYPartTracker>();

            if (SYP == null)
            {
                return(0);
            }
            float f = 0;

            if (randomisation.TryGetValue(SYP.ID, out f))
            {
                return(f);
            }
            int builds;

            if (HighLogic.LoadedSceneIsEditor)
            {
                builds = ScrapYardWrapper.GetBuildCount(p, ScrapYardWrapper.TrackType.NEW) + 1;
            }
            else
            {
                builds = ScrapYardWrapper.GetBuildCount(p, ScrapYardWrapper.TrackType.NEW);
            }
            int randomFactor = 8;

            if (builds > 0)
            {
                randomFactor = 8 / builds;
            }
            if (randomFactor > 1)
            {
                f = (Randomiser.instance.RandomInteger(1, randomFactor) / 100.0f);
            }
            float threshold = HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().safetyThreshold / 100.0f;

            if (f > threshold)
            {
                f = threshold - 0.01f;
            }
            if (!float.IsNaN(f))
            {
                randomisation.Add(SYP.ID, f);
#if DEBUG
                Debug.Log("[UPFM]: Applied Random Factor of " + f + " to part " + SYP.ID);
#endif
            }
            return(f);
        }
예제 #7
0
 //forces ScrapYard to refresh the part if it's needed.
 public void RefreshPart()
 {
     if (!HighLogic.LoadedSceneIsEditor || refreshed)
     {
         return;
     }
     SYP = part.FindModuleImplementing <ModuleSYPartTracker>();
     Debug.Log("[OhScrap]: Attempting to refresh part " + SYP.ID);
     if (SYP.TimesRecovered == 0)
     {
         SYP.MakeFresh();
         Debug.Log("[OhScrap]: Refreshed. New ID is " + SYP.ID);
     }
     else
     {
         Debug.Log("[OhScrap]: " + SYP.ID + " has been recovered " + SYP.TimesRecovered + " times. No need to refresh");
     }
     refreshed = true;
 }
예제 #8
0
        private void OnPartDie(Part part)
        {
            ModuleSYPartTracker SYP = part.FindModuleImplementing <ModuleSYPartTracker>();

            if (SYP == null)
            {
                return;
            }
            randomisation.Remove(SYP.ID);
            batteryLifetimes.Remove(SYP.ID);
            controlSurfaceLifetimes.Remove(SYP.ID);
            engineLifetimes.Remove(SYP.ID);
            parachuteLifetimes.Remove(SYP.ID);
            reactionWheelLifetimes.Remove(SYP.ID);
            solarPanelLifetimes.Remove(SYP.ID);
            tankLifetimes.Remove(SYP.ID);
#if DEBUG
            Debug.Log("[UPFM]: Stopped Tracking " + SYP.ID);
#endif
        }
예제 #9
0
        public void InventoryChangedEventListener(InventoryPart p, bool added)
        {
            //if removed then check if we should remove a corresponding part from the EditorLogic vessel
            if (!added)
            {
                if (EditorLogic.fetch?.ship?.Parts?.Count > 0)
                {
                    //see if this part is on it, if so, overwrite it with a new one
                    foreach (Part part in EditorLogic.fetch.ship.Parts)
                    {
                        InventoryPart shipPart = new InventoryPart(part);
                        if (p.ID == shipPart.ID)
                        {
                            ModuleSYPartTracker module = part.Modules["ModuleSYPartTracker"] as ModuleSYPartTracker;
                            module.MakeFresh();
                            break; //There can only be one part with this ID
                        }
                    }
                }
            }

            Logging.Log($"InventoryChangedEvent - part: '{p.Name}' added? {added}");
        }
예제 #10
0
        //Like Generations this checks if we've already generated a random factor, and if not generates one.
        public float GetRandomisation(Part p, int builds)
        {
            ModuleSYPartTracker SYP = p.FindModuleImplementing <ModuleSYPartTracker>();

            if (SYP == null)
            {
                return(0);
            }
            float f = 0;

            if (randomisation.TryGetValue(SYP.ID, out f))
            {
                return(f);
            }
            int randomFactor = 1;

            if (builds > 0)
            {
                randomFactor = 1 / builds;
            }
            if (numberOfFailures.TryGetValue(p.name, out int i))
            {
#if DEBUG
                Debug.Log("[UPFM]: " + p.name + " failure bonus of " + i + " applied");
#endif
                f = f / i;
            }
            if (!float.IsNaN(f))
            {
                randomisation.Add(SYP.ID, f);
#if DEBUG
                Debug.Log("[UPFM]: Applied Random Factor of " + f + " to part " + SYP.ID);
#endif
            }
            return(f);
        }
예제 #11
0
        /// <summary>
        /// Fully applies stored modules to the provided part
        /// </summary>
        /// <param name="part">The Part to apply onto</param>
        /// <returns>True if part is the right type</returns>
        public bool FullyApplyToPart(Part part)
        {
            if (part?.partInfo.name != Name)
            {
                return(false);
            }

            if (part.Modules?.Count > 0)
            {
                //we can't just copy saved modules over, since that won't work for going back to default
                //instead we copy all modules over from the default part and load our saved modules instead of default (where appropriate)
                foreach (PartModule defaultModule in part.partInfo.partPrefab.Modules)
                {
                    try
                    {
                        string modName = defaultModule.moduleName;
                        if (modName == "ModuleSYPartTracker")
                        {
                            continue;
                        }
                        ConfigNode copyNode;
                        if ((copyNode = savedModules.Find(m => m.GetValue("name") == modName)) == null)
                        {
                            copyNode = new ConfigNode("MODULE");
                            defaultModule?.Save(copyNode);
                        }
                        if (copyNode.HasData)
                        {
                            if (modName == "TweakScale")
                            {
                                ConfigNode current = new ConfigNode("MODULE");
                                part.Modules[modName].Save(current);
                                if (ScrapYard.Instance.Settings.ModuleTemplates.CheckForMatch(Name, copyNode) || ScrapYard.Instance.Settings.ModuleTemplates.CheckForMatch(Name, current))
                                {
                                    //Because of how tweakscale works, we have to change values on the module itself for the update to work
                                    EditorApplySpecialCases.TweakScale(part, defaultModule, copyNode);
                                }
                            }
                            else
                            {
                                part.Modules[modName].Load(copyNode);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logging.Log($"Error while applying module '{defaultModule.moduleName}'. Error: \n {ex}", Logging.LogType.ERROR);
                    }
                }

                if (part.Modules.Contains("ModuleSYPartTracker"))
                {
                    ModuleSYPartTracker tracker = part.Modules["ModuleSYPartTracker"] as ModuleSYPartTracker;
                    tracker.TimesRecovered = TrackerModule.TimesRecovered;
                    tracker.Inventoried    = TrackerModule.Inventoried;
                    tracker.ID             = TrackerModule.ID.GetValueOrDefault();
                }
            }
            //fire part changed event
            ScrapYardEvents.OnSYInventoryAppliedToPart.Fire(part);
            return(true);
        }
예제 #12
0
        public void Initialise()
        {
            SYP   = part.FindModuleImplementing <ModuleSYPartTracker>();
            ready = SYP.ID != "";
            if (!ready)
            {
                return;
            }
            randomisation = UPFMUtils.instance.GetRandomisation(part);
            if (hasFailed)
            {
                UPFM.Events["RepairChecks"].active    = true;
                UPFM.Events["ToggleHighlight"].active = true;
            }
            else
            {
                if (FailCheck(true) && !HighLogic.LoadedSceneIsEditor && launched)
                {
                    double timeToFailure = (maxTimeToFailure * (1 - chanceOfFailure)) * Randomiser.instance.NextDouble();
                    failureTime = Planetarium.GetUniversalTime() + timeToFailure;
                    willFail    = true;
                    Debug.Log("[UPFM]: " + SYP.ID + " " + ClassName + " will attempt to fail in " + timeToFailure + " seconds");
#if !DEBUG
                    Debug.Log("[UPFM]: Chance of Failure was " + displayChance + "% (Generation " + ScrapYardWrapper.GetBuildCount(part, ScrapYardWrapper.TrackType.NEW) + ")");
#endif
                }
            }
            displayChance = (int)(chanceOfFailure * 100);
            float safetyCalc = 1.0f - ((float)displayChance / HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().safetyThreshold);
            if (safetyCalc > 0.95)
            {
                safetyRating = 5;
            }
            else if (safetyCalc > 0.9)
            {
                safetyRating = 4;
            }
            else if (safetyCalc > 0.8)
            {
                safetyRating = 3;
            }
            else if (safetyCalc > 0.7)
            {
                safetyRating = 2;
            }
            else
            {
                safetyRating = 1;
            }
            if (displayChance > HighLogic.CurrentGame.Parameters.CustomParams <UPFMSettings>().safetyThreshold)
            {
                safetyRating = 0;
            }
            if (chanceOfFailure == 0.01f)
            {
                displayChance = 1;
            }
            if (UPFMUtils.instance != null && hasFailed)
            {
                if (!UPFMUtils.instance.brokenParts.ContainsKey(part))
                {
                    UPFMUtils.instance.brokenParts.Add(part, displayChance);
                }
            }
        }