EditorDisplay.Objects.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Drawing;
  5. using System.Data;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using CommonAI.Zone.ZoneEditor.Plugin.EditorToScene;
  9. using CommonAI.Zone.ZoneEditor.Plugin.SceneToEditor;
  10. using CommonAI.Zone;
  11. using CommonAI.Zone.ZoneEditor;
  12. using CommonAI.RTS;
  13. using CommonLang.Vector;
  14. using System.Collections;
  15. using CommonAI.Zone.Instance;
  16. using CommonLang;
  17. using GameEditorPlugin.Win32;
  18. using CommonFroms.Drawing;
  19. using CommonAI.RTS.Manhattan;
  20. using GameEditorPlugin.Tools;
  21. using CommonAI.Zone.Helper;
  22. namespace GameEditorPlugin.Win32.Editor
  23. {
  24. public abstract class EditorObject : DisplayObject
  25. {
  26. readonly private SceneObjectData Data;
  27. readonly public EditorWorld world;
  28. readonly public Pen pen;
  29. readonly public Pen pen_hight;
  30. readonly public SolidBrush brush;
  31. public bool Selected = false;
  32. public abstract bool Pickable { get; }
  33. public abstract float Direction { get; set; }
  34. public abstract bool IsDirectionality { get; }
  35. public EditorObject(EditorWorld wd, SceneObjectData data)
  36. {
  37. this.world = wd;
  38. this.Data = data;
  39. this.pen = new Pen(Color.FromArgb(data.Color));
  40. this.pen_hight = new Pen(Color.White);
  41. this.brush = new SolidBrush(Color.FromArgb(data.Color));
  42. }
  43. public virtual bool touch(float x, float y)
  44. {
  45. return CMath.includeRectPoint2(
  46. this.X + this.LocalBounds.X,
  47. this.Y + this.LocalBounds.Y,
  48. this.LocalBounds.Width,
  49. this.LocalBounds.Height,
  50. x, y);
  51. }
  52. public string Name { get { return Data.Name; } set { Data.Name = value; } }
  53. public override float X { get { return Data.X; } }
  54. public override float Y { get { return Data.Y; } }
  55. public override float Z { get { return 0; } }
  56. public void SetPos(float x, float y)
  57. {
  58. this.Data.X = x;
  59. this.Data.Y = y;
  60. }
  61. public override void render_begin(Graphics g)
  62. {
  63. float penscale = 1f / world.getCameraScale();
  64. pen.Width = pen_hight.Width = penscale;
  65. }
  66. public override void render_end(Graphics g)
  67. {
  68. base.render_end(g);
  69. if (Selected) this.render_selected(g);
  70. }
  71. protected virtual void render_selected(Graphics g)
  72. {
  73. g.DrawEllipse(pen_hight, LocalBounds);
  74. if (IsDirectionality)
  75. {
  76. float r = Math.Max(LocalBounds.Width, LocalBounds.Height) * 1.25f * 0.5f;
  77. g.DrawLine(pen_hight, 0, 0,
  78. (float)Math.Cos(Direction) * r,
  79. (float)Math.Sin(Direction) * r);
  80. }
  81. }
  82. public virtual void render_in_terrain(Graphics g) { }
  83. }
  84. public class EditorUnit : EditorObject
  85. {
  86. readonly public UnitData Data;
  87. readonly public UnitInfo Info;
  88. private RectangleF mLocalBounds;
  89. private static Pen pen_hitbody = new Pen(Color.Green);
  90. private static Pen pen_guardrange = new Pen(Color.Yellow);
  91. public override RectangleF LocalBounds { get { return mLocalBounds; } }
  92. public override bool Pickable { get { return EditorDisplayPanel.ShowUnit; } }
  93. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  94. public override float Direction { get { return Data.Direction; } set { this.Data.Direction = value; } }
  95. public override bool IsDirectionality { get { return true; } }
  96. public EditorUnit(EditorWorld wd, MsgPutUnit unit)
  97. : base(wd, unit.Data)
  98. {
  99. this.Data = unit.Data;
  100. this.Info = unit.UnitData;
  101. if (Info != null)
  102. {
  103. this.mLocalBounds = new RectangleF(
  104. -Info.BodySize,
  105. -Info.BodySize,
  106. Info.BodySize * 2,
  107. Info.BodySize * 2);
  108. }
  109. else
  110. {
  111. this.mLocalBounds = new RectangleF(-1, -1, 2, 2);
  112. }
  113. }
  114. public override bool touch(float x, float y)
  115. {
  116. if (Info != null)
  117. {
  118. return CMath.includeRoundPoint(this.X, this.Y, this.Info.BodySize, x, y);
  119. }
  120. return base.touch(x, y);
  121. }
  122. public override void render(Graphics g)
  123. {
  124. float penscale = 1f / world.getCameraScale();
  125. pen.Width = pen_hight.Width = pen_hitbody.Width = pen_guardrange.Width = penscale;
  126. g.DrawEllipse(pen, mLocalBounds);
  127. if (Selected)
  128. {
  129. g.FillEllipse(brush, mLocalBounds);
  130. g.DrawArc(pen_hitbody, -Info.BodyHitSize, -Info.BodyHitSize, Info.BodyHitSize * 2, Info.BodyHitSize * 2, 0, 360);
  131. g.DrawArc(pen_guardrange, -Info.GuardRange, -Info.GuardRange, Info.GuardRange * 2, Info.GuardRange * 2, 0, 360);
  132. g.DrawLine(pen_hight, 0, 0,
  133. (float)Math.Cos(Data.Direction) * mLocalBounds.Width,
  134. (float)Math.Sin(Data.Direction) * mLocalBounds.Width);
  135. }
  136. else
  137. {
  138. g.DrawLine(pen, 0, 0,
  139. (float)Math.Cos(Data.Direction) * mLocalBounds.Width,
  140. (float)Math.Sin(Data.Direction) * mLocalBounds.Width);
  141. }
  142. }
  143. }
  144. public class EditorItem : EditorObject
  145. {
  146. readonly public ItemData Data;
  147. readonly public ItemTemplate Info;
  148. private RectangleF mLocalBounds;
  149. public override RectangleF LocalBounds { get { return mLocalBounds; } }
  150. public override bool Pickable { get { return EditorDisplayPanel.ShowItem; } }
  151. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  152. public override float Direction { get { return Data.Direction; } set { this.Data.Direction = value; } }
  153. public override bool IsDirectionality { get { return true; } }
  154. public EditorItem(EditorWorld wd, MsgPutItem item)
  155. : base(wd, item.Data)
  156. {
  157. this.Data = item.Data;
  158. this.Info = item.Item;
  159. if (Info != null)
  160. {
  161. this.mLocalBounds = new RectangleF(
  162. -Info.BodySize,
  163. -Info.BodySize,
  164. Info.BodySize * 2,
  165. Info.BodySize * 2);
  166. }
  167. else
  168. {
  169. this.mLocalBounds = new RectangleF(-1, -1, 2, 2);
  170. }
  171. }
  172. public override bool touch(float x, float y)
  173. {
  174. if (Info != null)
  175. {
  176. return CMath.includeRoundPoint(this.X, this.Y, this.Info.BodySize, x, y);
  177. }
  178. return base.touch(x, y);
  179. }
  180. public override void render(Graphics g)
  181. {
  182. float penscale = 1f / world.getCameraScale();
  183. pen.Width = pen_hight.Width = penscale;
  184. g.DrawEllipse(pen, mLocalBounds);
  185. if (Selected)
  186. {
  187. g.FillEllipse(brush, mLocalBounds);
  188. g.DrawLine(pen_hight, 0, 0,
  189. (float)Math.Cos(Data.Direction) * mLocalBounds.Width,
  190. (float)Math.Sin(Data.Direction) * mLocalBounds.Width);
  191. }
  192. else
  193. {
  194. g.DrawLine(pen, 0, 0,
  195. (float)Math.Cos(Data.Direction) * mLocalBounds.Width,
  196. (float)Math.Sin(Data.Direction) * mLocalBounds.Width);
  197. }
  198. }
  199. }
  200. public class EditorRegion : EditorObject
  201. {
  202. readonly public RegionData Data;
  203. public override bool Pickable { get { return EditorDisplayPanel.ShowRegion; } }
  204. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  205. public override float Direction { get { return 0; } set { } }
  206. public override bool IsDirectionality { get { return false; } }
  207. public override RectangleF LocalBounds
  208. {
  209. get
  210. {
  211. if (Data.RegionType == RegionData.Shape.RECTANGLE)
  212. {
  213. return new RectangleF(-Data.W / 2, -Data.H / 2, Data.W, Data.H);
  214. }
  215. else if (Data.RegionType == RegionData.Shape.ROUND)
  216. {
  217. return new RectangleF(-Data.W / 2, -Data.W / 2, Data.W, Data.W);
  218. }
  219. else
  220. {
  221. return new RectangleF(-Data.W / 2, -Data.W / 2, Data.W, Data.W);
  222. }
  223. }
  224. }
  225. public EditorRegion(EditorWorld wd, MsgPutRegion data)
  226. : base(wd, data.Data)
  227. {
  228. this.Data = data.Data;
  229. }
  230. public override bool touch(float x, float y)
  231. {
  232. if (Data.RegionType == RegionData.Shape.RECTANGLE)
  233. {
  234. return base.touch(x, y);
  235. }
  236. else if(Data.RegionType == RegionData.Shape.ROUND)
  237. {
  238. return CMath.includeRoundPoint(X, Y, Data.W / 2, x, y);
  239. }
  240. else if (Data.RegionType == RegionData.Shape.STRIP)
  241. {
  242. float line_r = Data.W / 2;
  243. Vector2 p = new Vector2(X, Y);
  244. Vector2 q = new Vector2(X, Y);
  245. MathVector.movePolar(p, Data.StripDirection, -Data.H / 2);
  246. MathVector.movePolar(q, Data.StripDirection, +Data.H / 2);
  247. return CMath.includeStripWidthPoint(p.X, p.Y, q.X, q.Y, line_r, x, y);
  248. }
  249. return base.touch(x, y);
  250. }
  251. public override void render(Graphics g)
  252. {
  253. float penscale = 1f / world.getCameraScale();
  254. pen.Width = pen_hight.Width = penscale;
  255. if (Data.RegionType == RegionData.Shape.RECTANGLE)
  256. {
  257. g.DrawRectangle(pen, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  258. if (Selected)
  259. {
  260. g.FillRectangle(brush, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  261. }
  262. }
  263. else if (Data.RegionType == RegionData.Shape.ROUND)
  264. {
  265. g.DrawEllipse(pen, -Data.W / 2, -Data.W / 2, Data.W, Data.W);
  266. if (Selected)
  267. {
  268. g.FillEllipse(brush, -Data.W / 2, -Data.W / 2, Data.W, Data.W);
  269. }
  270. }
  271. else if (Data.RegionType == RegionData.Shape.STRIP)
  272. {
  273. float line_r = Data.W / 2;
  274. Line2 line = new Line2(0, 0, 0, 0);
  275. MathVector.movePolar(line.p, Data.StripDirection, -Data.H / 2);
  276. MathVector.movePolar(line.q, Data.StripDirection, +Data.H / 2);
  277. DrawingUtils.FillLineRect(g, brush, line.p.X, line.p.Y, line.q.X, line.q.Y, line_r);
  278. }
  279. }
  280. }
  281. public class EditorDecoration : EditorObject
  282. {
  283. private static SolidBrush deco_block_brush = new SolidBrush(Color.FromArgb(0x80, 0xFF, 0xFF, 0xFF));
  284. readonly public DecorationData Data;
  285. public override bool Pickable { get { return EditorDisplayPanel.ShowDecoration; } }
  286. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  287. public override bool IsDirectionality { get { return true; } }
  288. public override float Direction
  289. {
  290. get { return Data.Direction; }
  291. set
  292. {
  293. if (Data.RegionType == DecorationData.Shape.STRIP)
  294. {
  295. this.Data.StripDirection = value;
  296. }
  297. this.Data.Direction = value;
  298. }
  299. }
  300. public override RectangleF LocalBounds
  301. {
  302. get
  303. {
  304. if (Data.RegionType == DecorationData.Shape.STRIP)
  305. {
  306. return new RectangleF(-Data.W / 2, -Data.W / 2, Data.W, Data.W);
  307. }
  308. else
  309. {
  310. return new RectangleF(-Data.W / 2, -Data.H / 2, Data.W, Data.H);
  311. }
  312. }
  313. }
  314. public EditorDecoration(EditorWorld wd, MsgPutDecoration data)
  315. : base(wd, data.Data)
  316. {
  317. this.Data = data.Data;
  318. }
  319. public override bool touch(float x, float y)
  320. {
  321. if (Data.RegionType == DecorationData.Shape.RECTANGLE)
  322. {
  323. return base.touch(x, y);
  324. }
  325. else if (Data.RegionType == DecorationData.Shape.ROUND)
  326. {
  327. return CMath.includeEllipsePoint(X, Y, Data.W / 2, Data.H / 2, x, y);
  328. }
  329. else if (Data.RegionType == DecorationData.Shape.STRIP)
  330. {
  331. float line_r = Data.W / 2;
  332. Vector2 p = new Vector2(X, Y);
  333. Vector2 q = new Vector2(X, Y);
  334. MathVector.movePolar(p, Data.StripDirection, -Data.H / 2);
  335. MathVector.movePolar(q, Data.StripDirection, +Data.H / 2);
  336. return CMath.includeStripWidthPoint(p.X, p.Y, q.X, q.Y, line_r, x, y);
  337. }
  338. return base.touch(x, y);
  339. }
  340. public override void render(Graphics g)
  341. {
  342. float penscale = 1f / world.getCameraScale();
  343. pen.Width = pen_hight.Width = penscale;
  344. if (Data.RegionType == DecorationData.Shape.RECTANGLE)
  345. {
  346. if (Selected)
  347. {
  348. g.FillRectangle(brush, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  349. }
  350. g.DrawRectangle(pen, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  351. }
  352. else if (Data.RegionType == DecorationData.Shape.ROUND)
  353. {
  354. if (Selected)
  355. {
  356. g.FillEllipse(brush, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  357. }
  358. g.DrawEllipse(pen, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  359. }
  360. else if (Data.RegionType == DecorationData.Shape.STRIP)
  361. {
  362. float line_r = Data.W / 2;
  363. Line2 line = new Line2(0, 0, 0, 0);
  364. MathVector.movePolar(line.p, Data.StripDirection, -Data.H / 2);
  365. MathVector.movePolar(line.q, Data.StripDirection, +Data.H / 2);
  366. if (Selected)
  367. {
  368. DrawingUtils.FillLineRect(g, brush, line.p.X, line.p.Y, line.q.X, line.q.Y, line_r);
  369. }
  370. g.DrawEllipse(pen, -Data.W / 2, -Data.W / 2, Data.W, Data.W);
  371. DrawingUtils.DrawLineRect(g, pen, line.p.X, line.p.Y, line.q.X, line.q.Y, line_r);
  372. }
  373. if (this.Selected)
  374. {
  375. using (var pts = ListObjectPool<CommonLang.Geometry.Vector2>.AllocAutoRelease())
  376. {
  377. var pen_res = new Pen(Color.Yellow);
  378. pen_res.Width = penscale;
  379. Data.GetResourcePoints(pts);
  380. var st = g.Save();
  381. try
  382. {
  383. if (Data.ShapDirectionality) { g.RotateTransform(CMath.RadiansToDegrees(Data.StripDirection)); }
  384. foreach (var pt in pts)
  385. {
  386. DrawingUtils.DrawCross(g, pen_res, pt.X, pt.Y, 2 * penscale);
  387. }
  388. }
  389. finally
  390. {
  391. g.Restore(st);
  392. }
  393. }
  394. }
  395. }
  396. public override void render_begin(Graphics g)
  397. {
  398. base.render_begin(g);
  399. }
  400. public override void render_in_terrain(Graphics g)
  401. {
  402. if (this.Data.Blockable)
  403. {
  404. if (this.Selected || this.Pickable)
  405. {
  406. var ed = this;
  407. var bounds = ed.LocalBounds;
  408. AstarManhattan.ForEachTerrainAction action = (bx, by) =>
  409. {
  410. g.FillRectangle(deco_block_brush, bx * world.CellW, by * world.CellH, world.CellW, world.CellH);
  411. };
  412. var mmap = world.ManhattanMap;
  413. switch (ed.Data.RegionType)
  414. {
  415. case DecorationData.Shape.RECTANGLE:
  416. AstarManhattan.ForEachTerrainRect(mmap, ed.X + bounds.X, ed.Y + bounds.Y, bounds.Width, bounds.Height, action);
  417. break;
  418. case DecorationData.Shape.ROUND:
  419. AstarManhattan.ForEachTerrainEllipse(mmap, ed.X + bounds.X, ed.Y + bounds.Y, bounds.Width, bounds.Height, action);
  420. break;
  421. case DecorationData.Shape.STRIP:
  422. Line2 line = new Line2(Data.X, Data.Y, Data.X, Data.Y);
  423. MathVector.movePolar(line.p, Data.StripDirection, -Data.H / 2);
  424. MathVector.movePolar(line.q, Data.StripDirection, +Data.H / 2);
  425. AstarManhattan.ForEachTerrainStripWidth(mmap, line.p.X, line.p.Y, line.q.X, line.q.Y, Data.W / 2, action);
  426. break;
  427. }
  428. }
  429. }
  430. }
  431. }
  432. public class EditorPoint : EditorObject
  433. {
  434. readonly public PointData Data;
  435. private static Pen pen_link = new Pen(Color.FromArgb(0x80, 0x80, 0x80, 0xFF));
  436. private static Brush brush_link = new SolidBrush(Color.FromArgb(0x80, 0x80, 0x80, 0xFF));
  437. public override RectangleF LocalBounds
  438. {
  439. get
  440. {
  441. float penscale = 1f / world.getCameraScale();
  442. float ds = -4 * penscale;
  443. float dw = 8 * penscale;
  444. return new RectangleF(ds, ds, dw, dw);
  445. }
  446. }
  447. public override bool Pickable { get { return EditorDisplayPanel.ShowPoint; } }
  448. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  449. public override float Direction { get { return 0; } set { } }
  450. public override bool IsDirectionality { get { return false; } }
  451. public EditorPoint(EditorWorld wd, MsgPutPoint data)
  452. : base(wd, data.Data)
  453. {
  454. this.Data = data.Data;
  455. }
  456. public override bool touch(float x, float y)
  457. {
  458. float penscale = 1f / world.getCameraScale();
  459. return CMath.includeRoundPoint(this.X, this.Y, 4 * penscale, x, y);
  460. }
  461. public override void render(Graphics g)
  462. {
  463. float penscale = 1f / world.getCameraScale();
  464. pen_link.Width = pen.Width = pen_hight.Width = penscale;
  465. if (Data.NextNames != null)
  466. {
  467. float dw = 4 * penscale;
  468. float cw = 12 * penscale;
  469. float ch = 16 * penscale;
  470. foreach (string next in Data.NextNames)
  471. {
  472. EditorObject nextobb = world.GetObject(next);
  473. if (nextobb != null)
  474. {
  475. float ox = nextobb.X - X;
  476. float oy = nextobb.Y - Y;
  477. if (Selected)
  478. {
  479. DrawingUtils.FillCursor(g, brush_link, 0, 0, ox, oy, dw, cw, ch);
  480. }
  481. DrawingUtils.DrawCursor(g, pen_link, 0, 0, ox, oy, dw, cw, ch);
  482. }
  483. }
  484. }
  485. {
  486. float ds = -4 * penscale;
  487. float dw = 8 * penscale;
  488. g.DrawEllipse(pen, ds, ds, dw, dw);
  489. if (Selected)
  490. {
  491. g.FillEllipse(brush, ds, ds, dw, dw);
  492. }
  493. }
  494. }
  495. }
  496. public class EditorArea : EditorObject
  497. {
  498. readonly public AreaData Data;
  499. private Pen pen_link;
  500. private Pen pen_border;
  501. private Vector2 old_pos = new Vector2();
  502. private Vector2 old_size = new Vector2();
  503. private bool area_dirty = true;
  504. private ManhattanMapAreaGenerator.ContinuousMapNode area_blocks;
  505. public override RectangleF LocalBounds
  506. {
  507. get
  508. {
  509. float penscale = 1f / world.getCameraScale();
  510. float ds = -4 * penscale;
  511. float dw = 8 * penscale;
  512. return new RectangleF(ds, ds, dw, dw);
  513. }
  514. }
  515. public override bool Pickable { get { return EditorDisplayPanel.ShowArea; } }
  516. public override bool Visible { get { return EditorDisplayPanel.ShowAll || Pickable; } }
  517. public override float Direction { get { return 0; } set { } }
  518. public override bool IsDirectionality { get { return false; } }
  519. public EditorArea(EditorWorld wd, MsgPutArea data)
  520. : base(wd, data.Data)
  521. {
  522. this.Data = data.Data;
  523. var bc = Color.FromArgb((0xFFFFFF & data.Data.Color));
  524. this.pen_link = new Pen(Color.FromArgb(0x40, bc));
  525. this.pen_border = new Pen(Color.FromArgb(0xFF, bc));
  526. }
  527. public override bool touch(float x, float y)
  528. {
  529. float penscale = 1f / world.getCameraScale();
  530. return CMath.includeRoundPoint(this.X, this.Y, 4 * penscale, x, y);
  531. }
  532. public override void render(Graphics g)
  533. {
  534. float penscale = 1f / world.getCameraScale();
  535. pen_border.Width = pen_link.Width = pen.Width = pen_hight.Width = penscale;
  536. {
  537. float ds = -4 * penscale;
  538. float dw = 8 * penscale;
  539. g.DrawEllipse(pen, ds, ds, dw, dw);
  540. if (Selected)
  541. {
  542. g.FillEllipse(brush, ds, ds, dw, dw);
  543. }
  544. }
  545. if (Selected)
  546. {
  547. g.DrawRectangle(pen_hight, -Data.W / 2, -Data.H / 2, Data.W, Data.H);
  548. }
  549. if (world.IsAreaDirty || old_pos.X != X || old_pos.Y != Y || old_size.X != Data.W || old_size.Y != Data.H)
  550. {
  551. this.area_dirty = true;
  552. }
  553. this.old_pos.SetX(X);
  554. this.old_pos.SetY(Y);
  555. this.old_size.SetX(Data.W);
  556. this.old_size.SetY(Data.H);
  557. }
  558. public override void render_in_terrain(Graphics g)
  559. {
  560. if (this.Selected || this.Pickable)
  561. {
  562. if (area_dirty)
  563. {
  564. area_dirty = false;
  565. area_blocks = world.MapAreaGenerator.GetContinuousMapNode(X, Y, Data.W / 2, Data.H / 2);
  566. }
  567. if (area_blocks != null)
  568. {
  569. int current_value;
  570. if (world.MapAreaGenerator.TryGetValue(X, Y, out current_value))
  571. {
  572. int sx, sy;
  573. int sw = world.CellW;
  574. int sh = world.CellH;
  575. foreach (var index in area_blocks)
  576. {
  577. sx = index.BX * sw;
  578. sy = index.BY * sh;
  579. g.DrawRectangle(pen_link, sx, sy, sw, sh);
  580. if (area_blocks.GetIndex(index.BX, index.BY - 1) == null)
  581. g.DrawLine(pen_border, sx, sy, sx + sw, sy);
  582. if (area_blocks.GetIndex(index.BX, index.BY + 1) == null)
  583. g.DrawLine(pen_border, sx, sy + sh, sx + sw, sy + sh);
  584. if (area_blocks.GetIndex(index.BX - 1, index.BY) == null)
  585. g.DrawLine(pen_border, sx, sy, sx, sy + sh);
  586. if (area_blocks.GetIndex(index.BX + 1, index.BY) == null)
  587. g.DrawLine(pen_border, sx + sw, sy, sx + sw, sy + sh);
  588. }
  589. }
  590. }
  591. }
  592. }
  593. }
  594. }