private void Start() { SYP = part.FindModuleImplementing <ModuleSYPartTracker>(); #if DEBUG Debug.Log("[UPFM]: UPFMEvents.Start" + SYP.ID); #endif }
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(); } }
/// <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); }
//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 }
public void RefreshPart() { if (!HighLogic.LoadedSceneIsEditor || refreshed) { return; } SYP = part.FindModuleImplementing <ModuleSYPartTracker>(); if (SYP.TimesRecovered == 0) { SYP.MakeFresh(); } refreshed = true; }
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); }
//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; }
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 }
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}"); }
//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); }
/// <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); }
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); } } }