using System; using System.IO; using System.Windows.Forms; using System.Xml; namespace TeslaConsole.BattleTech; /// /// Operator defaults for the two BattleTech game modes, persisted to /// BTDefaults.btd in the common app-data directory (mirrors /// RPDefaults/.rpd). Both modes share one defaults shape — they differ /// only by role, which comes from the mode, not from a default. There is no /// defaults dialog yet (RPDefaultsDialog's counterpart is a later phase); the /// file is import/export round-trippable in the meantime. /// internal static class BTDefaults { public class BattleDefaults { private readonly string mNodeName; private bool mAdvancedDamage = true; private TimeSpan mMissionLength = new TimeSpan(0, 10, 0); private string mMapKey; private string mVehicleKey; private string mTimeOfDayKey; private string mWeatherKey; private string mExperienceKey; private string mCamoKey; private string mPatchKey; private string mEmblemKey; private int mLaunchDelay = 15; public bool AdvancedDamage { get { return mAdvancedDamage; } set { mAdvancedDamage = value; } } public TimeSpan MissionLength { get { return mMissionLength; } set { mMissionLength = value; } } public string MapKey { get { return mMapKey; } set { mMapKey = value; } } public string VehicleKey { get { return mVehicleKey; } set { mVehicleKey = value; } } public string TimeOfDayKey { get { return mTimeOfDayKey; } set { mTimeOfDayKey = value; } } public string WeatherKey { get { return mWeatherKey; } set { mWeatherKey = value; } } public string ExperienceKey { get { return mExperienceKey; } set { mExperienceKey = value; } } public string CamoKey { get { return mCamoKey; } set { mCamoKey = value; } } public string PatchKey { get { return mPatchKey; } set { mPatchKey = value; } } public string EmblemKey { get { return mEmblemKey; } set { mEmblemKey = value; } } public int LaunchDelay { get { return mLaunchDelay; } set { mLaunchDelay = value; } } internal BattleDefaults(string nodeName) { mNodeName = nodeName; } public void Save(XmlNode parrentNode) { XmlNode xmlNode = parrentNode.AppendChild(parrentNode.OwnerDocument.CreateElement(mNodeName)); xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("AdvancedDamage")).InnerText = mAdvancedDamage.ToString(); xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("MissionLength")).InnerText = mMissionLength.ToString(); SaveKey(xmlNode, "MapKey", mMapKey); SaveKey(xmlNode, "VehicleKey", mVehicleKey); SaveKey(xmlNode, "TimeOfDayKey", mTimeOfDayKey); SaveKey(xmlNode, "WeatherKey", mWeatherKey); SaveKey(xmlNode, "ExperienceKey", mExperienceKey); SaveKey(xmlNode, "CamoKey", mCamoKey); SaveKey(xmlNode, "PatchKey", mPatchKey); SaveKey(xmlNode, "EmblemKey", mEmblemKey); xmlNode.AppendChild(xmlNode.OwnerDocument.CreateElement("LaunchDelay")).InnerText = mLaunchDelay.ToString(); } private static void SaveKey(XmlNode parentNode, string elementName, string value) { if (!string.IsNullOrEmpty(value)) { parentNode.AppendChild(parentNode.OwnerDocument.CreateElement(elementName)).InnerText = value; } } public void Parse(XmlNode scenarioNode) { foreach (XmlNode childNode in scenarioNode.ChildNodes) { switch (childNode.Name) { case "AdvancedDamage": { if (bool.TryParse(childNode.InnerText, out var result2)) { mAdvancedDamage = result2; } break; } case "MissionLength": { if (TimeSpan.TryParse(childNode.InnerText, out var result3)) { mMissionLength = result3; } break; } case "MapKey": ParseKey(childNode, ref mMapKey); break; case "VehicleKey": ParseKey(childNode, ref mVehicleKey); break; case "TimeOfDayKey": ParseKey(childNode, ref mTimeOfDayKey); break; case "WeatherKey": ParseKey(childNode, ref mWeatherKey); break; case "ExperienceKey": ParseKey(childNode, ref mExperienceKey); break; case "CamoKey": ParseKey(childNode, ref mCamoKey); break; case "PatchKey": ParseKey(childNode, ref mPatchKey); break; case "EmblemKey": ParseKey(childNode, ref mEmblemKey); break; case "LaunchDelay": { if (int.TryParse(childNode.InnerText, out var result)) { mLaunchDelay = result; } break; } } } } private static void ParseKey(XmlNode node, ref string field) { if (!string.IsNullOrEmpty(node.InnerText)) { field = node.InnerText; } } } public const string FreeForAllNode = "FreeForAllDefaults"; public const string NoReturnNode = "NoReturnDefaults"; private static readonly string sDefaultsFilePath; private static readonly BattleDefaults sFreeForAll; private static readonly BattleDefaults sNoReturn; public static BattleDefaults FreeForAll => sFreeForAll; public static BattleDefaults NoReturn => sNoReturn; static BTDefaults() { sDefaultsFilePath = Path.Combine(Program.GetCommonAppDataDirectory(), "BTDefaults.btd"); sFreeForAll = new BattleDefaults("FreeForAllDefaults"); sNoReturn = new BattleDefaults("NoReturnDefaults"); if (File.Exists(sDefaultsFilePath)) { try { Import(sDefaultsFilePath); } catch (Exception) { MessageBox.Show("The BattleTech defaults file appears to be corrupt. Please delete it or export a new one to replace it.", "Error Loading BattleTech Defaults!", MessageBoxButtons.OK); } } } public static void Import(string fileName) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.Load(fileName); foreach (XmlNode childNode in xmlDocument.DocumentElement.ChildNodes) { switch (childNode.Name) { case "FreeForAllDefaults": sFreeForAll.Parse(childNode); break; case "NoReturnDefaults": sNoReturn.Parse(childNode); break; } } } public static void Save() { try { Export(sDefaultsFilePath); } catch (Exception) { MessageBox.Show("The BattleTech defaults file could not be saved. These defaults will only be remembered until the application is closed.", "Error Saving BattleTech Defaults!", MessageBoxButtons.OK); } } public static void Export(string filePath) { XmlDocument xmlDocument = new XmlDocument(); xmlDocument.AppendChild(xmlDocument.CreateElement("BTDefaults")); sFreeForAll.Save(xmlDocument.DocumentElement); sNoReturn.Save(xmlDocument.DocumentElement); string directoryName = Path.GetDirectoryName(filePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } xmlDocument.Save(filePath); } }