public void FacilityUpgradedEvent(Upgradeables.UpgradeableFacility facility, int lvl) { if (KCT_GUI.PrimarilyDisabled) { return; } if (!(allowedToUpgrade || KCT_GameStates.settings.InstantKSCUpgrades)) { KCT_UpgradingBuilding upgrading = new KCT_UpgradingBuilding(facility, lvl, lvl - 1, facility.id.Split('/').Last()); if (!upgrading.AlreadyInProgress()) { upgrading.Downgrade(); double cost = facility.GetUpgradeCost(); upgrading.SetBP(cost); upgrading.cost = cost; KCT_GameStates.ActiveKSC.KSCTech.Add(upgrading); ScreenMessages.PostScreenMessage("Facility upgrade requested!", 4.0f, ScreenMessageStyle.UPPER_CENTER); KCTDebug.Log("Facility " + facility.id + " upgrade requested to lvl " + lvl + " for " + cost + " funds, resulting in a BP of " + upgrading.BP); } else if (lvl != upgrading.currentLevel) { // KCT_UpgradingBuilding listBuilding = upgrading.KSC.KSCTech.Find(b => b.id == upgrading.id); listBuilding.Downgrade(); KCT_Utilities.AddFunds(listBuilding.cost, TransactionReasons.None); ScreenMessages.PostScreenMessage("Facility is already being upgraded!", 4.0f, ScreenMessageStyle.UPPER_CENTER); KCTDebug.Log("Facility " + facility.id + " tried to upgrade to lvl " + lvl + " but already in list!"); } } else { KCTDebug.Log("Facility " + facility.id + " upgraded to lvl " + lvl); allowedToUpgrade = false; foreach (KCT_KSC ksc in KCT_GameStates.KSCs) { ksc.RecalculateBuildRates(); ksc.RecalculateUpgradedBuildRates(); } foreach (KCT_TechItem tech in KCT_GameStates.TechList) { tech.UpdateBuildRate(); } } /* if (lvl <= lastLvl) * { * lastLvl = -1; * return; * } * facility.SetLevel(lvl - 1); * lastLvl = lvl; * double cost = facility.GetUpgradeCost(); * double BP = Math.Sqrt(cost) * 2000 * KCT_GameStates.timeSettings.OverallMultiplier;*/ // KCTDebug.Log(facility.GetNormLevel()); }
public static void PopUpVesselError(List <KCT_BuildListVessel> errored) { DialogGUIBase[] options = new DialogGUIBase[2]; options[0] = new DialogGUIButton("Understood", () => { }); // new DialogGUIBase("Understood", () => { }); //do nothing and close the window options[1] = new DialogGUIButton("Delete Vessels", () => { foreach (KCT_BuildListVessel blv in errored) { blv.RemoveFromBuildList(); KCT_Utilities.AddFunds(blv.cost, TransactionReasons.VesselRollout); //remove any associated recon_rollout } }); string txt = "The following KCT vessels contain missing or invalid parts and have been quarantined. Either add the missing parts back into your game or delete the vessels. A file containing the ship names and missing parts has been added to your save folder.\n"; string txtToWrite = ""; foreach (KCT_BuildListVessel blv in errored) { txt += blv.shipName + "\n"; txtToWrite += blv.shipName + "\n"; txtToWrite += String.Join("\n", blv.MissingParts().ToArray()); txtToWrite += "\n\n"; } //HighLogic.SaveFolder //make new file for missing ships string filename = KSPUtil.ApplicationRootPath + "/saves/" + HighLogic.SaveFolder + "/missingParts.txt"; System.IO.File.WriteAllText(filename, txtToWrite); //remove all rollout and recon items since they're invalid without the ships foreach (KCT_BuildListVessel blv in errored) { //remove any associated recon_rollout foreach (KCT_KSC ksc in KCT_GameStates.KSCs) { for (int i = 0; i < ksc.Recon_Rollout.Count; i++) { KCT_Recon_Rollout rr = ksc.Recon_Rollout[i]; if (rr.associatedID == blv.id.ToString()) { ksc.Recon_Rollout.Remove(rr); i--; } } } } MultiOptionDialog diag = new MultiOptionDialog("missingPartsPopup", txt, "Vessels Contain Missing Parts", null, options); PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), diag, false, HighLogic.UISkin); //PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), "Vessel Contains Missing Parts", "The KCT vessel " + errored.shipName + " contains missing or invalid parts. You will not be able to do anything with the vessel until the parts are available again.", "Understood", false, HighLogic.UISkin); }
public void PartPurchasedEvent(AvailablePart part) { if (HighLogic.CurrentGame.Parameters.Difficulty.BypassEntryPurchaseAfterResearch) { return; } KCT_TechItem tech = KCT_GameStates.TechList.Find(t => t.techID == part.TechRequired); if (tech != null && tech.isInList()) { ScreenMessages.PostScreenMessage("[KCT] You must wait until the node is fully researched to purchase parts!", 4.0f, ScreenMessageStyle.UPPER_LEFT); KCT_Utilities.AddFunds(part.entryCost, TransactionReasons.RnDPartPurchase); tech.protoNode.partsPurchased.Remove(part); tech.DisableTech(); } }
public void Start() { if (KCT_Utilities.CurrentGameIsMission()) { return; } KCTDebug.Log("Start called"); // Subscribe to events from KSP and other mods if (!KCT_Events.instance.subscribedToEvents) { KCT_Events.instance.SubscribeToEvents(); } KCT_GameStates.settings.Save(); //Save the settings file, with defaults if it doesn't exist KCT_PresetManager.Instance.SaveActiveToSaveData(); // Ghetto event queue if (HighLogic.LoadedScene == GameScenes.EDITOR) { InvokeRepeating("EditorRecalculation", 1, 1); KCT_GUI.buildRateForDisplay = null; if (!KCT_GUI.PrimarilyDisabled) { KCT_Utilities.RecalculateEditorBuildTime(EditorLogic.fetch.ship); } } if (KCT_GUI.PrimarilyDisabled) { if (InputLockManager.GetControlLock("KCTLaunchLock") == ControlTypes.EDITOR_LAUNCH) { InputLockManager.RemoveControlLock("KCTLaunchLock"); } } KACWrapper.InitKACWrapper(); if (!KCT_PresetManager.Instance.ActivePreset.generalSettings.Enabled) { if (InputLockManager.GetControlLock("KCTKSCLock") == ControlTypes.KSC_FACILITIES) { InputLockManager.RemoveControlLock("KCTKSCLock"); } return; } //Begin primary mod functions KCT_GameStates.UT = Planetarium.GetUniversalTime(); KCT_GUI.guiDataSaver.Load(); switch (HighLogic.LoadedScene) { case GameScenes.EDITOR: //if (HighLogic.LoadedSceneIsEditor) { KCT_GUI.hideAll(); if (!KCT_GUI.PrimarilyDisabled) { KCT_GUI.showEditorGUI = KCT_GameStates.showWindows[1]; if (KCT_GUI.showEditorGUI) { KCT_GUI.ClickOn(); } else { KCT_GUI.ClickOff(); } } } break; case GameScenes.SPACECENTER: //else if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { bool shouldStart = KCT_GUI.showFirstRun; KCT_GUI.hideAll(); if (!shouldStart) { KCT_GUI.showBuildList = KCT_GameStates.showWindows[0]; if (KCT_GUI.showBuildList) { KCT_GUI.ClickOn(); } else { KCT_GUI.ClickOff(); } } KCT_GUI.showFirstRun = shouldStart; } break; case GameScenes.FLIGHT: if (/*HighLogic.LoadedSceneIsFlight && */ FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH && FlightGlobals.ActiveVessel.GetCrewCount() == 0 && KCT_GameStates.launchedCrew.Count > 0) { KerbalRoster roster = HighLogic.CurrentGame.CrewRoster; for (int i = 0; i < FlightGlobals.ActiveVessel.parts.Count; i++) { Part p = FlightGlobals.ActiveVessel.parts[i]; //KCTDebug.Log("craft: " + p.craftID); KCTDebug.LogError("Part being tested: " + p.partInfo.title); { CrewedPart cP = KCT_GameStates.launchedCrew.Find(part => part.partID == p.craftID); if (cP == null) { continue; } List <ProtoCrewMember> crewList = cP.crewList; KCTDebug.LogError("cP.crewList.Count: " + cP.crewList.Count); foreach (ProtoCrewMember crewMember in crewList) { if (crewMember != null) { ProtoCrewMember finalCrewMember = crewMember; if (crewMember.type == ProtoCrewMember.KerbalType.Crew) { finalCrewMember = roster.Crew.FirstOrDefault(c => c.name == crewMember.name); } else if (crewMember.type == ProtoCrewMember.KerbalType.Tourist) { finalCrewMember = roster.Tourist.FirstOrDefault(c => c.name == crewMember.name); } if (finalCrewMember == null) { KCTDebug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name + ". Cannot find Kerbal in list."); continue; } try { KCTDebug.Log("Assigning " + finalCrewMember.name + " to " + p.partInfo.name); if (p.AddCrewmember(finalCrewMember)) //p.AddCrewmemberAt(finalCrewMember, crewList.IndexOf(crewMember))) { finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Assigned; if (finalCrewMember.seat != null) { finalCrewMember.seat.SpawnCrew(); } } else { KCTDebug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name); finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available; continue; } } catch { KCTDebug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name); finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available; continue; } } } } } KCT_GameStates.launchedCrew.Clear(); } //if (HighLogic.LoadedSceneIsFlight) { KCT_GUI.hideAll(); if (KCT_GameStates.launchedVessel != null && FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH) { KCT_GameStates.launchedVessel.KSC = null; //it's invalid now KCTDebug.Log("Attempting to remove launched vessel from build list"); bool removed = KCT_GameStates.launchedVessel.RemoveFromBuildList(); if (removed) //Only do these when the vessel is first removed from the list { //Add the cost of the ship to the funds so it can be removed again by KSP KCT_Utilities.AddFunds(KCT_GameStates.launchedVessel.cost, TransactionReasons.VesselRollout); FlightGlobals.ActiveVessel.vesselName = KCT_GameStates.launchedVessel.shipName; } KCT_Recon_Rollout rollout = KCT_GameStates.ActiveKSC.Recon_Rollout.FirstOrDefault(r => r.associatedID == KCT_GameStates.launchedVessel.id.ToString()); if (rollout != null) { KCT_GameStates.ActiveKSC.Recon_Rollout.Remove(rollout); } KCT_AirlaunchPrep alPrep = KCT_GameStates.ActiveKSC.AirlaunchPrep.FirstOrDefault(r => r.associatedID == KCT_GameStates.launchedVessel.id.ToString()); if (alPrep != null) { KCT_GameStates.ActiveKSC.AirlaunchPrep.Remove(alPrep); } AirlaunchParams alParams = KCT_GameStates.AirlaunchParams; if (alParams != null && alParams.KCTVesselId == KCT_GameStates.launchedVessel.id && (!alParams.KSPVesselId.HasValue || alParams.KSPVesselId == FlightGlobals.ActiveVessel.id)) { if (!alParams.KSPVesselId.HasValue) { alParams.KSPVesselId = FlightGlobals.ActiveVessel.id; } StartCoroutine(AirlaunchRoutine(alParams, FlightGlobals.ActiveVessel.id)); } } } break; } ratesUpdated = false; KCTDebug.Log("Start finished"); wfsOne = new WaitForSeconds(1f); wfsTwo = new WaitForSeconds(2f); wfsHalf = new WaitForSeconds(0.5f); DelayedStart(); UpdateTechlistIconColor(); StartCoroutine(HandleEditorButton_Coroutine()); }
public void FacilityUpgradedEvent(Upgradeables.UpgradeableFacility facility, int lvl) { if (KCT_GUI.PrimarilyDisabled) { bool isLaunchpad = facility.id.ToLower().Contains("launchpad"); if (!isLaunchpad) { return; } //is a launch pad KCT_GameStates.ActiveKSC.ActiveLPInstance.Upgrade(lvl); } if (!(allowedToUpgrade || !KCT_PresetManager.Instance.ActivePreset.generalSettings.KSCUpgradeTimes)) { KCT_UpgradingBuilding upgrading = new KCT_UpgradingBuilding(facility, lvl, lvl - 1, facility.id.Split('/').Last()); upgrading.isLaunchpad = facility.id.ToLower().Contains("launchpad"); if (upgrading.isLaunchpad) { upgrading.launchpadID = KCT_GameStates.ActiveKSC.ActiveLaunchPadID; if (upgrading.launchpadID > 0) { upgrading.commonName += KCT_GameStates.ActiveKSC.ActiveLPInstance.name;//" " + (upgrading.launchpadID+1); } } if (!upgrading.AlreadyInProgress()) { KCT_GameStates.ActiveKSC.KSCTech.Add(upgrading); upgrading.Downgrade(); double cost = facility.GetUpgradeCost(); upgrading.SetBP(cost); upgrading.cost = cost; ScreenMessages.PostScreenMessage("Facility upgrade requested!", 4.0f, ScreenMessageStyle.UPPER_CENTER); KCTDebug.Log("Facility " + facility.id + " upgrade requested to lvl " + lvl + " for " + cost + " funds, resulting in a BP of " + upgrading.BP); } else if (lvl != upgrading.currentLevel) { // KCT_UpgradingBuilding listBuilding = upgrading.KSC.KSCTech.Find(b => b.id == upgrading.id); if (upgrading.isLaunchpad) { listBuilding = upgrading.KSC.KSCTech.Find(b => b.isLaunchpad && b.launchpadID == upgrading.launchpadID); } listBuilding.Downgrade(); KCT_Utilities.AddFunds(listBuilding.cost, TransactionReasons.None); ScreenMessages.PostScreenMessage("Facility is already being upgraded!", 4.0f, ScreenMessageStyle.UPPER_CENTER); KCTDebug.Log("Facility " + facility.id + " tried to upgrade to lvl " + lvl + " but already in list!"); } } else { KCTDebug.Log("Facility " + facility.id + " upgraded to lvl " + lvl); if (facility.id.ToLower().Contains("launchpad")) { if (!allowedToUpgrade) { KCT_GameStates.ActiveKSC.ActiveLPInstance.Upgrade(lvl); //also repairs the launchpad } else { KCT_GameStates.ActiveKSC.ActiveLPInstance.level = lvl; } } allowedToUpgrade = false; foreach (KCT_KSC ksc in KCT_GameStates.KSCs) { ksc.RecalculateBuildRates(); ksc.RecalculateUpgradedBuildRates(); } foreach (KCT_TechItem tech in KCT_GameStates.TechList) { tech.UpdateBuildRate(KCT_GameStates.TechList.IndexOf(tech)); } } /* if (lvl <= lastLvl) * { * lastLvl = -1; * return; * } * facility.SetLevel(lvl - 1); * lastLvl = lvl; * double cost = facility.GetUpgradeCost(); * double BP = Math.Sqrt(cost) * 2000 * KCT_GameStates.timeSettings.OverallMultiplier;*/ // KCTDebug.Log(facility.GetNormLevel()); }
public static void DelayedStart() { // KCTDebug.Log(ScenarioUpgradeableFacilities.protoUpgradeables.Keys); // KCTDebug.Log(ScenarioUpgradeableFacilities.protoUpgradeables.Values.ElementAt(0).facilityRefs[0].name); /* if (!updateChecked) * { * if (KCT_GameStates.settings.CheckForUpdates && !KCT_GameStates.firstStart) //Check for updates * KCT_UpdateChecker.CheckForUpdate(false, KCT_GameStates.settings.VersionSpecific); * updateChecked = true; * }*/ if (!KCT_PresetManager.Instance.ActivePreset.generalSettings.Enabled) { return; } List <GameScenes> validScenes = new List <GameScenes> { GameScenes.SPACECENTER }; if (validScenes.Contains(HighLogic.LoadedScene)) { //Check for simulation save and load it. string backupFile = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/KCT_simulation_backup.sfs"; if (System.IO.File.Exists(backupFile)) { KCT_GameStates.LoadingSimulationSave = true; /* if (!KCT_GameStates.LoadingSimulationSave) * KCT_Utilities.LoadSimulationSave(); * else * System.IO.File.Delete(backupFile);*/ } } if (HighLogic.LoadedSceneIsFlight && KCT_GameStates.flightSimulated) { KCTDebug.Log("Simulation started"); KCT_GUI.hideAll(); KCT_GUI.showSimulationWindow = !KCT_GameStates.settings.NoSimGUI; KCT_GUI.showTimeRemaining = true; if (!KCT_GameStates.simulationInitialized) { Planetarium.SetUniversalTime(KCT_GameStates.simulationUT); KCT_GameStates.simulationInitialized = true; } } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsToChargeAtSimEnd != 0) { KCT_Utilities.SpendFunds(KCT_GameStates.FundsToChargeAtSimEnd, TransactionReasons.None); KCT_GameStates.FundsToChargeAtSimEnd = 0; } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsGivenForVessel != 0) { KCT_Utilities.SpendFunds(KCT_GameStates.FundsGivenForVessel, TransactionReasons.VesselRollout); KCT_GameStates.FundsGivenForVessel = 0; } if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated) { List <VesselType> invalidTypes = new List <VesselType> { VesselType.Debris, VesselType.SpaceObject, VesselType.Unknown }; if (!invalidTypes.Contains(FlightGlobals.ActiveVessel.vesselType) && !KCT_GameStates.BodiesVisited.Contains(FlightGlobals.ActiveVessel.mainBody.bodyName)) { KCT_GameStates.BodiesVisited.Add(FlightGlobals.ActiveVessel.mainBody.bodyName); var message = new ScreenMessage("[KCT] New simulation body unlocked: " + FlightGlobals.ActiveVessel.mainBody.bodyName, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(message, true); KCTDebug.Log("Unlocked sim body: " + FlightGlobals.ActiveVessel.mainBody.bodyName); } } if (KCT_GUI.PrimarilyDisabled) { return; } //The following should only be executed when fully enabled for the save //check that all parts are valid in all ships. If not, warn the user and disable that vessel (once that code is written) if (!KCT_GameStates.vesselErrorAlerted) { List <KCT_BuildListVessel> erroredVessels = new List <KCT_BuildListVessel>(); foreach (KCT_KSC KSC in KCT_GameStates.KSCs) //this is faster one subsequent scene changes { foreach (KCT_BuildListVessel blv in KSC.VABList) { if (!blv.allPartsValid) { //error! KCTDebug.Log(blv.shipName + " contains invalid parts!"); erroredVessels.Add(blv); } } foreach (KCT_BuildListVessel blv in KSC.VABWarehouse) { if (!blv.allPartsValid) { //error! KCTDebug.Log(blv.shipName + " contains invalid parts!"); erroredVessels.Add(blv); } } foreach (KCT_BuildListVessel blv in KSC.SPHList) { if (!blv.allPartsValid) { //error! KCTDebug.Log(blv.shipName + " contains invalid parts!"); erroredVessels.Add(blv); } } foreach (KCT_BuildListVessel blv in KSC.SPHWarehouse) { if (!blv.allPartsValid) { //error! KCTDebug.Log(blv.shipName + " contains invalid parts!"); erroredVessels.Add(blv); } } } if (erroredVessels.Count > 0) { PopUpVesselError(erroredVessels); } KCT_GameStates.vesselErrorAlerted = true; } foreach (KCT_KSC KSC in KCT_GameStates.KSCs) { KSC.RecalculateBuildRates(); KSC.RecalculateUpgradedBuildRates(); } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.buildSimulatedVessel) { KCT_GameStates.buildSimulatedVessel = false; KCT_BuildListVessel toBuild = KCT_GameStates.launchedVessel.NewCopy(false); toBuild.buildPoints = KCT_Utilities.GetBuildTime(toBuild.ExtractedPartNodes, true, KCT_GUI.useInventory); KCT_Utilities.AddVesselToBuildList(toBuild, KCT_GUI.useInventory); } if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated) { KCT_GUI.hideAll(); if (FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH && KCT_GameStates.launchedVessel != null) { bool removed = KCT_GameStates.launchedVessel.RemoveFromBuildList(); if (removed) //Only do these when the vessel is first removed from the list { //Add the cost of the ship to the funds so it can be removed again by KSP //KCT_Utilities.AddFunds(KCT_Utilities.GetTotalVesselCost(FlightGlobals.ActiveVessel.protoVessel), TransactionReasons.VesselRollout); KCT_Utilities.AddFunds(KCT_GameStates.launchedVessel.cost, TransactionReasons.VesselRollout); FlightGlobals.ActiveVessel.vesselName = KCT_GameStates.launchedVessel.shipName; } KCT_Recon_Rollout rollout = KCT_GameStates.ActiveKSC.Recon_Rollout.FirstOrDefault(r => r.associatedID == KCT_GameStates.launchedVessel.id.ToString()); if (rollout != null) { KCT_GameStates.ActiveKSC.Recon_Rollout.Remove(rollout); } } } if (HighLogic.LoadedSceneIsEditor) { if (KCT_GameStates.EditorShipEditingMode) { KCTDebug.Log("Editing " + KCT_GameStates.editedVessel.shipName); EditorLogic.fetch.shipNameField.Text = KCT_GameStates.editedVessel.shipName; } if (!KCT_GUI.PrimarilyDisabled) { if (KCT_GameStates.settings.OverrideLaunchButton) { KCTDebug.Log("Taking control of launch button"); EditorLogic.fetch.launchBtn.methodToInvoke = "ShowLaunchAlert"; EditorLogic.fetch.launchBtn.scriptWithMethodToInvoke = KerbalConstructionTime.instance; } else { InputLockManager.SetControlLock(ControlTypes.EDITOR_LAUNCH, "KCTLaunchLock"); } KCT_Utilities.RecalculateEditorBuildTime(EditorLogic.fetch.ship); } } if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { if (!KCT_GUI.PrimarilyDisabled) { if (ToolbarManager.ToolbarAvailable && KCT_GameStates.settings.PreferBlizzyToolbar) { if (KCT_GameStates.showWindows[0]) { KCT_GUI.ClickOn(); } else { if (KCT_Events.instance != null && KCT_Events.instance.KCTButtonStock != null) { //KCT_Events.instance.KCTButtonStock.SetTrue(true); //KCT_GUI.clicked = true; if (KCT_GameStates.showWindows[0]) { KCT_GUI.ClickOn(); } } /* else * { * KCT_GUI.showEditorGUI = KCT_GameStates.showWindows[0]; * }*/ } } KCT_GUI.ResetBLWindow(); } else { KCT_GUI.showBuildList = false; KCT_GameStates.showWindows[0] = false; } if (KCT_GameStates.firstStart) { KCTDebug.Log("Showing first start."); KCT_GUI.showFirstRun = true; //initialize the proper launchpad KCT_GameStates.ActiveKSC.ActiveLPInstance.level = KCT_Utilities.BuildingUpgradeLevel(SpaceCenterFacility.LaunchPad); } KCT_GameStates.firstStart = false; if (KCT_GameStates.LaunchFromTS) { KCT_GameStates.launchedVessel.Launch(); } KCT_GameStates.ActiveKSC.SwitchLaunchPad(KCT_GameStates.ActiveKSC.ActiveLaunchPadID); foreach (KCT_KSC ksc in KCT_GameStates.KSCs) { //foreach (KCT_Recon_Rollout rr in ksc.Recon_Rollout) for (int i = 0; i < ksc.Recon_Rollout.Count; i++) { KCT_Recon_Rollout rr = ksc.Recon_Rollout[i]; if (rr.RRType != KCT_Recon_Rollout.RolloutReconType.Reconditioning && KCT_Utilities.FindBLVesselByID(new Guid(rr.associatedID)) == null) { KCTDebug.Log("Invalid Recon_Rollout at " + ksc.KSCName + ". ID " + rr.associatedID + " not found."); ksc.Recon_Rollout.Remove(rr); i--; } } } } }
public void vesselDestroyEvent(Vessel v) { if (!KCT_GameStates.settings.enabledForSave) { return; } if (!KCT_GameStates.settings.AllowParachuteRecovery) { return; } Dictionary <string, int> PartsRecovered = new Dictionary <string, int>(); float FundsRecovered = 0, KSCDistance = 0, RecoveryPercent = 0; StringBuilder Message = new StringBuilder(); if (FlightGlobals.fetch == null) { return; } if (v != null && !(HighLogic.LoadedSceneIsFlight && v.isActiveVessel) && v.mainBody.bodyName == "Kerbin" && (!v.loaded || v.packed) && v.altitude < 35000 && (v.situation == Vessel.Situations.FLYING || v.situation == Vessel.Situations.SUB_ORBITAL) && !v.isEVA) { double totalMass = 0; double dragCoeff = 0; bool realChuteInUse = false; float RCParameter = 0; if (!v.packed) //adopted from mission controller. { foreach (Part p in v.Parts) { p.Pack(); } } if (v.protoVessel == null) { return; } KCTDebug.Log("Attempting to recover vessel."); try { foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { //KCTDebug.Log("Has part " + p.partName + ", mass " + p.mass); List <string> ModuleNames = new List <string>(); foreach (ProtoPartModuleSnapshot ppms in p.modules) { //Debug.Log(ppms.moduleName); ModuleNames.Add(ppms.moduleName); } totalMass += p.mass; totalMass += GetResourceMass(p.resources); bool isParachute = false; if (ModuleNames.Contains("ModuleParachute")) { KCTDebug.Log("Found parachute module on " + p.partInfo.name); //Find the ModuleParachute (find it in the module list by checking for a module with the name ModuleParachute) ProtoPartModuleSnapshot ppms = p.modules.First(mod => mod.moduleName == "ModuleParachute"); float drag = 500; if (ppms.moduleRef != null) { ModuleParachute mp = (ModuleParachute)ppms.moduleRef; mp.Load(ppms.moduleValues); drag = mp.fullyDeployedDrag; } else { drag = KCT_Utilities.GetParachuteDragFromPart(p.partInfo); KCTDebug.Log("Pulled drag info from part. Drag: " + drag); } //Add the part mass times the fully deployed drag (typically 500) to the dragCoeff variable (you'll see why later) dragCoeff += p.mass * drag; //This is most definitely a parachute part isParachute = true; } if (ModuleNames.Contains("RealChuteModule")) { KCTDebug.Log("Found realchute module on " + p.partInfo.name); ProtoPartModuleSnapshot realChute = p.modules.First(mod => mod.moduleName == "RealChuteModule"); if ((object)realChute != null) //Some of this was adopted from DebRefund, as Vendan's method of handling multiple parachutes is better than what I had. { Type matLibraryType = AssemblyLoader.loadedAssemblies .SelectMany(a => a.assembly.GetExportedTypes()) .SingleOrDefault(t => t.FullName == "RealChute.Libraries.MaterialsLibrary"); ConfigNode[] parchutes = realChute.moduleValues.GetNodes("PARACHUTE"); foreach (ConfigNode chute in parchutes) { float diameter = float.Parse(chute.GetValue("deployedDiameter")); string mat = chute.GetValue("material"); System.Reflection.MethodInfo matMethod = matLibraryType.GetMethod("GetMaterial", new Type[] { mat.GetType() }); object MatLibraryInstance = matLibraryType.GetProperty("instance").GetValue(null, null); object materialObject = matMethod.Invoke(MatLibraryInstance, new object[] { mat }); float dragC = (float)KCT_Utilities.GetMemberInfoValue(materialObject.GetType().GetMember("dragCoefficient")[0], materialObject); RCParameter += dragC * (float)Math.Pow(diameter, 2); } isParachute = true; realChuteInUse = true; } } if (!isParachute) { if (p.partRef != null) { dragCoeff += p.mass * p.partRef.maximum_drag; } else { dragCoeff += p.mass * 0.2; } } } } catch (Exception e) { Debug.LogError("[KCT] Error while attempting to recover vessel."); Debug.LogException(e); } double Vt = double.MaxValue; if (!realChuteInUse) { dragCoeff = dragCoeff / (totalMass); Vt = Math.Sqrt((250 * 6.674E-11 * 5.2915793E22) / (3.6E11 * 1.22309485 * dragCoeff)); KCTDebug.Log("Using Stock Module! Drag: " + dragCoeff + " Vt: " + Vt); } else { Vt = Math.Sqrt((8000 * totalMass * 9.8) / (1.223 * Math.PI) * Math.Pow(RCParameter, -1)); //This should work perfect for multiple identical chutes and gives an approximation for multiple differing chutes KCTDebug.Log("Using RealChute Module! Vt: " + Vt); } if (Vt < 10.0) { KCTDebug.Log("Recovered parts from " + v.vesselName); foreach (ProtoPartSnapshot p in v.protoVessel.protoPartSnapshots) { KCT_Utilities.AddPartToInventory(p); if (!PartsRecovered.ContainsKey(p.partInfo.title)) { PartsRecovered.Add(p.partInfo.title, 1); } else { ++PartsRecovered[p.partInfo.title]; } } Message.AppendLine("Vessel name: " + v.vesselName); Message.AppendLine("Parts recovered: "); for (int i = 0; i < PartsRecovered.Count; i++) { Message.AppendLine(PartsRecovered.Values.ElementAt(i) + "x " + PartsRecovered.Keys.ElementAt(i)); } if (KCT_Utilities.CurrentGameIsCareer()) { if (KCT_Utilities.StageRecoveryAddonActive || KCT_Utilities.DebRefundAddonActive) //Delegate funds handling to Stage Recovery or DebRefund if it's present { KCTDebug.Log("Delegating Funds recovery to another addon."); } else //Otherwise do it ourselves { bool probeCoreAttached = false; foreach (ProtoPartSnapshot pps in v.protoVessel.protoPartSnapshots) { //if (pps.modules.Find(module => (module.moduleName == "ModuleCommand" && KCT_Utilities.IsUnmannedCommand(pps.partInfo))) != null) if (v.protoVessel.wasControllable) { KCTDebug.Log("Was controlled!"); probeCoreAttached = true; break; } } float RecoveryMod = probeCoreAttached ? 1.0f : KCT_GameStates.settings.RecoveryModifier; KSCDistance = (float)SpaceCenter.Instance.GreatCircleDistance(SpaceCenter.Instance.cb.GetRelSurfaceNVector(v.protoVessel.latitude, v.protoVessel.longitude)); double maxDist = SpaceCenter.Instance.cb.Radius * Math.PI; RecoveryPercent = RecoveryMod * Mathf.Lerp(0.98f, 0.1f, (float)(KSCDistance / maxDist)); float totalReturn = 0; foreach (ProtoPartSnapshot pps in v.protoVessel.protoPartSnapshots) { float dryCost, fuelCost; totalReturn += Math.Max(ShipConstruction.GetPartCosts(pps, pps.partInfo, out dryCost, out fuelCost), 0); } float totalBeforeModifier = totalReturn; totalReturn *= RecoveryPercent; FundsRecovered = totalReturn; KCTDebug.Log("Vessel being recovered by KCT. Percent returned: " + 100 * RecoveryPercent + "%. Distance from KSC: " + Math.Round(KSCDistance / 1000, 2) + " km"); KCTDebug.Log("Funds being returned: " + Math.Round(totalReturn, 2) + "/" + Math.Round(totalBeforeModifier, 2)); Message.AppendLine("Funds recovered: " + FundsRecovered + "(" + Math.Round(RecoveryPercent * 100, 1) + "%)"); KCT_Utilities.AddFunds(FundsRecovered, TransactionReasons.VesselRecovery); } } Message.AppendLine("\nAdditional information:"); Message.AppendLine("Distance from KSC: " + Math.Round(KSCDistance / 1000, 2) + " km"); if (!realChuteInUse) { Message.AppendLine("Stock module used. Terminal velocity (less than 10 needed): " + Math.Round(Vt, 2)); } else { Message.AppendLine("RealChute module used. Terminal velocity (less than 10 needed): " + Math.Round(Vt, 2)); } if (!(KCT_Utilities.StageRecoveryAddonActive || KCT_Utilities.DebRefundAddonActive) && (KCT_Utilities.CurrentGameIsCareer() || !KCT_GUI.PrimarilyDisabled) && !(KCT_GameStates.settings.DisableAllMessages || KCT_GameStates.settings.DisableRecoveryMessages)) { KCT_Utilities.DisplayMessage("Stage Recovered", Message, MessageSystemButton.MessageButtonColor.BLUE, MessageSystemButton.ButtonIcons.MESSAGE); } } } }
public void Start() { const string logBlockName = nameof(KerbalConstructionTime) + "." + nameof(Start); using (EntryExitLogger.EntryExitLog(logBlockName, EntryExitLoggerOptions.All)) { if (KCT_Utilities.CurrentGameIsMission()) { return; } Log.Trace("Start called"); //add the events if (!KCTEvents.instance.eventAdded) { KCTEvents.instance.addEvents(); } GameStates.settings.Save(); //Save the settings file, with defaults if it doesn't exist KCT_PresetManager.Instance.SaveActiveToSaveData(); // Ghetto event queue if (HighLogic.LoadedScene == GameScenes.EDITOR) { InvokeRepeating("EditorRecalculation", 1, 1); KCT_GUI.buildRateForDisplay = null; if (!KCT_GUI.PrimarilyDisabled) { KCT_Utilities.RecalculateEditorBuildTime(EditorLogic.fetch.ship); } } if (KCT_GUI.PrimarilyDisabled) { if (InputLockManager.GetControlLock("KCTLaunchLock") == ControlTypes.EDITOR_LAUNCH) { InputLockManager.RemoveControlLock("KCTLaunchLock"); } } KACWrapper.InitKACWrapper(); if (!KCT_PresetManager.Instance.ActivePreset.generalSettings.Enabled) { if (InputLockManager.GetControlLock("KCTKSCLock") == ControlTypes.KSC_FACILITIES) { InputLockManager.RemoveControlLock("KCTKSCLock"); } return; } //Begin primary mod functions GameStates.UT = Planetarium.GetUniversalTime(); KCT_GUI.guiDataSaver.Load(); if (HighLogic.LoadedSceneIsEditor) { KCT_GUI.hideAll(); if (!KCT_GUI.PrimarilyDisabled) { KCT_GUI.showEditorGUI = GameStates.showWindows[1]; if (KCT_GUI.showEditorGUI) { KCT_GUI.ClickOn(); } else { KCT_GUI.ClickOff(); } } } else if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { bool shouldStart = KCT_GUI.showFirstRun; KCT_GUI.hideAll(); if (!shouldStart) { KCT_GUI.showBuildList = GameStates.showWindows[0]; if (KCT_GUI.showBuildList) { KCT_GUI.ClickOn(); } else { KCT_GUI.ClickOff(); } } KCT_GUI.showFirstRun = shouldStart; } if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH) { if (FlightGlobals.ActiveVessel.GetCrewCount() == 0 && GameStates.launchedCrew.Count > 0) { KerbalRoster roster = HighLogic.CurrentGame.CrewRoster; for (int i = 0; i < FlightGlobals.ActiveVessel.parts.Count; i++) { Part p = FlightGlobals.ActiveVessel.parts[i]; //Log.Trace("craft: " + p.craftID); { CrewedPart cP = GameStates.launchedCrew.Find(part => part.partID == p.craftID); if (cP == null) { continue; } List <ProtoCrewMember> crewList = cP.crewList; foreach (ProtoCrewMember crewMember in crewList) { if (crewMember != null) { ProtoCrewMember finalCrewMember = crewMember; if (crewMember.type == ProtoCrewMember.KerbalType.Crew) { finalCrewMember = roster.Crew.FirstOrDefault(c => c.name == crewMember.name); } else if (crewMember.type == ProtoCrewMember.KerbalType.Tourist) { finalCrewMember = roster.Tourist.FirstOrDefault(c => c.name == crewMember.name); } if (finalCrewMember == null) { Debug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name + ". Cannot find Kerbal in list."); continue; } try { Log.Trace("Assigning " + finalCrewMember.name + " to " + p.partInfo.name); if (p.AddCrewmember(finalCrewMember)) //p.AddCrewmemberAt(finalCrewMember, crewList.IndexOf(crewMember))) { finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Assigned; if (finalCrewMember.seat != null) { finalCrewMember.seat.SpawnCrew(); } } else { Debug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name); finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available; continue; } } catch { Debug.LogError("Error when assigning " + crewMember.name + " to " + p.partInfo.name); finalCrewMember.rosterStatus = ProtoCrewMember.RosterStatus.Available; continue; } } } } } GameStates.launchedCrew.Clear(); } } if (HighLogic.LoadedSceneIsFlight) { KCT_GUI.hideAll(); if (GameStates.launchedVessel != null && FlightGlobals.ActiveVessel != null && FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH) { GameStates.launchedVessel.KSC = null; //it's invalid now Log.Trace("Attempting to remove launched vessel from build list"); bool removed = GameStates.launchedVessel.RemoveFromBuildList(); if (removed) //Only do these when the vessel is first removed from the list { //Add the cost of the ship to the funds so it can be removed again by KSP KCT_Utilities.AddFunds(GameStates.launchedVessel.cost, TransactionReasons.VesselRollout); FlightGlobals.ActiveVessel.vesselName = GameStates.launchedVessel.shipName; } Recon_Rollout rollout = GameStates.ActiveKSC.Recon_Rollout.FirstOrDefault(r => r.associatedID == GameStates.launchedVessel.id.ToString()); if (rollout != null) { GameStates.ActiveKSC.Recon_Rollout.Remove(rollout); } } } ratesUpdated = false; DelayedStart(); } }
public static void DelayedStart() { // KCTDebug.Log(ScenarioUpgradeableFacilities.protoUpgradeables.Keys); // KCTDebug.Log(ScenarioUpgradeableFacilities.protoUpgradeables.Values.ElementAt(0).facilityRefs[0].name); if (!updateChecked) { if (KCT_GameStates.settings.CheckForUpdates && !KCT_GameStates.firstStart) //Check for updates { KCT_UpdateChecker.CheckForUpdate(false, KCT_GameStates.settings.VersionSpecific); } updateChecked = true; } if (!KCT_GameStates.settings.enabledForSave) { return; } List <GameScenes> validScenes = new List <GameScenes> { GameScenes.SPACECENTER }; if (validScenes.Contains(HighLogic.LoadedScene)) { //Check for simulation save and load it. string backupFile = KSPUtil.ApplicationRootPath + "saves/" + HighLogic.SaveFolder + "/KCT_simulation_backup.sfs"; if (System.IO.File.Exists(backupFile)) { KCT_GameStates.LoadingSimulationSave = true; /* if (!KCT_GameStates.LoadingSimulationSave) * KCT_Utilities.LoadSimulationSave(); * else * System.IO.File.Delete(backupFile);*/ } } if (HighLogic.LoadedSceneIsFlight && KCT_GameStates.flightSimulated) { KCTDebug.Log("Simulation started"); KCT_GUI.hideAll(); KCT_GUI.showSimulationWindow = !KCT_GameStates.settings.NoSimGUI; KCT_GUI.showTimeRemaining = true; Planetarium.SetUniversalTime(KCT_GameStates.simulationUT); } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsToChargeAtSimEnd != 0) { KCT_Utilities.SpendFunds(KCT_GameStates.FundsToChargeAtSimEnd, TransactionReasons.None); KCT_GameStates.FundsToChargeAtSimEnd = 0; } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.FundsGivenForVessel != 0) { KCT_Utilities.SpendFunds(KCT_GameStates.FundsGivenForVessel, TransactionReasons.VesselRollout); KCT_GameStates.FundsGivenForVessel = 0; } if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated) { List <VesselType> invalidTypes = new List <VesselType> { VesselType.Debris, VesselType.SpaceObject, VesselType.Unknown }; if (!invalidTypes.Contains(FlightGlobals.ActiveVessel.vesselType) && !KCT_GameStates.BodiesVisited.Contains(FlightGlobals.ActiveVessel.mainBody.bodyName)) { KCT_GameStates.BodiesVisited.Add(FlightGlobals.ActiveVessel.mainBody.bodyName); var message = new ScreenMessage("[KCT] New simulation body unlocked: " + FlightGlobals.ActiveVessel.mainBody.bodyName, 4.0f, ScreenMessageStyle.UPPER_LEFT); ScreenMessages.PostScreenMessage(message, true); KCTDebug.Log("Unlocked sim body: " + FlightGlobals.ActiveVessel.mainBody.bodyName); } } if (KCT_GUI.PrimarilyDisabled) { return; } //The following should only be executed when fully enabled for the save foreach (KCT_KSC KSC in KCT_GameStates.KSCs) { KSC.RecalculateBuildRates(); KSC.RecalculateUpgradedBuildRates(); } if (!HighLogic.LoadedSceneIsFlight && KCT_GameStates.buildSimulatedVessel) { KCT_GameStates.buildSimulatedVessel = false; KCT_BuildListVessel toBuild = KCT_GameStates.launchedVessel.NewCopy(false); toBuild.buildPoints = KCT_Utilities.GetBuildTime(toBuild.ExtractedPartNodes, true, KCT_GUI.useInventory); KCT_Utilities.AddVesselToBuildList(toBuild, KCT_GUI.useInventory); } if (HighLogic.LoadedSceneIsFlight && !KCT_GameStates.flightSimulated) { KCT_GUI.hideAll(); if (FlightGlobals.ActiveVessel.situation == Vessel.Situations.PRELAUNCH && KCT_GameStates.launchedVessel != null) { bool removed = KCT_GameStates.launchedVessel.RemoveFromBuildList(); if (removed) //Only do these when the vessel is first removed from the list { //Add the cost of the ship to the funds so it can be removed again by KSP //KCT_Utilities.AddFunds(KCT_Utilities.GetTotalVesselCost(FlightGlobals.ActiveVessel.protoVessel), TransactionReasons.VesselRollout); KCT_Utilities.AddFunds(KCT_GameStates.launchedVessel.cost, TransactionReasons.VesselRollout); FlightGlobals.ActiveVessel.vesselName = KCT_GameStates.launchedVessel.shipName; } KCT_Recon_Rollout rollout = KCT_GameStates.ActiveKSC.Recon_Rollout.FirstOrDefault(r => r.associatedID == KCT_GameStates.launchedVessel.id.ToString()); if (rollout != null) { KCT_GameStates.ActiveKSC.Recon_Rollout.Remove(rollout); } } } if (HighLogic.LoadedSceneIsEditor) { if (KCT_GameStates.EditorShipEditingMode) { KCTDebug.Log("Editing " + KCT_GameStates.editedVessel.shipName); EditorLogic.fetch.shipNameField.Text = KCT_GameStates.editedVessel.shipName; } if (!KCT_GUI.PrimarilyDisabled) { if (KCT_GameStates.settings.OverrideLaunchButton) { KCTDebug.Log("Taking control of launch button"); EditorLogic.fetch.launchBtn.methodToInvoke = "ShowLaunchAlert"; EditorLogic.fetch.launchBtn.scriptWithMethodToInvoke = KerbalConstructionTime.instance; } else { InputLockManager.SetControlLock(ControlTypes.EDITOR_LAUNCH, "KCTLaunchLock"); } KCT_Utilities.RecalculateEditorBuildTime(EditorLogic.fetch.ship); } } if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { if (KCT_Utilities.CurrentGameHasScience() && KCT_GameStates.TotalUpgradePoints == 0) { ConfigNode CN = new ConfigNode(); ResearchAndDevelopment.Instance.snapshot.Save(CN); ConfigNode[] techNodes = CN.GetNodes("Tech"); KCTDebug.Log("technodes length: " + techNodes.Length); KCT_GameStates.TotalUpgradePoints = techNodes.Length + 14; } if (!KCT_GUI.PrimarilyDisabled) { KCT_GUI.showBuildList = KCT_GameStates.showWindows[0]; KCT_GUI.ResetBLWindow(); } else { KCT_GUI.showBuildList = false; KCT_GameStates.showWindows[0] = false; } if (KCT_GameStates.firstStart) { KCTDebug.Log("Showing first start."); KCT_GUI.showFirstRun = true; } KCT_GameStates.firstStart = false; if (KCT_GameStates.LaunchFromTS) { KCT_GameStates.launchedVessel.Launch(); } } }