/// <summary> /// Called when a draft fails. /// </summary> /// <param name="reason">The reason for the failure.</param> void DraftFailure(string reason) { // If the reason is because a channel isn't specified, if (reason == "Please specify a channel!") { // Simply clear the contract queue and then indicate a stop in waiting status. contractsToModify.Clear(); working = false; // Notify the player that the contract draft failed because of a lack of channel. ScreenMessages.PostScreenMessage("<color=" + XKCDColors.HexFormat.KSPNotSoGoodOrange + ">Contract draft FAILED. (Please input a channel to draft from.)</color>", 5f, ScreenMessageStyle.UPPER_CENTER); } // Else, follow normal failure procedure. else { // Increment failures. failures++; // Log a warning with the reason. Logger.DebugWarning("Contract Draft failed (" + failures.ToString() + " failures): " + reason); // If the queue is not empty, and the failure count isn't 5, if (contractsToModify.Count > 0 && failures < 5) { // Retry the draft. StartCoroutine(ScenarioDraftManager.DraftKerbal(DraftSuccess, DraftFailure, false, false, "Any")); } // Else, the queue is empty, or 5 failures have occurred. else { // Indicate a stop in waiting status. working = false; } // If 5 failures have occurred, if (failures == 5) { // Notify the player that the contract draft failed consecutively. ScreenMessages.PostScreenMessage("<color=" + XKCDColors.HexFormat.KSPNotSoGoodOrange + ">Contract draft FAILED. (5 failed attempts. Deactivating.)</color>", 5f, ScreenMessageStyle.UPPER_CENTER); // Log an error and destroy the addon. Logger.DebugError("5 failed Contract Drafts. Disabling."); Destroy(gameObject); } } }
/// <summary> /// Enqueues any rescue contracts offered. /// </summary> /// <param name="toEnqueue">The contract to test and enqueue.</param> void EnqueueContract(Contract toEnqueue) { // Create a ConfigNode to save the contract into. ConfigNode test = new ConfigNode(); toEnqueue.Save(test); // If the contract is of the RecoverAsset type, if (test.GetValue("type") == "RecoverAsset") { // If the saved ConfigNode contains a kerbalName value, if (test.HasValue("kerbalName")) { // If the value contained isn't null or empty, if (!string.IsNullOrEmpty(test.GetValue("kerbalName"))) { // If the contract wasn't already modified, if (test.GetNodes("PARAM")[0].GetValue("name") != "ModifiedByDTV") { // The contract is a proper rescue contract. Logger.DebugLog("Rescue contract found: " + test.GetValue("kerbalName")); // Enqueue it. contractsToModify.Enqueue(toEnqueue); // If a draft is not currently underway, if (!working) { // Begin a draft and indicate waiting status. StartCoroutine(ScenarioDraftManager.DraftKerbal(DraftSuccess, DraftFailure, false, false, "Any")); working = true; } } } } } }
/// <summary> /// Called when a draft succeeds. /// </summary> /// <param name="kerbalName">The name of the drafted viewer.</param> void DraftSuccess(Dictionary <string, string> info) { // Resets failures. The addon should only destroy after 5 consecutive failures. failures = 0; // Get the next contract in the queue. Contract toMod = contractsToModify.Dequeue(); // Create a ConfigNode to save the contract into. ConfigNode replacement = new ConfigNode("CONTRACT"); toMod.Save(replacement); // Get the old Kerbal name for later use. string oldName = replacement.GetValue("kerbalName"); // Replace the old name with the new. replacement.SetValue("kerbalName", info["name"]); // For each PARAM node in the CONTRACT node, foreach (ConfigNode node in replacement.nodes) { // Get the name of the contract parameter. string paramName = node.GetValue("name"); // Perform certain replacement functions for each parameter. switch (paramName) { case "AcquireCrew": { node.SetValue("title", "Save " + info["name"]); break; } case "AcquirePart": { string firstName = info["name"].Substring(0, info["name"].IndexOf(' ')); node.SetValue("title", "Obtain " + firstName + "'s Scrap"); break; } case "RecoverKerbal": { node.SetValue("title", "Recover " + info["name"] + " on Kerbin"); break; } case "RecoverPart": { string firstName = info["name"].Substring(0, info["name"].IndexOf(' ')); node.SetValue("title", "Recover " + firstName + "'s Scrap on Kerbin"); break; } } } // Get a count of parameters currently held by the contract. int parameters = toMod.ParameterCount; // Iterate using this count, removing the one parameter each time, effectively clearing the list. for (int i = 0; i < parameters; i++) { // Remove the first parameter. toMod.RemoveParameter(0); } // Add the custom parameter indicating DTV has modified this contract. toMod.AddParameter(new ModifiedByDTV()); // Reload the contract. Contract.Load(toMod, replacement); // Get the old Kerbal and rename it. ProtoCrewMember toRename = HighLogic.CurrentGame.CrewRoster[oldName]; toRename.ChangeName(info["name"]); // Logging. Logger.DebugLog("Draft Success (" + contractsToModify.Count.ToString() + " contracts waiting): " + info["name"]); // Refresh the contract list by firing the onContractListChanged event. GameEvents.Contract.onContractsListChanged.Fire(); // If the queue is not empty, if (contractsToModify.Count > 0) { // Begin another draft. StartCoroutine(ScenarioDraftManager.DraftKerbal(DraftSuccess, DraftFailure, false, false, "Any")); } // Else, the queue is empty. else { // Indicate a stop in waiting status. working = false; } }
/// <summary> /// Called when a draft succeeds. /// </summary> /// <param name="kerbalName">The name of the drafted viewer.</param> void DraftSuccess(Dictionary <string, string> info) { // Enqueue the name first thing, since it needs to be in the queue whether it has enough with it or not. draftNames.Enqueue(info["name"]); // Resets failures. The addon should only destroy after 5 consecutive failures. failures = 0; // Peek at the next contract in the queue instead of dequeueing because there might not yet be enough names to cover the contract. Contract toMod = contractsToModify.Peek(); // Create a ConfigNode to save the contract into. ConfigNode replacement = new ConfigNode("CONTRACT"); toMod.Save(replacement); // Obtain a list of the old tourists in the contract. string[] oldTourists = replacement.GetValue("tourists").Split('|'); // If the count of names in the queue plus this name equals the number of tourists, if (draftNames.Count == oldTourists.Length) { // Dequeue the contract we peeked because there are enough names for it. contractsToModify.Dequeue(); // Create an array from the queue and clear it. string[] newTourists = draftNames.ToArray(); draftNames.Clear(); // Replace the contract "tourists" string. replacement.SetValue("tourists", string.Join("|", newTourists)); // Get a list of PARAM nodes in the contract. ConfigNode[] paramNodes = replacement.GetNodes("PARAM"); // Iterate through them, for (int i = 0; i < paramNodes.Length; i++) { // And replace their kerbalName values. paramNodes[i].SetValue("kerbalName", newTourists[i]); // Iterate through any sub-PARAMS, foreach (ConfigNode subParam in paramNodes[i].GetNodes("PARAM")) { // And replace their kerbalName values as well. subParam.SetValue("kerbalName", newTourists[i]); } // Remove the parameter from the actual contract to prevent duplicates. toMod.RemoveParameter(0); // Get an old Kerbal and rename it. ProtoCrewMember toRename = HighLogic.CurrentGame.CrewRoster[oldTourists[i]]; toRename.ChangeName(newTourists[i]); } // Add the custom parameter indicating DTV has modified this contract. toMod.AddParameter((ContractParameter) new ModifiedByDTV()); // Reload the contract. Contract.Load(toMod, replacement); // Logging. Logger.DebugLog("Draft Success (" + contractsToModify.Count.ToString() + " contracts waiting): " + string.Join("|", newTourists)); // Refresh the contract list by firing the onContractListChanged event. GameEvents.Contract.onContractsListChanged.Fire(); // If the queue is not empty, if (contractsToModify.Count > 0) { // Begin another draft. StartCoroutine(ScenarioDraftManager.DraftKerbal(DraftSuccess, DraftFailure, false, false, "Any")); } // Else, the queue is empty. else { // Indicate a stop in waiting status. working = false; } } // Else, run another draft. else { StartCoroutine(ScenarioDraftManager.DraftKerbal(DraftSuccess, DraftFailure, false, false, "Any")); } }