PageRenderTime 41ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/TEditXna/Editor/Tools/MorphTool.cs

https://github.com/Surfpup/Terraria-Map-Editor
C# | 331 lines | 297 code | 32 blank | 2 comment | 82 complexity | 225ba31418c85e1b2827e0186682167e MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Input;
  4. using System.Windows.Media;
  5. using System.Windows.Media.Imaging;
  6. using BCCL.Geometry;
  7. using BCCL.Geometry.Primitives;
  8. using TEditXna.ViewModel;
  9. using System.Linq;
  10. using TEditXna.Terraria.Objects;
  11. namespace TEditXna.Editor.Tools
  12. {
  13. public sealed class MorphTool : BaseTool
  14. {
  15. private bool _isLeftDown;
  16. private bool _isRightDown;
  17. private Vector2Int32 _startPoint;
  18. private int _dirtLayer;
  19. private int _rockLayer;
  20. private List<BiomeData> Biomes = new List<BiomeData>();
  21. private BiomeData _currentBiome;
  22. public MorphTool(WorldViewModel worldViewModel)
  23. : base(worldViewModel)
  24. {
  25. CreateTileLookup();
  26. Icon = new BitmapImage(new Uri(@"pack://application:,,,/TEditXna;component/Images/Tools/paintbrush.png"));
  27. Name = "Morph";
  28. ToolType = ToolType.Brush;
  29. }
  30. private void CreateTileLookup()
  31. {
  32. Biomes.Add(new BiomeData
  33. {
  34. Biome = MorphBiome.Grass,
  35. DirtToStone = false,
  36. Stone = 1,
  37. Grass = 2,
  38. Plant1 = 3,
  39. Plant2 = 73,
  40. Sand = 53,
  41. Wall = 0,
  42. Vines = 52
  43. });
  44. Biomes.Add(new BiomeData
  45. {
  46. Biome = MorphBiome.Corruption,
  47. DirtToStone = false,
  48. Stone = 25,
  49. Grass = 23,
  50. Plant1 = 24,
  51. Plant2 = 73,
  52. Sand = 112,
  53. Wall = 3,
  54. Vines = 32
  55. });
  56. Biomes.Add(new BiomeData
  57. {
  58. Biome = MorphBiome.Jungle,
  59. DirtToStone = true,
  60. Stone = 59,
  61. Grass = 60,
  62. Plant1 = 61,
  63. Plant2 = 74,
  64. Sand = 53,
  65. Wall = 15,
  66. Vines = 62
  67. });
  68. Biomes.Add(new BiomeData
  69. {
  70. Biome = MorphBiome.Hallowed,
  71. DirtToStone = false,
  72. Stone = 117,
  73. Grass = 109,
  74. Plant1 = 110,
  75. Plant2 = 113,
  76. Sand = 116,
  77. Wall = 0,
  78. Vines = 52
  79. });
  80. Biomes.Add(new BiomeData
  81. {
  82. Biome = MorphBiome.Snow,
  83. DirtToStone = true,
  84. Stone = 147,
  85. Grass = 147,
  86. Plant1 = 3,
  87. Plant2 = 73,
  88. Sand = 147,
  89. Wall = 0,
  90. Vines = 52
  91. });
  92. Biomes.Add(new BiomeData
  93. {
  94. Biome = MorphBiome.Desert,
  95. DirtToStone = true,
  96. Stone = 53,
  97. Grass = 53,
  98. Plant1 = 3,
  99. Plant2 = 73,
  100. Sand = 53,
  101. Wall = 0,
  102. Vines = 52
  103. });
  104. }
  105. public override void MouseDown(TileMouseState e)
  106. {
  107. if (!_isRightDown && !_isLeftDown)
  108. {
  109. _currentBiome = Biomes.FirstOrDefault(b=>b.Biome== _wvm.MorphBiomeTarget);
  110. _startPoint = e.Location;
  111. _dirtLayer = (int)_wvm.CurrentWorld.GroundLevel;
  112. _rockLayer = (int)_wvm.CurrentWorld.RockLevel;
  113. _wvm.CheckTiles = new bool[_wvm.CurrentWorld.TilesWide * _wvm.CurrentWorld.TilesHigh];
  114. }
  115. _isLeftDown = (e.LeftButton == MouseButtonState.Pressed);
  116. _isRightDown = (e.RightButton == MouseButtonState.Pressed);
  117. CheckDirectionandDraw(e.Location);
  118. }
  119. public override void MouseMove(TileMouseState e)
  120. {
  121. _isLeftDown = (e.LeftButton == MouseButtonState.Pressed);
  122. _isRightDown = (e.RightButton == MouseButtonState.Pressed);
  123. CheckDirectionandDraw(e.Location);
  124. }
  125. public override void MouseUp(TileMouseState e)
  126. {
  127. CheckDirectionandDraw(e.Location);
  128. _isLeftDown = (e.LeftButton == MouseButtonState.Pressed);
  129. _isRightDown = (e.RightButton == MouseButtonState.Pressed);
  130. _wvm.UndoManager.SaveUndo();
  131. }
  132. public override WriteableBitmap PreviewTool()
  133. {
  134. var bmp = new WriteableBitmap(_wvm.Brush.Width + 1, _wvm.Brush.Height + 1, 96, 96, PixelFormats.Bgra32, null);
  135. bmp.Clear();
  136. if (_wvm.Brush.Shape == BrushShape.Square)
  137. bmp.FillRectangle(0, 0, _wvm.Brush.Width, _wvm.Brush.Height, Color.FromArgb(127, 0, 90, 255));
  138. else
  139. bmp.FillEllipse(0, 0, _wvm.Brush.Width, _wvm.Brush.Height, Color.FromArgb(127, 0, 90, 255));
  140. _preview = bmp;
  141. return _preview;
  142. }
  143. private void CheckDirectionandDraw(Vector2Int32 tile)
  144. {
  145. if (_currentBiome != null)
  146. {
  147. Vector2Int32 p = tile;
  148. if (_isRightDown)
  149. {
  150. if (_isLeftDown)
  151. p.X = _startPoint.X;
  152. else
  153. p.Y = _startPoint.Y;
  154. DrawLine(p);
  155. _startPoint = p;
  156. }
  157. else if (_isLeftDown)
  158. {
  159. DrawLine(p);
  160. _startPoint = p;
  161. }
  162. }
  163. }
  164. private void DrawLine(Vector2Int32 to)
  165. {
  166. IEnumerable<Vector2Int32> area;
  167. foreach (Vector2Int32 point in Shape.DrawLineTool(_startPoint, to))
  168. {
  169. if (_wvm.Brush.Shape == BrushShape.Round)
  170. {
  171. area = Fill.FillEllipseCentered(point, new Vector2Int32(_wvm.Brush.Width / 2, _wvm.Brush.Height / 2));
  172. FillSolid(area);
  173. }
  174. else if (_wvm.Brush.Shape == BrushShape.Square)
  175. {
  176. area = Fill.FillRectangleCentered(point, new Vector2Int32(_wvm.Brush.Width, _wvm.Brush.Height));
  177. FillSolid(area);
  178. }
  179. }
  180. }
  181. private void FillSolid(IEnumerable<Vector2Int32> area)
  182. {
  183. foreach (Vector2Int32 pixel in area)
  184. {
  185. if (!_wvm.CurrentWorld.ValidTileLocation(pixel)) continue;
  186. int index = pixel.X + pixel.Y * _wvm.CurrentWorld.TilesWide;
  187. if (!_wvm.CheckTiles[index])
  188. {
  189. _wvm.CheckTiles[index] = true;
  190. if (_wvm.Selection.IsValid(pixel))
  191. {
  192. _wvm.UndoManager.SaveTile(pixel);
  193. MorphTile(pixel);
  194. _wvm.UpdateRenderPixel(pixel);
  195. /* Heathtech */
  196. BlendRules.ResetUVCache(_wvm, pixel.X, pixel.Y, 1, 1);
  197. }
  198. }
  199. }
  200. }
  201. private void MorphTile(Vector2Int32 p)
  202. {
  203. var curtile = _wvm.CurrentWorld.Tiles[p.X, p.Y];
  204. if (curtile.IsActive)
  205. {
  206. if (curtile.Type == 0 && _currentBiome.DirtToStone)
  207. curtile.Type = _currentBiome.Stone;
  208. else
  209. {
  210. foreach (var biome in Biomes)
  211. {
  212. if (curtile.Type == biome.Stone)
  213. {
  214. if (!_currentBiome.DirtToStone && (p.Y < _dirtLayer))
  215. curtile.Type = 0;
  216. else
  217. curtile.Type = _currentBiome.Stone;
  218. }
  219. else if (curtile.Type == biome.Grass)
  220. {
  221. if (!_currentBiome.DirtToStone && (p.Y < _rockLayer))
  222. curtile.Type = _currentBiome.Grass;
  223. else
  224. curtile.Type = _currentBiome.Stone;
  225. }
  226. else if (curtile.Type == biome.Sand)
  227. curtile.Type = _currentBiome.Sand;
  228. else if (curtile.Type == biome.Stone)
  229. curtile.Type = _currentBiome.Stone;
  230. else if (curtile.Type == biome.Vines)
  231. curtile.Type = _currentBiome.Vines;
  232. else if (curtile.Type == biome.Plant1 || curtile.Type == biome.Plant2)
  233. curtile.IsActive = false;
  234. }
  235. }
  236. // Add grass where appropriate
  237. if ((curtile.Type == 0 && p.Y < _rockLayer) || (curtile.Type == _currentBiome.Stone && _currentBiome.DirtToStone))
  238. {
  239. if (BordersAir(p))
  240. {
  241. curtile.Type = _currentBiome.Grass;
  242. }
  243. }
  244. }
  245. if (p.Y < _dirtLayer)
  246. {
  247. if (curtile.Wall != 0)
  248. {
  249. if ((Biomes.Any(x => x.Wall == curtile.Wall) || curtile.Wall == 2) || _currentBiome.DirtToStone)
  250. {
  251. curtile.Wall = _currentBiome.Wall == 0 ? (byte)2 : _currentBiome.Wall;
  252. }
  253. }
  254. }
  255. else if (p.Y < _wvm.CurrentWorld.TilesHigh - 182)
  256. {
  257. if (_currentBiome.DirtToStone)
  258. {
  259. curtile.Wall = _currentBiome.Wall;
  260. }
  261. else if (curtile.Wall != 0)
  262. {
  263. if (Biomes.Any(x => x.Wall == curtile.Wall))
  264. {
  265. curtile.Wall = _currentBiome.Wall;
  266. }
  267. }
  268. }
  269. }
  270. private bool BordersAir(Vector2Int32 p)
  271. {
  272. int x1 = p.X - 1;
  273. if (x1 < 0) x1 = 0;
  274. int x2 = p.X + 1;
  275. if (x2 >= _wvm.CurrentWorld.TilesWide) x2 = p.X;
  276. int y1 = p.Y - 1;
  277. if (y1 < 0) y1 = 0;
  278. int y2 = p.Y + 1;
  279. if (y2 >= _wvm.CurrentWorld.TilesHigh) y2 = p.X;
  280. if (!_wvm.CurrentWorld.Tiles[p.X, y1].IsActive || !_wvm.CurrentWorld.Tiles[p.X, y2].IsActive ||
  281. !_wvm.CurrentWorld.Tiles[x1, p.Y].IsActive || !_wvm.CurrentWorld.Tiles[x2, p.Y].IsActive)
  282. return true;
  283. return false;
  284. }
  285. private class BiomeData
  286. {
  287. public MorphBiome Biome;
  288. public byte Plant1;
  289. public byte Plant2;
  290. public byte Stone;
  291. public byte Grass;
  292. public byte Sand;
  293. public byte Wall;
  294. public byte Vines;
  295. public bool DirtToStone;
  296. public bool IsOverwriteAll;
  297. }
  298. }
  299. }