/JTacticalSim.Component/GameBoard/Tile.cs
C# | 270 lines | 195 code | 51 blank | 24 comment | 18 complexity | f9123e51af5fca85fab4de0914c688b0 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Configuration;
- using System.Threading.Tasks;
- using JTacticalSim.API;
- using JTacticalSim.API.Component;
- using JTacticalSim.API.DTO;
- using JTacticalSim.API.Service;
- using JTacticalSim.API.InfoObjects;
- using JTacticalSim.Utility;
- using Microsoft.Xna.Framework;
-
- namespace JTacticalSim.Component.GameBoard
- {
- public class Tile : BoardComponentBase, ITile
- {
- private readonly List<IDemographic> _demographics;
-
- public List<IDemographic> BaseGeography { get { return _demographics.Where(d => d.IsDemographicType("BaseGeography")).ToList(); }}
- public List<IDemographic> Terrain { get { return _demographics.Where(d => d.IsDemographicType("Terrain")).ToList(); }}
- public List<IDemographic> AllGeography { get { return BaseGeography.Concat(Terrain).ToList(); }}
- public List<IDemographic> Infrastructure { get { return _demographics.Where(d => d.IsDemographicType("Infrastructure")).ToList(); }}
- public List<IDemographic> Flora { get { return _demographics.Where(d => d.IsDemographicType("Flora")).ToList(); } }
-
- public TileConsoleRenderHelper ConsoleRenderHelper { get; private set; }
-
- public bool IsGeographicChokePoint { get; set; }
- public int VictoryPoints { get; set; }
- public int TotalUnitCount { get { return _componentStacks.Sum(s => s.Value.GetAllUnits().Count); } }
-
- /// <summary>
- /// Use Tile_[Location]
- /// </summary>
- public override string SpriteName
- {
- get { return "Tile_{0}".F(Location.ToStringForName()); }
- }
-
- private Dictionary<Guid, IUnitStack> _componentStacks { get; set; }
-
- public override ICountry Country
- {
- get { return this.GetNode().Country; }
- set { this.GetNode().Country = value; }
- }
-
- // ----------------------------------------------------------------------------------------------------------
-
- /// <summary>
- /// Base geography is required for the tile
- /// this paramater can be null for the purposes of conversion
- /// </summary>
- /// <param name="location"></param>
- /// <param name="baseGeography"></param>
- public Tile(ICoordinate location, IDemographic baseGeography)
- {
- ConsoleRenderHelper = new TileConsoleRenderHelper();
-
- if (baseGeography != null && !baseGeography.IsDemographicType("BaseGeography"))
- throw new RulesViolationException("Tile's baseGeography must be a configured base geography type");
-
- this._demographics = new List<IDemographic>();
- if (baseGeography != null) this.AddDemographic(baseGeography);
-
- this.Location = location;
- this._componentStacks = new Dictionary<Guid, IUnitStack>();
-
-
- // Create a component stack for each country in the game by default
- CreateComponentStacksForGameCountries(location);
- }
-
- // ----------------------------------------------------------------------------------------------------------
-
- // Graphics
-
- public override IEnumerable<Rectangle?> GetSprites(SpriteSheet sheet)
- {
- // Try to get the specific sprite for this tile first
- // When a game board is created with actual map items
- var sprites = new List<Rectangle?>();
- var sprite = TheGame().JTSServices.GraphicsService.GetSprite(this, sheet);
-
- if (sprite != null)
- {
- sprites.Add(sprite);
- return sprites;
- }
-
- // Else - get the Geography class sprite for each geography class.
- // when the game board is created using default tiles
- this.AllGeography.ForEach(d =>
- {
- sprite = TheGame().JTSServices.GraphicsService.GetSprite(d.DemographicClass, sheet);
- if (sprite != null) sprites.Add(sprite);
- });
-
- return sprites;
- }
-
- // ---------------------------------------------------------------------------------------------------
-
- public int VisibleStackCount() { return _componentStacks.Count(cs => cs.Value.HasVisibleComponents); }
-
- public IResult<IDemographic> AddDemographic(IDemographic demographic)
- {
- var r = new ComponentResult<IDemographic>(){Status = ResultStatus.SUCCESS};
-
- try
- {
- this._demographics.Add(demographic);
- r.SuccessfulObjects.Add(demographic);
- }
- catch (Exception ex)
- {
- r.FailedObjects.Add(demographic);
- r.ex = ex;
- r.Status = ResultStatus.EXCEPTION;
- }
-
- return r;
- }
-
- public IResult<IDemographic> RemoveDemographic(IDemographic demographic)
- {
- var r = new ComponentResult<IDemographic>(){Status = ResultStatus.SUCCESS};
-
- try
- {
- this._demographics.Remove(demographic);
- r.SuccessfulObjects.Add(demographic);
- }
- catch (Exception ex)
- {
- r.FailedObjects.Add(demographic);
- r.ex = ex;
- r.Status = ResultStatus.EXCEPTION;
- }
-
- return r;
- }
-
- public List<IDemographic> GetAllDemographics() { return AllGeography.Concat(Infrastructure).Concat(Flora).ToList(); }
-
- public List<IDemographic> GetAllHybridDemographics() { return this.GetAllDemographics().Where(d => d.IsHybrid()).ToList(); }
-
- public IUnitStack GetCountryComponentStack(ICountry country){ return _componentStacks[country.UID]; }
-
- public List<IUnitStack> GetAllComponentStacks() { return _componentStacks.Select(cs => cs.Value).ToList(); }
-
- public IResult<IUnit> AddComponentsToStacks(IEnumerable<IUnit> components)
- {
- var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
-
- try
- {
- Action<IUnit> componentAction = c =>
- {
- if (_componentStacks.Any() && _componentStacks[c.Country.UID] == null)
- {
- r.Status = API.ResultStatus.SOME_FAILURE;
- r.FailedObjects.Add(c);
- r.Messages.Add("Component stack for {0} does not exist at the current tile.".F(c.Country.Name));
- }
-
- _componentStacks[c.Country.UID].AddUnit(c);
- r.SuccessfulObjects.Add(c);
- };
-
- if (Convert.ToBoolean(ConfigurationManager.AppSettings["run_multithreaded"]))
- {
- Parallel.ForEach(components, componentAction);
- }
- else
- {
- foreach(var c in components)
- componentAction(c);
- }
- }
- catch (Exception ex)
- {
- r.Status = API.ResultStatus.EXCEPTION;
- r.Messages.Add(ex.Message);
- r.ex = ex;
- }
-
- if (!r.SuccessfulObjects.Any())
- {
- r.Status = ResultStatus.FAILURE;
- r.Messages.Add("No units were added to unit stacks for the current tile.");
- }
-
- return r;
- }
-
- public IResult<IUnit> RemoveComponentsFromStacks(IEnumerable<IUnit> components)
- {
- var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
-
- Action<IUnit> componentAction = c =>
- {
- if (_componentStacks[c.Country.UID] == null)
- {
- r.Status = API.ResultStatus.SOME_FAILURE;
- r.FailedObjects.Add(c);
- r.Messages.Add("Component stack for {0} does not exist at the current tile.".F(c.Country.Name));
- }
-
- _componentStacks[c.Country.UID].RemoveUnit(c);
- r.SuccessfulObjects.Add(c);
- };
-
- try
- {
- if (Convert.ToBoolean(ConfigurationManager.AppSettings["run_multithreaded"]))
- {
- Parallel.ForEach(components, componentAction);
- }
- else
- {
- foreach(var c in components)
- {
- componentAction(c);
- }
- }
- }
- catch (Exception ex)
- {
- r.Status = ResultStatus.EXCEPTION;
- r.Messages.Add(ex.Message);
- r.ex = ex;
- }
-
- if (!r.SuccessfulObjects.Any())
- {
- r.Status = ResultStatus.FAILURE;
- r.Messages.Add("No units were removed from unit stacks for the current tile.");
- }
-
- return r;
- }
-
- public IResult<IUnit> RefreshComponentStacks()
- {
- var r = new ComponentResult<IUnit>{Status = API.ResultStatus.SUCCESS};
-
- // Get all components to add to stacks
- var units = TheGame().JTSServices.UnitService.GetAllUnitsAt(this.Location);
-
- // Clear out the current stacks
- _componentStacks.ToList().ForEach(kvp => kvp.Value.ClearUnits());
-
- r = (ComponentResult<IUnit>)AddComponentsToStacks(units);
-
- return r;
- }
-
-
- /// <summary>
- /// Stacks should be memory resident containers only... no need to save out to data
- /// Each component saves it's own relevant data
- /// </summary>
- private void CreateComponentStacksForGameCountries(ICoordinate location)
- {
- TheGame().GetPlayers().ForEach(p => _componentStacks.Add(p.Country.UID, new UnitStack(p.Country, location)));
- }
- }
- }