PageRenderTime 42ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/JTacticalSim.DataContext/XMLDataContext.cs

https://github.com/Queztionmark/JTacticalSim
C# | 1123 lines | 818 code | 220 blank | 85 comment | 25 complexity | 20f8603e956df84e27f96143444bbd41 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Xml.Linq;
  5. using System.Dynamic;
  6. using System.IO;
  7. using System.Transactions;
  8. using JTacticalSim.API;
  9. using JTacticalSim.API.DTO;
  10. using JTacticalSim.Data.DTO;
  11. using JTacticalSim.API.Data;
  12. using JTacticalSim.API.Component;
  13. using JTacticalSim.Utility;
  14. namespace JTacticalSim.DataContext
  15. {
  16. /// <summary>
  17. /// File based data context
  18. /// </summary>
  19. public sealed class XMLDataContext : BaseDataContext
  20. {
  21. private DataFileFactory _dataFileFactory = DataFileFactory.Instance;
  22. private static volatile IDataContext _instance = null;
  23. static readonly object padlock = new object();
  24. public static IDataContext Instance
  25. {
  26. get
  27. {
  28. if (_instance == null)
  29. {
  30. lock (padlock)
  31. if (_instance == null) _instance = new XMLDataContext();
  32. }
  33. return _instance;
  34. }
  35. }
  36. // Initialize Context
  37. private XMLDataContext()
  38. {}
  39. #region Save
  40. public override IResult<IGameFileCopyable> SaveData(IGameFileCopyable currentData)
  41. {
  42. var r = new DataResult<IGameFileCopyable>{Status = ResultStatus.SUCCESS, Result = currentData};
  43. using (var txn = new TransactionScope())
  44. {
  45. // 1. Create a new file handler for the current game file directory
  46. IDataFileHandler<XDocument> dataFileHandler = null;
  47. try
  48. {
  49. dataFileHandler = new DataFileHandler<XDocument>(_dataFileFactory.GetDataFiles<XDocument>(currentData.GameFileDirectory, currentData.IsScenario));
  50. }
  51. catch (Exception ex)
  52. {
  53. r.Status = ResultStatus.EXCEPTION;
  54. r.ex = ex;
  55. r.Messages.Add("Game data not saved. DataFileHandler could not be created.");
  56. return r;
  57. }
  58. // 2. Backup Current Files
  59. if (dataFileHandler.GameDirectoryHasFiles())
  60. {
  61. try
  62. {
  63. BackupCurrentGameFiles(dataFileHandler);
  64. }
  65. catch (Exception ex)
  66. {
  67. r.Status = ResultStatus.EXCEPTION;
  68. r.ex = ex;
  69. r.Messages.Add("Game data not saved. Could not backup current game files.");
  70. return r;
  71. }
  72. }
  73. // 3. Save data
  74. try
  75. {
  76. SaveGameData(dataFileHandler);
  77. }
  78. catch (Exception ex)
  79. {
  80. r.Status = ResultStatus.EXCEPTION;
  81. r.ex = ex;
  82. r.Messages.Add("Game data not saved.");
  83. return r;
  84. }
  85. txn.Complete();
  86. }
  87. r.Messages.Add("Game data saved.");
  88. return r;
  89. }
  90. public override IResult<IGameFileCopyable> SaveDataAs(IGameFileCopyable currentData, IGameFileCopyable newData)
  91. {
  92. var r = new DataResult<IGameFileCopyable>{Status = ResultStatus.SUCCESS, Result = newData};
  93. using (var txn = new TransactionScope())
  94. {
  95. // 1. Create a new file handler for the current and new game file directories
  96. IDataFileHandler<XDocument> currentDataFileHandler = null;
  97. IDataFileHandler<XDocument> newDataFileHandler = null;
  98. try
  99. {
  100. currentDataFileHandler = new DataFileHandler<XDocument>(_dataFileFactory.GetDataFiles<XDocument>(currentData.GameFileDirectory, currentData.IsScenario));
  101. newDataFileHandler = new DataFileHandler<XDocument>(_dataFileFactory.GetDataFiles<XDocument>(newData.GameFileDirectory, newData.IsScenario));
  102. }
  103. catch (Exception ex)
  104. {
  105. r.Status = ResultStatus.EXCEPTION;
  106. r.ex = ex;
  107. r.Messages.Add("Game data not saved. DataFileHandlers could not be created.");
  108. return r;
  109. }
  110. // 2. Verify game directory. Create if it does not exists.
  111. if (!newDataFileHandler.GameDirectoryExists())
  112. {
  113. try
  114. {
  115. newDataFileHandler.CreateNewGameDirectory();
  116. }
  117. catch (Exception ex)
  118. {
  119. r.Status = ResultStatus.EXCEPTION;
  120. r.ex = ex;
  121. r.Messages.Add("Game data not saved. Could not create new game directory.");
  122. return r;
  123. }
  124. }
  125. // 3. Copy current files to new directory
  126. var result = (currentData.IsScenario)
  127. ? currentDataFileHandler.CopyScenarioFiles(newDataFileHandler.DataFiles.GameSaveDirectory)
  128. : currentDataFileHandler.CopyGameFiles(newDataFileHandler.DataFiles.GameSaveDirectory);
  129. if (result.Status == ResultStatus.EXCEPTION)
  130. {
  131. r.Status = ResultStatus.EXCEPTION;
  132. r.ex = result.ex;
  133. r.Messages.Add("Game data not saved. {0}.".F(result.Message));
  134. return r;
  135. }
  136. txn.Complete();
  137. }
  138. r.Messages.Add("Game data saved.");
  139. return r;
  140. }
  141. public override IResult<IGameFileCopyable> RemoveSavedGameData(IGameFileCopyable delData)
  142. {
  143. var r = new DataResult<IGameFileCopyable>{Status = ResultStatus.SUCCESS, Result = delData};
  144. using (var txn = new TransactionScope())
  145. {
  146. // 1. Create a new file handler for the game to be deleted.
  147. IDataFileHandler<XDocument> delDataFileHandler = null;
  148. try
  149. {
  150. delDataFileHandler = new DataFileHandler<XDocument>(_dataFileFactory.GetDataFiles<XDocument>(delData.GameFileDirectory, delData.IsScenario));
  151. }
  152. catch (Exception ex)
  153. {
  154. r.Status = ResultStatus.EXCEPTION;
  155. r.ex = ex;
  156. r.Messages.Add("Game data not saved. DataFileHandlers could not be created.");
  157. return r;
  158. }
  159. // 2. Verify game directory. Create if it does not exists.
  160. if (delDataFileHandler.GameRootDirectoryExists())
  161. {
  162. try
  163. {
  164. delDataFileHandler.DeleteGameDirectory();
  165. }
  166. catch (Exception ex)
  167. {
  168. r.Status = ResultStatus.EXCEPTION;
  169. r.ex = ex;
  170. r.Messages.Add("Game data not deleted. Could not delete game directory.");
  171. return r;
  172. }
  173. }
  174. // 3. Save data
  175. try
  176. {
  177. SaveSavedGameFile(delDataFileHandler);
  178. }
  179. catch (Exception ex)
  180. {
  181. r.Status = ResultStatus.EXCEPTION;
  182. r.ex = ex;
  183. r.Messages.Add("Game data file not saved.");
  184. return r;
  185. }
  186. txn.Complete();
  187. }
  188. r.Messages.Add("Game data removed.");
  189. return r;
  190. }
  191. private void BackupCurrentGameFiles(IDataFileHandler<XDocument> dataFileHandler)
  192. {
  193. dataFileHandler.DataFiles.ScenarioFilePaths.ForEach(path =>
  194. {
  195. File.Delete("{0}.BAK".F(path));
  196. File.Copy(path, "{0}.BAK".F(path));
  197. });
  198. // Back up the Saved Games file
  199. File.Delete("{0}.BAK".F(dataFileHandler.DataFiles.SavedGameDataFilePath));
  200. File.Copy(dataFileHandler.DataFiles.SavedGameDataFilePath, "{0}.BAK".F(dataFileHandler.DataFiles.SavedGameDataFilePath));
  201. }
  202. private void SaveGameData(IDataFileHandler<XDocument> dataFileHandler)
  203. {
  204. SaveBoardDataFile(dataFileHandler);
  205. SaveUnitDataFile(dataFileHandler);
  206. SaveGameDataFile(dataFileHandler);
  207. SaveSavedGameFile(dataFileHandler);
  208. }
  209. private void SaveBoardDataFile(IDataFileHandler<XDocument> dataFileHandler)
  210. {
  211. // Clear all nodes
  212. var nodes = dataFileHandler.DataFiles.BoardDataFile.Descendants("Nodes").Single();
  213. nodes.RemoveAll();
  214. var attributes = dataFileHandler.DataFiles.BoardDataFile.Descendants("Attributes").Single();
  215. // Clear the board
  216. var board = dataFileHandler.DataFiles.BoardDataFile.Descendants("GameBoard").Single();
  217. board.RemoveAll();
  218. // Update attributes
  219. attributes.Attribute("Title").SetValue(Board.Title);
  220. attributes.Attribute("Width").SetValue(Board.Width);
  221. attributes.Attribute("Height").SetValue(Board.Height);
  222. attributes.Attribute("CellSize").SetValue(Board.CellSize);
  223. attributes.Attribute("CellMaxUnits").SetValue(Board.CellMaxUnits);
  224. // Create Nodes for save
  225. foreach (var n in NodesTable.Records)
  226. {
  227. nodes.Add(n.ToXML());
  228. }
  229. board.Add(attributes);
  230. board.Add(nodes);
  231. // Save back file
  232. board.Document.Save(dataFileHandler.DataFiles.BoardDataFilePath);
  233. }
  234. private void SaveUnitDataFile(IDataFileHandler<XDocument> dataFileHandler)
  235. {
  236. // Remove all existing units
  237. var units = dataFileHandler.DataFiles.UnitDataFile.Descendants("Units").Single();
  238. units.RemoveAll();
  239. // Create units for save
  240. foreach (var u in UnitsTable.Records)
  241. {
  242. units.Add(u.ToXML());
  243. }
  244. units.Document.Save(dataFileHandler.DataFiles.UnitDataFilePath);
  245. }
  246. private void SaveGameDataFile(IDataFileHandler<XDocument> dataFileHandler)
  247. {
  248. // Remove all existing GameData
  249. var gameData = dataFileHandler.DataFiles.GameDataFile.Descendants("GameData").Single();
  250. gameData.RemoveAll();
  251. // Create Factions for save
  252. XElement fs = new XElement("Factions");
  253. foreach (var f in FactionsTable.Records)
  254. {
  255. fs.Add(f.ToXML());
  256. }
  257. gameData.Add(fs);
  258. // Create Countries for save
  259. XElement cs = new XElement("Countries");
  260. foreach (var c in CountriesTable.Records)
  261. {
  262. cs.Add(c.ToXML());
  263. }
  264. gameData.Add(cs);
  265. // Create Players for save
  266. XElement ps = new XElement("Players");
  267. foreach (var p in PlayersTable.Records)
  268. {
  269. ps.Add(p.ToXML());
  270. }
  271. gameData.Add(ps);
  272. gameData.Add(new XComment("Conditions for winning the game for a faction. Winning is an OR proposition"));
  273. XElement fvcs = new XElement("FactionVictoryConditions");
  274. foreach (var fvc in FactionVictoryConditions)
  275. {
  276. XElement vc = new XElement("VictoryCondition");
  277. vc.Add(new XAttribute("Faction", fvc.Faction));
  278. vc.Add(new XAttribute("Condition", fvc.Condition));
  279. vc.Add(new XAttribute("Value", fvc.Value));
  280. fvcs.Add(vc);
  281. }
  282. gameData.Add(fvcs);
  283. gameData.Add(new XComment("Unit Assignments"));
  284. XElement uas = new XElement("UnitAssignments");
  285. foreach (var a in UnitAssignments)
  286. {
  287. XElement ua = new XElement("UnitAssignment");
  288. ua.Add(new XAttribute("Unit", a.Unit));
  289. ua.Add(new XAttribute("AssignedToUnit", a.AssignedToUnit));
  290. uas.Add(ua);
  291. }
  292. gameData.Add(uas);
  293. gameData.Add(new XComment("Unit Transports"));
  294. XElement uts = new XElement("UnitTransports");
  295. foreach (var a in UnitTransports)
  296. {
  297. XElement ua = new XElement("UnitTransport");
  298. ua.Add(new XAttribute("Unit", a.Unit));
  299. ua.Add(new XAttribute("TransportUnit", a.TransportUnit));
  300. uts.Add(ua);
  301. }
  302. gameData.Add(uts);
  303. gameData.Document.Save(dataFileHandler.DataFiles.GameDataFilePath);
  304. }
  305. private void SaveSavedGameFile(IDataFileHandler<XDocument> dataFileHandler)
  306. {
  307. // Remove all existing GameData
  308. var gameData = dataFileHandler.DataFiles.SavedGameDataFile.Descendants("SavedGames").Single();
  309. gameData.RemoveAll();
  310. foreach(var game in SavedGames.Records)
  311. {
  312. gameData.Add(game.ToXML());
  313. }
  314. gameData.Document.Save(dataFileHandler.DataFiles.SavedGameDataFilePath);
  315. }
  316. #endregion
  317. #region Load
  318. public override IResult<string> LoadData(string gameFileDirectory, bool IsScenario)
  319. {
  320. var r = new DataResult<string>{Status = ResultStatus.SUCCESS, Result = gameFileDirectory};
  321. try
  322. {
  323. IDataFileHandler<XDocument> dataFileHandler = new DataFileHandler<XDocument>(_dataFileFactory.GetDataFiles<XDocument>(gameFileDirectory, IsScenario));
  324. // ~~~~~~~~~~~~~~~~~~~~ Load up context
  325. // (Order is important for dependant objects)
  326. LoadComponentData(dataFileHandler.DataFiles.ComponentDataFile);
  327. LoadLookupData(dataFileHandler.DataFiles.LookupDataFile);
  328. LoadGamedata(dataFileHandler.DataFiles.GameDataFile,
  329. dataFileHandler.DataFiles.BoardDataFile,
  330. dataFileHandler.DataFiles.UnitDataFile,
  331. dataFileHandler.DataFiles.ComponentDataFile);
  332. // We need to make sure we have the last played game set correctly in the data file for saved games
  333. SaveSavedGameFile(dataFileHandler);
  334. }
  335. catch (Exception ex)
  336. {
  337. r.Status = ResultStatus.EXCEPTION;
  338. r.ex = ex;
  339. r.Messages.Add("Game data not loaded.");
  340. }
  341. r.Messages.Add("Game data loaded.");
  342. return r;
  343. }
  344. /// <summary>
  345. /// Load all static code data tables into context
  346. /// </summary>
  347. /// <param name="componentDataFile"></param>
  348. private void LoadComponentData(XDocument componentDataFile)
  349. {
  350. LoadBasePointValues(componentDataFile);
  351. LoadUnitBaseTypes(componentDataFile);
  352. LoadUnitGroupTypes(componentDataFile);
  353. LoadUnitTypes(componentDataFile);
  354. LoadUnitClasses(componentDataFile);
  355. LoadDemographicClasses(componentDataFile);
  356. LoadDemographicTypes(componentDataFile);
  357. LoadVictoryConditions(componentDataFile);
  358. LoadMissionData(componentDataFile);
  359. }
  360. /// <summary>
  361. /// Load all the lookup tables for code game code data into context
  362. /// </summary>
  363. /// <param name="lookupDataFile"></param>
  364. private void LoadLookupData(XDocument lookupDataFile)
  365. {
  366. LoadUnitBaseTypeUnitClasses(lookupDataFile);
  367. LoadUnitBaseTypeUnitGeogTypes(lookupDataFile);
  368. LoadUnitGeogTypeDemographicClasses(lookupDataFile);
  369. LoadUnitGroupTypeUnitTasks(lookupDataFile);
  370. LoadMissionObjectiveUnitTasks(lookupDataFile);
  371. LoadUnitTaskUnitClasses(lookupDataFile);
  372. LoadUnitGeogTypeMovementOverrides(lookupDataFile);
  373. LoadUnitTypeUnitGeogTypeBattleEffectives(lookupDataFile);
  374. LoadUnitTransportUnitTypeUnitClasses(lookupDataFile);
  375. LoadHybridDemographicClasses(lookupDataFile);
  376. LoadMovementHinderancesInDirection(lookupDataFile);
  377. }
  378. private void LoadGamedata( XDocument gameDataFile,
  379. XDocument boardDataFile,
  380. XDocument unitDataFile,
  381. XDocument componentDataFile)
  382. {
  383. LoadBoard(boardDataFile);
  384. LoadUnits(unitDataFile);
  385. LoadFactions(gameDataFile);
  386. LoadCountries(gameDataFile);
  387. LoadPlayers(gameDataFile);
  388. LoadDemographics(gameDataFile, componentDataFile);
  389. LoadUnitAssignments(gameDataFile);
  390. LoadUnitTransports(gameDataFile);
  391. LoadFactionVictoryConditions(gameDataFile);
  392. }
  393. private void LoadBasePointValues(XDocument staticDataFile)
  394. {
  395. var data = staticDataFile.Descendants("BasePointValues").Single();
  396. var basePointValues = new BasePointValuesDTO
  397. (
  398. Convert.ToInt32(data.Attribute("Movement").Value),
  399. Convert.ToInt32(data.Attribute("CombatRoll").Value),
  400. Convert.ToInt32(data.Attribute("CombatBase").Value),
  401. Convert.ToInt32(data.Attribute("StealthRoll").Value),
  402. Convert.ToInt32(data.Attribute("StealthBase").Value),
  403. Convert.ToInt32(data.Attribute("MedicalSupportBase").Value),
  404. Convert.ToInt32(data.Attribute("WeightBase").Value),
  405. Convert.ToInt32(data.Attribute("CostBase").Value),
  406. Convert.ToInt32(data.Attribute("AIBaseRoll").Value),
  407. Convert.ToInt32(data.Attribute("AIAggressiveness").Value),
  408. Convert.ToInt32(data.Attribute("AIDefensiveness").Value),
  409. Convert.ToInt32(data.Attribute("AIIntelligence").Value),
  410. Convert.ToInt32(data.Attribute("ReinforcementCalcBaseCountry").Value),
  411. Convert.ToInt32(data.Attribute("ReinforcementCalcBaseFaction").Value),
  412. Convert.ToDouble(data.Attribute("ReinforcementCalcBaseVP").Value),
  413. Convert.ToDouble(data.Attribute("HQBonus").Value),
  414. Convert.ToDouble(data.Attribute("SuppliedBonus").Value),
  415. Convert.ToInt32(data.Attribute("MaxSupplyDistance").Value),
  416. Convert.ToDouble(data.Attribute("TargetAttachedUnitBonus").Value),
  417. Convert.ToDouble(data.Attribute("TargetMedicalUnitBonus").Value),
  418. Convert.ToDouble(data.Attribute("TargetSupplyUnitBonus").Value)
  419. ) as IBasePointValues;
  420. this._basePointValues = basePointValues;
  421. }
  422. private void LoadUnitBaseTypes(XDocument staticDataFile)
  423. {
  424. //Get base type with properties
  425. var unitBaseTypes = GetBaseComponentDTOs<UnitBaseTypeDTO>(staticDataFile.Descendants("UnitBaseType")).ToList();
  426. unitBaseTypes.ForEach(o =>
  427. {
  428. o.Item1.CanReceiveMedicalSupport = Convert.ToBoolean(o.Item2.Attribute("CanReceiveMedicalSupport").Value);
  429. });
  430. // Add to context
  431. this._unitBaseTypesTable.Records = unitBaseTypes.Select(p => p.Item1 as IUnitBaseTypeDTO).ToList();
  432. }
  433. private void LoadVictoryConditions(XDocument staticDataFile)
  434. {
  435. var victoryConditions = GetBaseComponentDTOs<VictoryConditionDTO>(staticDataFile.Descendants("Condition"));
  436. this._victoryConditionsTable.Records = victoryConditions.Select(vc => vc.Item1 as IVictoryConditionDTO).ToList();
  437. }
  438. private void LoadUnitGroupTypes(XDocument staticDataFile)
  439. {
  440. var unitGroupTypes = GetBaseComponentDTOs<UnitGroupTypeDTO>(staticDataFile.Descendants("UnitGroupType")).ToList();
  441. // Set type specific properties
  442. unitGroupTypes.ForEach(o =>
  443. {
  444. o.Item1.TextDisplay = o.Item2.Attribute("TextDisplay").Value;
  445. o.Item1.Level = Convert.ToInt32(o.Item2.Attribute("Level").Value);
  446. });
  447. // Add to context
  448. this._unitGroupTypesTable.Records = unitGroupTypes.Select(p => p.Item1 as IUnitGroupTypeDTO).ToList();
  449. }
  450. private void LoadUnitGeogTypes(XDocument staticDataFile)
  451. {
  452. var unitGeogTypes = GetBaseComponentDTOs<UnitGeogTypeDTO>(staticDataFile.Descendants("UnitGeogType")).ToList();
  453. // Add to context
  454. this._unitGeogTypesTable.Records = unitGeogTypes.Select(p => p.Item1 as IUnitGeogTypeDTO).ToList();
  455. }
  456. private void LoadUnitTypes(XDocument staticDataFile)
  457. {
  458. // Get base type with properties
  459. var unitTypes = GetBaseComponentDTOs<UnitTypeDTO>(staticDataFile.Descendants("UnitType")).ToList();
  460. // Set type specific properties
  461. unitTypes.ForEach(o =>
  462. {
  463. o.Item1.TextDisplay = o.Item2.Attribute("TextDisplay").Value;
  464. o.Item1.UnitBaseTypeID = Convert.ToInt32(o.Item2.Attribute("UnitBaseType").Value);
  465. });
  466. // Load stat modifier data
  467. unitTypes.ForEach(o => LoadStatModifierData(o.Item2, o.Item1));
  468. // Add to context
  469. this._unitTypesTable.Records = unitTypes.Select(p => p.Item1 as IUnitTypeDTO).ToList();
  470. }
  471. private void LoadUnitClasses(XDocument staticDataFile)
  472. {
  473. // Get base type with properties
  474. var unitClasses = GetBaseComponentDTOs<UnitClassDTO>(staticDataFile.Descendants("UnitClass")).ToList();
  475. // Set type specific properties
  476. unitClasses.ForEach(o =>
  477. {
  478. o.Item1.TextDisplay = o.Item2.Attribute("TextDisplay").Value;
  479. });
  480. // Load stat modifier data
  481. unitClasses.ForEach(o => LoadStatModifierData(o.Item2, o.Item1));
  482. // Add to context
  483. this._unitClassesTable.Records = unitClasses.Select(p => p.Item1 as IUnitClassDTO).ToList();
  484. }
  485. private void LoadMissionData(XDocument staticDataFile)
  486. {
  487. // UnitTasks
  488. var unitTasks = GetBaseComponentDTOs<UnitTaskDTO>(staticDataFile.Descendants("UnitTask")).ToList();
  489. this._unitTasksTable.Records = unitTasks.Select(p => p.Item1 as IUnitTaskDTO).ToList();
  490. //MissionObjectives
  491. var missionObjectives = GetBaseComponentDTOs<MissionObjectiveDTO>(staticDataFile.Descendants("MissionObjective")).ToList();
  492. missionObjectives.ForEach(o =>
  493. {
  494. o.Item1.Priority = Convert.ToInt32(o.Item2.Attribute("Priority").Value);
  495. o.Item1.TurnOrder = Convert.ToInt32(o.Item2.Attribute("TurnOrder").Value);
  496. });
  497. this._missionObjectivesTable.Records = missionObjectives.Select(mo => mo.Item1 as IMissionObjectiveDTO).ToList();
  498. }
  499. private void LoadDemographicClasses(XDocument staticDataFile)
  500. {
  501. // Get base type with properties
  502. var demographicClasses = GetBaseComponentDTOs<DemographicClassDTO>(staticDataFile.Descendants("DemographicClass")).ToList();
  503. // Set type specific properties
  504. demographicClasses.ForEach(o =>
  505. {
  506. o.Item1.TextDisplay = o.Item2.Attribute("TextDisplay").Value;
  507. o.Item1.DemographicType = Convert.ToInt32(o.Item2.Attribute("DemographicType").Value);
  508. });
  509. // Load stat modifier data
  510. demographicClasses.ForEach(o => LoadStatModifierData(o.Item2, o.Item1));
  511. // Add to context
  512. this._demographicClassesTable.Records = demographicClasses.Select(p => p.Item1 as IDemographicClassDTO).ToList();
  513. }
  514. private void LoadDemographicTypes(XDocument staticDataFile)
  515. {
  516. // Get base type with properties
  517. var demographicTypes = GetBaseComponentDTOs<DemographicTypeDTO>(staticDataFile.Descendants("DemographicType")).ToList();
  518. demographicTypes.ForEach(dt =>
  519. {
  520. dt.Item1.DisplayOrder = Convert.ToInt32(dt.Item2.Attribute("DisplayOrder").Value);
  521. });
  522. // Add to context
  523. this._demographicTypesTable.Records = demographicTypes.Select(p => p.Item1 as IDemographicTypeDTO).ToList();
  524. }
  525. private void LoadDemographics(XDocument gameDataFile, XDocument componentDataFile)
  526. {
  527. var defaultDemographicsList = GetBaseComponentDTOs<DemographicDTO>(componentDataFile.Descendants("Demographic")).ToList();
  528. var gameDemographicsList = GetBaseComponentDTOs<DemographicDTO>(gameDataFile.Descendants("Demographic")).ToList();
  529. var demographicsList = defaultDemographicsList.Concat(gameDemographicsList).ToList();
  530. // Set type specific properties
  531. demographicsList.ForEach(o =>
  532. {
  533. o.Item1.DemographicClass = Convert.ToInt32(o.Item2.Attribute("DemographicClass").Value);
  534. o.Item1.Value = o.Item2.Attribute("Value").Value;
  535. });
  536. // Add to context
  537. this._demographicsTable.Records = demographicsList.Select(p => p.Item1 as IDemographicDTO).ToList();
  538. }
  539. private void LoadFactions(XDocument gameDataFile)
  540. {
  541. // Get base type with properties
  542. var factionList = GetBaseComponentDTOs<FactionDTO>(gameDataFile.Descendants("Faction")).ToList();
  543. // Add to context
  544. this._factionsTable.Records = factionList.Select(p => p.Item1 as IFactionDTO).ToList();
  545. }
  546. private void LoadCountries(XDocument gameDataFile)
  547. {
  548. // Get base type with properties
  549. var countryList = GetBaseComponentDTOs<CountryDTO>(gameDataFile.Descendants("Country")).ToList();
  550. // Set type specific properties
  551. countryList.ForEach(o =>
  552. {
  553. o.Item1.Faction = Convert.ToInt32(o.Item2.Attribute("Faction").Value);
  554. });
  555. // Add to context
  556. this._countriesTable.Records = countryList.Select(p => p.Item1 as ICountryDTO).ToList();
  557. }
  558. private void LoadPlayers(XDocument gameDataFile)
  559. {
  560. // Get base type with properties
  561. var playerList = GetBaseComponentDTOs<PlayerDTO>(gameDataFile.Descendants("Player")).ToList();
  562. // Set type specific properties
  563. playerList.ForEach(o =>
  564. {
  565. var units = o.Item2.Descendants("Unit").ToList();
  566. units.ForEach(u => o.Item1.UnplacedReinforcements.Add(Convert.ToInt32(u.Attribute("ID").Value)));
  567. o.Item1.Country = Convert.ToInt32(o.Item2.Attribute("Country").Value);
  568. o.Item1.ReinforcementPoints = Convert.ToInt32(o.Item2.Attribute("ReinforcementPoints").Value);
  569. o.Item1.IsCurrentPlayer = (o.Item2.Attribute("IsCurrentPlayer") != null) && Convert.ToBoolean(o.Item2.Attribute(("IsCurrentPlayer")).Value);
  570. o.Item1.IsAIPlayer = (o.Item2.Attribute("IsAIPlayer") != null) && Convert.ToBoolean(o.Item2.Attribute(("IsAIPlayer")).Value);
  571. });
  572. // Add to context
  573. this._playersTable.Records = playerList.Select(p => p.Item1 as IPlayerDTO).ToList();
  574. }
  575. private void LoadBoard(XDocument boardDataFile)
  576. {
  577. // Board Data
  578. var dimension = boardDataFile.Descendants("Attributes").SingleOrDefault();
  579. var board = new BoardDTO
  580. {
  581. Title = dimension.Attribute("Title").Value,
  582. Height = Convert.ToInt32(dimension.Attribute("Height").Value),
  583. Width = Convert.ToInt32(dimension.Attribute("Width").Value),
  584. CellSize = Convert.ToInt32(dimension.Attribute("CellSize").Value),
  585. CellMaxUnits = Convert.ToInt32(dimension.Attribute("CellSize").Value),
  586. } as IBoardDTO;
  587. var nodeList = boardDataFile.Descendants("Node");
  588. var nodesToSave = new List<INodeDTO>();
  589. var tilesToSave = new List<ITileDTO>();
  590. foreach (var e in nodeList)
  591. {
  592. var c = new CoordinateDTO
  593. {
  594. X = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("X").Value),
  595. Y = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("Y").Value),
  596. Z = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("Z").Value)
  597. } as ICoordinateDTO;
  598. var dgs = e.Descendants("Demographics").Descendants("Demographic")
  599. .Select(d =>
  600. new DemographicDTO
  601. {
  602. ID = Convert.ToInt32(d.Attribute("ID").Value),
  603. Orientation = (d.Attribute("Orientation") != null) ? d.Attribute("Orientation").Value : ""
  604. } as IDemographicDTO );
  605. var v = Convert.ToInt32(e.Descendants("Tile").SingleOrDefault().Attribute("VictoryPoints").Value);
  606. var t = new TileDTO
  607. {
  608. UID = Guid.NewGuid(),
  609. VictoryPoints = v,
  610. Location = c,
  611. Demographics = dgs
  612. } as ITileDTO;
  613. tilesToSave.Add(t);
  614. var n = new NodeDTO
  615. {
  616. Name = "Node - {0}".F(c.ToString()),
  617. UID = Guid.NewGuid(),
  618. Location = c,
  619. Country = Convert.ToInt32(e.Descendants("Country").SingleOrDefault().Attribute("ID").Value),
  620. DefaultTile = t
  621. } as INodeDTO;
  622. nodesToSave.Add(n);
  623. }
  624. // Add to context
  625. this._tilesTable.Records = tilesToSave;
  626. this._nodesTable.Records = nodesToSave;
  627. this._board = board;
  628. }
  629. private void LoadUnits(XDocument unitDataFile)
  630. {
  631. var unitUnitList = unitDataFile.Descendants("Unit");
  632. var unitsToSave = new List<IUnitDTO>();
  633. foreach (var e in unitUnitList)
  634. {
  635. // No Location indicates unplaced unit
  636. var c = (e.Descendants("Coordinate").SingleOrDefault() == null) ? null : new CoordinateDTO
  637. {
  638. X = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("X").Value),
  639. Y = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("Y").Value),
  640. Z = Convert.ToInt32(e.Descendants("Coordinate").SingleOrDefault().Attribute("Z").Value)
  641. };
  642. var m = new UnitDTO
  643. {
  644. ID = Convert.ToInt32(e.Attribute("ID").Value),
  645. UID = Guid.NewGuid(),
  646. Name = e.Attribute("Name").Value,
  647. SubNodeLocation = Convert.ToInt32(e.Descendants("SubNodeLocation").SingleOrDefault().Attribute("Value").Value),
  648. Location = c,
  649. Description = e.Attribute("Description").Value,
  650. Country = Convert.ToInt32(e.Descendants("Country").SingleOrDefault().Attribute("ID").Value),
  651. StackOrder = Convert.ToInt32(e.Attribute("StackOrder").Value),
  652. UnitClass = Convert.ToInt32(e.Descendants("UnitInfo").SingleOrDefault().Attribute("UnitClass").Value),
  653. UnitType = Convert.ToInt32(e.Descendants("UnitInfo").SingleOrDefault().Attribute("UnitType").Value),
  654. UnitGroupType = Convert.ToInt32(e.Descendants("UnitInfo").SingleOrDefault().Attribute("UnitGroupType").Value)
  655. };
  656. // Movement stats if this is a saved game
  657. // Data saved mid-turn
  658. if (e.Descendants("MovementStats").SingleOrDefault() != null)
  659. {
  660. m.CurrentHasPerformedAction =
  661. Convert.ToBoolean(e.Descendants("MovementStats").SingleOrDefault().Attribute("CurrentHasPerformedAction").Value);
  662. m.CurrentMovementPoints =
  663. Convert.ToInt32(e.Descendants("MovementStats").SingleOrDefault().Attribute("CurrentMovementPoints").Value);
  664. m.CurrentRemoteFirePoints =
  665. Convert.ToInt32(e.Descendants("MovementStats").SingleOrDefault().Attribute("CurrentRemoteFirePoints").Value);
  666. }
  667. var tu = new List<int>();
  668. unitsToSave.Add(m);
  669. }
  670. this._unitsTable.Records = unitsToSave;
  671. }
  672. private void LoadUnitAssignments(XDocument gameDataFile)
  673. {
  674. var lookupTmp = gameDataFile.Descendants("UnitAssignment");
  675. var lookupListTmp = new List<dynamic>();
  676. foreach (var e in lookupTmp)
  677. {
  678. dynamic d = new ExpandoObject();
  679. d.Unit = Convert.ToInt32(e.Attribute("Unit").Value);
  680. d.AssignedToUnit = Convert.ToInt32(e.Attribute("AssignedToUnit").Value);
  681. lookupListTmp.Add(d);
  682. }
  683. this._unitAssignments = lookupListTmp;
  684. }
  685. private void LoadUnitTransports(XDocument gameDataFile)
  686. {
  687. var lookupTmp = gameDataFile.Descendants("UnitTransport");
  688. var lookupListTmp = new List<dynamic>();
  689. foreach (var e in lookupTmp)
  690. {
  691. dynamic d = new ExpandoObject();
  692. d.Unit = Convert.ToInt32(e.Attribute("Unit").Value);
  693. d.TransportUnit = Convert.ToInt32(e.Attribute("TransportUnit").Value);
  694. lookupListTmp.Add(d);
  695. }
  696. this._unitTransports = lookupListTmp;
  697. }
  698. private void LoadUnitBaseTypeUnitClasses(XDocument lookupDataFile)
  699. {
  700. var lookupTmp = lookupDataFile.Descendants("UnitBaseTypeUnitClass");
  701. var lookupListTmp = new List<dynamic>();
  702. foreach (var e in lookupTmp)
  703. {
  704. dynamic d = new ExpandoObject();
  705. d.UnitBaseType = Convert.ToInt32(e.Attribute("UnitBaseType").Value);
  706. d.UnitClass = Convert.ToInt32(e.Attribute("UnitClass").Value);
  707. lookupListTmp.Add(d);
  708. }
  709. this._unitBaseTypeUnitClassesLookup = lookupListTmp;
  710. }
  711. private void LoadUnitBaseTypeUnitGeogTypes(XDocument lookupDataFile)
  712. {
  713. var lookupTmp = lookupDataFile.Descendants("UnitBaseTypeUnitGeogType");
  714. var lookupListTmp = new List<dynamic>();
  715. foreach (var e in lookupTmp)
  716. {
  717. dynamic d = new ExpandoObject();
  718. d.UnitBaseType = Convert.ToInt32(e.Attribute("UnitBaseType").Value);
  719. d.UnitGeogType = Convert.ToInt32(e.Attribute("UnitGeogType").Value);
  720. lookupListTmp.Add(d);
  721. }
  722. this._unitBaseTypeUnitGeogTypesLookup = lookupListTmp;
  723. }
  724. private void LoadHybridDemographicClasses(XDocument lookupDataFile)
  725. {
  726. var lookupTmp = lookupDataFile.Descendants("HybridDemographicClass");
  727. var lookupListTmp = new List<int>();
  728. foreach (var e in lookupTmp)
  729. {
  730. lookupListTmp.Add(Convert.ToInt32(e.Attribute("DemographicClass").Value));
  731. }
  732. this._hybridDemographicClasses = lookupListTmp;
  733. }
  734. private void LoadMovementHinderancesInDirection(XDocument lookupDataFile)
  735. {
  736. var lookupTmp = lookupDataFile.Descendants("MovementHinderance");
  737. var lookupListTmp = new List<dynamic>();
  738. foreach (var e in lookupTmp)
  739. {
  740. dynamic d = new ExpandoObject();
  741. d.DemographicClass = Convert.ToInt32(e.Attribute("DemographicClass").Value);
  742. d.UnitGeogType = Convert.ToInt32(e.Attribute("UnitGeogType").Value);
  743. d.Direction = (Direction)Convert.ToInt32(e.Attribute("Direction").Value);
  744. lookupListTmp.Add(d);
  745. }
  746. this._movementHinderanceInDirection = lookupListTmp;
  747. }
  748. private void LoadUnitGeogTypeDemographicClasses(XDocument lookupDataFile)
  749. {
  750. var lookupTmp = lookupDataFile.Descendants("UnitGeogTypeDemographicClass");
  751. var lookupListTmp = new List<dynamic>();
  752. foreach (var e in lookupTmp)
  753. {
  754. dynamic d = new ExpandoObject();
  755. d.UnitGeogType = Convert.ToInt32(e.Attribute("UnitGeogType").Value);
  756. d.DemographicClass = Convert.ToInt32(e.Attribute("DemographicClass").Value);
  757. lookupListTmp.Add(d);
  758. }
  759. this._unitGeogTypeDemographicClassesLookup = lookupListTmp;
  760. }
  761. private void LoadUnitGroupTypeUnitTasks(XDocument lookupDataFile)
  762. {
  763. var lookupTmp = lookupDataFile.Descendants("UnitGroupTypeUnitTask");
  764. var lookupListTmp = new List<dynamic>();
  765. foreach (var e in lookupTmp)
  766. {
  767. dynamic d = new ExpandoObject();
  768. d.UnitGroupType = Convert.ToInt32(e.Attribute("UnitGroupType").Value);
  769. d.UnitTask = Convert.ToInt32(e.Attribute("UnitTask").Value);
  770. lookupListTmp.Add(d);
  771. }
  772. this._unitGroupTypeUnitTaskLookup = lookupListTmp;
  773. }
  774. private void LoadMissionObjectiveUnitTasks(XDocument lookupDataFile)
  775. {
  776. var lookupTmp = lookupDataFile.Descendants("MissionObjectiveUnitTask");
  777. var lookupListTmp = new List<dynamic>();
  778. foreach (var e in lookupTmp)
  779. {
  780. dynamic d = new ExpandoObject();
  781. d.MissionObjective = Convert.ToInt32(e.Attribute("MissionObjective").Value);
  782. d.UnitTask = Convert.ToInt32(e.Attribute("UnitTask").Value);
  783. d.StepOrder = Convert.ToInt32(e.Attribute("StepOrder").Value);
  784. lookupListTmp.Add(d);
  785. }
  786. this._missionObjectiveUnitTasks = lookupListTmp;
  787. }
  788. private void LoadUnitTaskUnitClasses(XDocument lookupDataFile)
  789. {
  790. var lookupTmp = lookupDataFile.Descendants("UnitTaskUnitClass");
  791. var lookupListTmp = new List<dynamic>();
  792. foreach (var e in lookupTmp)
  793. {
  794. dynamic d = new ExpandoObject();
  795. d.UnitClass = Convert.ToInt32(e.Attribute("UnitClass").Value);
  796. d.UnitTask = Convert.ToInt32(e.Attribute("UnitTask").Value);
  797. lookupListTmp.Add(d);
  798. }
  799. this._unitTaskUnitClassesLookup = lookupListTmp;
  800. }
  801. private void LoadUnitGeogTypeMovementOverrides(XDocument lookupDataFile)
  802. {
  803. var lookupTmp = lookupDataFile.Descendants("UnitGeogTypeMovementOverrides").First().Descendants("Override");
  804. var lookupListTmp = new List<dynamic>();
  805. foreach (var e in lookupTmp)
  806. {
  807. dynamic d = new ExpandoObject();
  808. d.UnitGeogType = Convert.ToInt32(e.Attribute("UnitGeogType").Value);
  809. d.Geography = Convert.ToInt32(e.Attribute("DemographicClassA").Value);
  810. d.Infrastructure = Convert.ToInt32(e.Attribute("DemographicClassB").Value);
  811. lookupListTmp.Add(d);
  812. }
  813. this._unitGeogTypeMovementOverrides = lookupListTmp;
  814. }
  815. private void LoadUnitTypeUnitGeogTypeBattleEffectives(XDocument lookupDataFile)
  816. {
  817. var lookupTmp = lookupDataFile.Descendants("UnitTypeUnitGeogTypeBattleEffective").First().Descendants("BattleEffective");
  818. var lookupListTmp = new List<dynamic>();
  819. foreach (var e in lookupTmp)
  820. {
  821. dynamic d = new ExpandoObject();
  822. d.UnitType = Convert.ToInt32(e.Attribute("UnitType").Value);
  823. d.UnitGeogType = Convert.ToInt32(e.Attribute("UnitGeogType").Value);
  824. lookupListTmp.Add(d);
  825. }
  826. this._unitBattleEffectiveLookup = lookupListTmp;
  827. }
  828. private void LoadUnitTransportUnitTypeUnitClasses(XDocument lookupDataFile)
  829. {
  830. var lookupTmp = lookupDataFile.Descendants("UnitTransportUnitTypeUnitClasses").First().Descendants("TransportEffective");
  831. var lookupListTmp = new List<dynamic>();
  832. foreach (var e in lookupTmp)
  833. {
  834. dynamic d = new ExpandoObject();
  835. d.TransportUnitType = Convert.ToInt32(e.Attribute("TransportUnitType").Value);
  836. d.CarriedUnitType = Convert.ToInt32(e.Attribute("CarriedUnitType").Value);
  837. d.CarriedUnitClass = Convert.ToInt32(e.Attribute("CarriedUnitClass").Value);
  838. lookupListTmp.Add(d);
  839. }
  840. this._unitTransportUnitTypeUnitClasses = lookupListTmp;
  841. }
  842. private void LoadFactionVictoryConditions(XDocument gameDataFile)
  843. {
  844. var lookupTmp = gameDataFile.Descendants("VictoryCondition");
  845. var lookupListTmp = new List<dynamic>();
  846. foreach (var e in lookupTmp)
  847. {
  848. dynamic d = new ExpandoObject();
  849. d.Faction = Convert.ToInt32(e.Attribute("Faction").Value);
  850. d.Condition = Convert.ToInt32(e.Attribute("Condition").Value);
  851. d.Value = Convert.ToInt32(e.Attribute("Value").Value);
  852. lookupListTmp.Add(d);
  853. }
  854. this._factionVictoryConditions = lookupListTmp;
  855. }
  856. #endregion
  857. #region Helper Methods
  858. /// <summary>
  859. /// Returns a list of IBaseGameComponentDTO and matching source elements with the properties set from the data source
  860. /// </summary>
  861. /// <typeparam name="T"></typeparam>
  862. /// <param name="elements"></param>
  863. /// <returns></returns>
  864. private IEnumerable<Tuple<T, XElement>> GetBaseComponentDTOs<T>(IEnumerable<XElement> elements)
  865. where T : class, IBaseGameComponentDTO, new()
  866. {
  867. var retVal = elements
  868. .Select(c => new {element = c, pair = new Tuple<T, XElement>(GetBaseComponentDTO<T>(c), c)})
  869. .Select(p => p.pair);
  870. return retVal;
  871. }
  872. /// <summary>
  873. /// Returns an IBaseGameComponentDTO with the properties set from the data source
  874. /// </summary>
  875. /// <typeparam name="T"></typeparam>
  876. /// <param name="e"></param>
  877. /// <returns></returns>
  878. private T GetBaseComponentDTO<T>(XElement e)
  879. where T : class, IBaseGameComponentDTO, new()
  880. {
  881. var retVal = new T
  882. {
  883. UID = Guid.NewGuid(),
  884. Name = e.Attribute("Name").Value,
  885. Description = e.Attribute("Description").Value,
  886. ID = Convert.ToInt32(e.Attribute("ID").Value)
  887. } ;
  888. return retVal;
  889. }
  890. private void LoadStatModifierData(XElement e, IStatModifier dto)
  891. {
  892. dto.AttackModifier = (e.Attribute("AttackModifier") != null) ? Convert.ToDouble(e.Attribute("AttackModifier").Value) : 0;
  893. dto.AttackDistanceModifier = (e.Attribute("AttackDistanceModifier") != null) ? Convert.ToDouble(e.Attribute("AttackDistanceModifier").Value) : 0;
  894. dto.DefenceModifier = (e.Attribute("DefenceModifier") != null) ? Convert.ToDouble(e.Attribute("DefenceModifier").Value) : 0;
  895. dto.MovementModifier = (e.Attribute("MovementModifier") != null) ? Convert.ToDouble(e.Attribute("MovementModifier").Value) : 0;
  896. dto.UnitWeightModifier = (e.Attribute("UnitWeightModifier") != null) ? Convert.ToDouble(e.Attribute("UnitWeightModifier").Value) : 0;
  897. dto.AllowableWeightModifier = (e.Attribute("AllowableWeightModifier") != null) ? Convert.ToDouble(e.Attribute("AllowableWeightModifier").Value) : 0;
  898. dto.UnitCostModifier = (e.Attribute("UnitCostModifier") != null) ? Convert.ToDouble(e.Attribute("UnitCostModifier").Value) : 0;
  899. dto.StealthModifier = (e.Attribute("StealthModifier") != null) ? Convert.ToDouble(e.Attribute("StealthModifier").Value) : 0;
  900. }
  901. #endregion
  902. }
  903. }