/TSOClient/FSO.Common.Domain/Realestate/RealestateDomain.cs

https://github.com/riperiperi/FreeSO · C# · 129 lines · 102 code · 18 blank · 9 comment · 5 complexity · bc9b4f999cf6c579cd5d7b087029a03b MD5 · raw file

  1. using FSO.Common.Domain.RealestateDomain;
  2. using FSO.Common.Domain.Shards;
  3. using FSO.Content.Model;
  4. using FSO.Server.Protocol.CitySelector;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Text.RegularExpressions;
  10. using System.Threading.Tasks;
  11. namespace FSO.Common.Domain.Realestate
  12. {
  13. public class RealestateDomain : IRealestateDomain
  14. {
  15. // No need to check redundant regex conditions until you have to throw various errors
  16. // (vide tso.client/UI/Panels/UILotPurchaseDialog.cs)
  17. // I tried to combine conditions to reduce redundancy
  18. private Regex VALIDATE_SPECIAL_CHARS = new Regex(@"[^\p{L} '-]"); // Numbers are special chars in this case
  19. private Regex VALIDATE_APOSTROPHES = new Regex("^[^']*'?[^']*$");
  20. private Regex VALIDATE_DASHES = new Regex("^[^-]*-?[^-]*$");
  21. private Regex VALIDATE_SPACES = new Regex("^[^ ]+(?: [^ ]+)*$");
  22. private Dictionary<int, ShardRealestateDomain> _ByShard;
  23. private IShardsDomain _Shards;
  24. private FSO.Content.Content _Content;
  25. public RealestateDomain(IShardsDomain shards, FSO.Content.Content content)
  26. {
  27. _Shards = shards;
  28. _Content = content;
  29. _ByShard = new Dictionary<int, ShardRealestateDomain>();
  30. foreach(var item in shards.All){
  31. GetByShard(item.Id);
  32. }
  33. }
  34. public IShardRealestateDomain GetByShard(int shardId)
  35. {
  36. lock (_ByShard)
  37. {
  38. if (_ByShard.ContainsKey(shardId))
  39. {
  40. return _ByShard[shardId];
  41. }
  42. var shard = _Shards.GetById(shardId);
  43. var item = new ShardRealestateDomain(shard, this._Content.CityMaps.Get(shard.Map));
  44. _ByShard.Add(shardId, item);
  45. return item;
  46. }
  47. }
  48. public bool ValidateLotName(string name)
  49. {
  50. if (string.IsNullOrEmpty(name) ||
  51. name.Length < 3 ||
  52. name.Length > 24 ||
  53. VALIDATE_SPECIAL_CHARS.IsMatch(name) ||
  54. !VALIDATE_APOSTROPHES.IsMatch(name) ||
  55. !VALIDATE_DASHES.IsMatch(name) ||
  56. !VALIDATE_SPACES.IsMatch(name))
  57. {
  58. return false;
  59. }
  60. return true;
  61. }
  62. }
  63. public class ShardRealestateDomain : IShardRealestateDomain
  64. {
  65. private LotPricingStrategy _Pricing;
  66. private CityMap _Map;
  67. public ShardRealestateDomain(ShardStatusItem shard, CityMap map)
  68. {
  69. _Map = map;
  70. //TODO: Hardcore
  71. _Pricing = new BasicLotPricingStrategy();
  72. }
  73. public int GetPurchasePrice(ushort x, ushort y)
  74. {
  75. return _Pricing.GetPrice(_Map, x, y);
  76. }
  77. public bool IsPurchasable(ushort x, ushort y)
  78. {
  79. //Cant buy lots on the very edge
  80. if(!MapCoordinates.InBounds(x, y, 1)){
  81. //Out of bounds!
  82. return false;
  83. }
  84. //Cant build on water
  85. var terrain = _Map.GetTerrain(x, y);
  86. if (terrain == TerrainType.WATER) { return false; }
  87. var slope = GetSlope(x, y);
  88. //10 is threshold for now
  89. return (slope < 10);
  90. }
  91. public int GetSlope(ushort x, ushort y)
  92. {
  93. x += 1;
  94. //Check elevation is ok, get all 4 corners and then decide
  95. var tl = _Map.GetElevation(x, y);
  96. var trPoint = MapCoordinates.Offset(x, y, 1, 0);
  97. var tr = _Map.GetElevation(trPoint.X, trPoint.Y);
  98. var blPoint = MapCoordinates.Offset(x, y, 0, 1);
  99. var bl = _Map.GetElevation(blPoint.X, blPoint.Y);
  100. var brPoint = MapCoordinates.Offset(x, y, 1, 1);
  101. var br = _Map.GetElevation(brPoint.X, brPoint.Y);
  102. int max = Math.Max(tl, Math.Max(tr, Math.Max(bl, br)));
  103. int min = Math.Min(tl, Math.Min(tr, Math.Min(bl, br)));
  104. return (max - min);
  105. }
  106. public CityMap GetMap()
  107. {
  108. return _Map;
  109. }
  110. }
  111. }