PageRenderTime 45ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/JTacticalSim.Component/GameBoard/Tile.cs

https://github.com/Queztionmark/JTacticalSim
C# | 270 lines | 195 code | 51 blank | 24 comment | 18 complexity | f9123e51af5fca85fab4de0914c688b0 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Configuration;
  6. using System.Threading.Tasks;
  7. using JTacticalSim.API;
  8. using JTacticalSim.API.Component;
  9. using JTacticalSim.API.DTO;
  10. using JTacticalSim.API.Service;
  11. using JTacticalSim.API.InfoObjects;
  12. using JTacticalSim.Utility;
  13. using Microsoft.Xna.Framework;
  14. namespace JTacticalSim.Component.GameBoard
  15. {
  16. public class Tile : BoardComponentBase, ITile
  17. {
  18. private readonly List<IDemographic> _demographics;
  19. public List<IDemographic> BaseGeography { get { return _demographics.Where(d => d.IsDemographicType("BaseGeography")).ToList(); }}
  20. public List<IDemographic> Terrain { get { return _demographics.Where(d => d.IsDemographicType("Terrain")).ToList(); }}
  21. public List<IDemographic> AllGeography { get { return BaseGeography.Concat(Terrain).ToList(); }}
  22. public List<IDemographic> Infrastructure { get { return _demographics.Where(d => d.IsDemographicType("Infrastructure")).ToList(); }}
  23. public List<IDemographic> Flora { get { return _demographics.Where(d => d.IsDemographicType("Flora")).ToList(); } }
  24. public TileConsoleRenderHelper ConsoleRenderHelper { get; private set; }
  25. public bool IsGeographicChokePoint { get; set; }
  26. public int VictoryPoints { get; set; }
  27. public int TotalUnitCount { get { return _componentStacks.Sum(s => s.Value.GetAllUnits().Count); } }
  28. /// <summary>
  29. /// Use Tile_[Location]
  30. /// </summary>
  31. public override string SpriteName
  32. {
  33. get { return "Tile_{0}".F(Location.ToStringForName()); }
  34. }
  35. private Dictionary<Guid, IUnitStack> _componentStacks { get; set; }
  36. public override ICountry Country
  37. {
  38. get { return this.GetNode().Country; }
  39. set { this.GetNode().Country = value; }
  40. }
  41. // ----------------------------------------------------------------------------------------------------------
  42. /// <summary>
  43. /// Base geography is required for the tile
  44. /// this paramater can be null for the purposes of conversion
  45. /// </summary>
  46. /// <param name="location"></param>
  47. /// <param name="baseGeography"></param>
  48. public Tile(ICoordinate location, IDemographic baseGeography)
  49. {
  50. ConsoleRenderHelper = new TileConsoleRenderHelper();
  51. if (baseGeography != null && !baseGeography.IsDemographicType("BaseGeography"))
  52. throw new RulesViolationException("Tile's baseGeography must be a configured base geography type");
  53. this._demographics = new List<IDemographic>();
  54. if (baseGeography != null) this.AddDemographic(baseGeography);
  55. this.Location = location;
  56. this._componentStacks = new Dictionary<Guid, IUnitStack>();
  57. // Create a component stack for each country in the game by default
  58. CreateComponentStacksForGameCountries(location);
  59. }
  60. // ----------------------------------------------------------------------------------------------------------
  61. // Graphics
  62. public override IEnumerable<Rectangle?> GetSprites(SpriteSheet sheet)
  63. {
  64. // Try to get the specific sprite for this tile first
  65. // When a game board is created with actual map items
  66. var sprites = new List<Rectangle?>();
  67. var sprite = TheGame().JTSServices.GraphicsService.GetSprite(this, sheet);
  68. if (sprite != null)
  69. {
  70. sprites.Add(sprite);
  71. return sprites;
  72. }
  73. // Else - get the Geography class sprite for each geography class.
  74. // when the game board is created using default tiles
  75. this.AllGeography.ForEach(d =>
  76. {
  77. sprite = TheGame().JTSServices.GraphicsService.GetSprite(d.DemographicClass, sheet);
  78. if (sprite != null) sprites.Add(sprite);
  79. });
  80. return sprites;
  81. }
  82. // ---------------------------------------------------------------------------------------------------
  83. public int VisibleStackCount() { return _componentStacks.Count(cs => cs.Value.HasVisibleComponents); }
  84. public IResult<IDemographic> AddDemographic(IDemographic demographic)
  85. {
  86. var r = new ComponentResult<IDemographic>(){Status = ResultStatus.SUCCESS};
  87. try
  88. {
  89. this._demographics.Add(demographic);
  90. r.SuccessfulObjects.Add(demographic);
  91. }
  92. catch (Exception ex)
  93. {
  94. r.FailedObjects.Add(demographic);
  95. r.ex = ex;
  96. r.Status = ResultStatus.EXCEPTION;
  97. }
  98. return r;
  99. }
  100. public IResult<IDemographic> RemoveDemographic(IDemographic demographic)
  101. {
  102. var r = new ComponentResult<IDemographic>(){Status = ResultStatus.SUCCESS};
  103. try
  104. {
  105. this._demographics.Remove(demographic);
  106. r.SuccessfulObjects.Add(demographic);
  107. }
  108. catch (Exception ex)
  109. {
  110. r.FailedObjects.Add(demographic);
  111. r.ex = ex;
  112. r.Status = ResultStatus.EXCEPTION;
  113. }
  114. return r;
  115. }
  116. public List<IDemographic> GetAllDemographics() { return AllGeography.Concat(Infrastructure).Concat(Flora).ToList(); }
  117. public List<IDemographic> GetAllHybridDemographics() { return this.GetAllDemographics().Where(d => d.IsHybrid()).ToList(); }
  118. public IUnitStack GetCountryComponentStack(ICountry country){ return _componentStacks[country.UID]; }
  119. public List<IUnitStack> GetAllComponentStacks() { return _componentStacks.Select(cs => cs.Value).ToList(); }
  120. public IResult<IUnit> AddComponentsToStacks(IEnumerable<IUnit> components)
  121. {
  122. var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
  123. try
  124. {
  125. Action<IUnit> componentAction = c =>
  126. {
  127. if (_componentStacks.Any() && _componentStacks[c.Country.UID] == null)
  128. {
  129. r.Status = API.ResultStatus.SOME_FAILURE;
  130. r.FailedObjects.Add(c);
  131. r.Messages.Add("Component stack for {0} does not exist at the current tile.".F(c.Country.Name));
  132. }
  133. _componentStacks[c.Country.UID].AddUnit(c);
  134. r.SuccessfulObjects.Add(c);
  135. };
  136. if (Convert.ToBoolean(ConfigurationManager.AppSettings["run_multithreaded"]))
  137. {
  138. Parallel.ForEach(components, componentAction);
  139. }
  140. else
  141. {
  142. foreach(var c in components)
  143. componentAction(c);
  144. }
  145. }
  146. catch (Exception ex)
  147. {
  148. r.Status = API.ResultStatus.EXCEPTION;
  149. r.Messages.Add(ex.Message);
  150. r.ex = ex;
  151. }
  152. if (!r.SuccessfulObjects.Any())
  153. {
  154. r.Status = ResultStatus.FAILURE;
  155. r.Messages.Add("No units were added to unit stacks for the current tile.");
  156. }
  157. return r;
  158. }
  159. public IResult<IUnit> RemoveComponentsFromStacks(IEnumerable<IUnit> components)
  160. {
  161. var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
  162. Action<IUnit> componentAction = c =>
  163. {
  164. if (_componentStacks[c.Country.UID] == null)
  165. {
  166. r.Status = API.ResultStatus.SOME_FAILURE;
  167. r.FailedObjects.Add(c);
  168. r.Messages.Add("Component stack for {0} does not exist at the current tile.".F(c.Country.Name));
  169. }
  170. _componentStacks[c.Country.UID].RemoveUnit(c);
  171. r.SuccessfulObjects.Add(c);
  172. };
  173. try
  174. {
  175. if (Convert.ToBoolean(ConfigurationManager.AppSettings["run_multithreaded"]))
  176. {
  177. Parallel.ForEach(components, componentAction);
  178. }
  179. else
  180. {
  181. foreach(var c in components)
  182. {
  183. componentAction(c);
  184. }
  185. }
  186. }
  187. catch (Exception ex)
  188. {
  189. r.Status = ResultStatus.EXCEPTION;
  190. r.Messages.Add(ex.Message);
  191. r.ex = ex;
  192. }
  193. if (!r.SuccessfulObjects.Any())
  194. {
  195. r.Status = ResultStatus.FAILURE;
  196. r.Messages.Add("No units were removed from unit stacks for the current tile.");
  197. }
  198. return r;
  199. }
  200. public IResult<IUnit> RefreshComponentStacks()
  201. {
  202. var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
  203. // Get all components to add to stacks
  204. var units = TheGame().JTSServices.UnitService.GetAllUnitsAt(this.Location);
  205. // Clear out the current stacks
  206. _componentStacks.ToList().ForEach(kvp => kvp.Value.ClearUnits());
  207. r = (ComponentResult<IUnit>)AddComponentsToStacks(units);
  208. return r;
  209. }
  210. /// <summary>
  211. /// Stacks should be memory resident containers only... no need to save out to data
  212. /// Each component saves it's own relevant data
  213. /// </summary>
  214. private void CreateComponentStacksForGameCountries(ICoordinate location)
  215. {
  216. TheGame().GetPlayers().ForEach(p => _componentStacks.Add(p.Country.UID, new UnitStack(p.Country, location)));
  217. }
  218. }
  219. }