You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

555 lines
14 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using SUISS.Core;
  5. using SUISS.Storage;
  6. using UnityEngine;
  7. namespace SUISSEngine
  8. {
  9. [RequireComponent(typeof(Serializing))]
  10. public class IsometricGrid : MonoBehaviour
  11. {
  12. //[DebuggerBrowsable(DebuggerBrowsableState.Never)]
  13. public event IsometricGrid.GridDeserializedEventHandler GridDeserializedEvent;
  14. protected virtual void FireGridDeserializedEvent(UnityEngine.Object sender)
  15. {
  16. if (this.GridDeserializedEvent != null)
  17. {
  18. this.GridDeserializedEvent(sender);
  19. }
  20. }
  21. private void Awake()
  22. {
  23. if (this.sizeU <= 0 || this.sizeV <= 0)
  24. {
  25. throw new ArgumentException("Grid size must be positive integers", (this.Size.u > 0) ? "sizeU" : "sizeU");
  26. }
  27. if (this.readOnlyGrid && this.readOnlyWapper == null)
  28. {
  29. UnityEngine.Debug.LogError("The grid " + base.gameObject.name + " is marked read only but does not have a readonly building wapper!");
  30. }
  31. this.size = new GridSize(this.sizeU, this.sizeV);
  32. this.elements = new GridElement[this.size.u, this.size.v];
  33. this.tiles = new Dictionary<GridIndex, GridTile>();
  34. this.deserializing = false;
  35. List<bool> list = new List<bool>();
  36. string[] array = new string[0];
  37. if (this.elementTypes != null)
  38. {
  39. array = this.elementTypes.text.Split(new char[]
  40. {
  41. '\n'
  42. });
  43. }
  44. else
  45. {
  46. UnityEngine.Debug.LogWarning("elementTypes is null!");
  47. }
  48. GridIndex index;
  49. index.v = 0;
  50. while (index.v < this.size.v)
  51. {
  52. string[] array2 = new string[0];
  53. if (index.v < array.Length)
  54. {
  55. array2 = array[index.v].Split(new char[]
  56. {
  57. '\t'
  58. });
  59. }
  60. else
  61. {
  62. UnityEngine.Debug.LogWarning(string.Format("index.v ({0}) >= typeLines.Length ({1})", index.v, array.Length));
  63. }
  64. index.u = 0;
  65. while (index.u < this.size.u)
  66. {
  67. int num = 0;
  68. if (index.u < array2.Length)
  69. {
  70. try
  71. {
  72. num = int.Parse(array2[index.u].Trim());
  73. }
  74. catch (Exception ex)
  75. {
  76. UnityEngine.Debug.LogError(string.Format("Unable to parse '{0}' at {1},{2} on {3}: {4}", new object[]
  77. {
  78. array2[index.u],
  79. index.u,
  80. index.v,
  81. this.island.name,
  82. ex.StackTrace
  83. }));
  84. }
  85. }
  86. else
  87. {
  88. UnityEngine.Debug.LogWarning(string.Format("[index.v ({0})] index.u ({1}) >= types.Length ({2})", index.v, index.u, array2.Length));
  89. }
  90. GridElement gridElement = new GridElement(this, index, num);
  91. this.elements[index.u, index.v] = gridElement;
  92. while (list.Count <= num)
  93. {
  94. list.Add(false);
  95. }
  96. list[num] = true;
  97. index.u++;
  98. }
  99. index.v++;
  100. }
  101. this._availableSurfaceTypes = list.ToArray();
  102. }
  103. private void OnSerialize(Dictionary<string, object> values)
  104. {
  105. if (!this.readOnlyGrid)
  106. {
  107. GameObjectManager instance = SingletonMonobehaviour<GameObjectManager>.Instance;
  108. if (instance == null)
  109. {
  110. UnityEngine.Debug.LogError("Cannot serialize grid without GameObjectManager.");
  111. return;
  112. }
  113. values.Clear();
  114. foreach (GridTile gridTile in this.tiles.Values)
  115. {
  116. if (instance.HavePrefabWithName(gridTile.name))
  117. {
  118. string key = string.Format("{0},{1}", gridTile.index.u, gridTile.index.v);
  119. string text = gridTile.name;
  120. if (gridTile.mirrored)
  121. {
  122. text = "!" + text;
  123. }
  124. values[key] = text;
  125. }
  126. }
  127. }
  128. }
  129. private GameObject createReadOnlyPrefab(GameObject buildingPrefab)
  130. {
  131. if (buildingPrefab.GetComponent<Road>() != null)
  132. {
  133. return buildingPrefab;
  134. }
  135. this.readOnlyWapper.WrapAround(buildingPrefab);
  136. return this.readOnlyWapper.gameObject;
  137. }
  138. private void OnDeserialize(Dictionary<string, object> values)
  139. {
  140. GameObjectManager instance = SingletonMonobehaviour<GameObjectManager>.Instance;
  141. if (instance == null)
  142. {
  143. UnityEngine.Debug.LogError("Cannot deserialize grid without GameObjectManager.");
  144. return;
  145. }
  146. this.deserializing = true;
  147. Builder builder = this.island.builder;
  148. foreach (KeyValuePair<string, object> keyValuePair in values)
  149. {
  150. bool mirrored = false;
  151. string text = (string)keyValuePair.Value;
  152. if (text.StartsWith("!"))
  153. {
  154. mirrored = true;
  155. text = text.Substring(1);
  156. }
  157. if (instance.HavePrefabWithName(text))
  158. {
  159. string[] array = keyValuePair.Key.Split(new char[]
  160. {
  161. ','
  162. });
  163. GridIndex gridIndex = new GridIndex(int.Parse(array[0]), int.Parse(array[1]));
  164. if (gridIndex.isInvalid)
  165. {
  166. UnityEngine.Debug.LogWarning(string.Format("Grid entry {0} => {1} has invalid index.", keyValuePair.Key, keyValuePair.Value));
  167. }
  168. else
  169. {
  170. GameObject gameObject = instance.GetPrefabWithName(text);
  171. if (this.readOnlyGrid)
  172. {
  173. gameObject = this.createReadOnlyPrefab(gameObject);
  174. }
  175. if (builder.BuildAt(gameObject, gridIndex, mirrored, true))
  176. {
  177. GridTile gridTile = this.tiles[gridIndex];
  178. Serializing component = gridTile.GetComponent<Serializing>();
  179. if (component != null)
  180. {
  181. component.Deserialize();
  182. }
  183. }
  184. }
  185. }
  186. else if (text != "surfingSchool" && text != "jungle" && text != "swamp")
  187. {
  188. UnityEngine.Debug.LogWarning(string.Format("GameObjectManager does not have prefab with name {0}.", text));
  189. }
  190. }
  191. this.deserializing = false;
  192. this.HasGridDeserialized = true;
  193. this.FireGridDeserializedEvent(this);
  194. }
  195. protected void OnDeserialized()
  196. {
  197. this.island.BroadcastMessage("OnGridDeserialized", SendMessageOptions.DontRequireReceiver);
  198. }
  199. protected string GetKeyForIndex(GridIndex index)
  200. {
  201. return string.Format(this.serializing.StorageKey + "_Tile{0}", index.ToString());
  202. }
  203. public bool[] AvailableSurfaceTypes
  204. {
  205. get
  206. {
  207. return this._availableSurfaceTypes;
  208. }
  209. }
  210. public GridSize Size
  211. {
  212. get
  213. {
  214. return new GridSize(this.sizeU, this.sizeV);
  215. }
  216. }
  217. public GridElement this[int u, int v]
  218. {
  219. get
  220. {
  221. return this.elements[u, v];
  222. }
  223. }
  224. public GridElement this[GridIndex index]
  225. {
  226. get
  227. {
  228. return this.elements[index.u, index.v];
  229. }
  230. }
  231. public GridOverlay Overlay
  232. {
  233. get
  234. {
  235. return this.overlay;
  236. }
  237. }
  238. public ICollection<GridTile> Tiles
  239. {
  240. get
  241. {
  242. return this.tiles.Values;
  243. }
  244. }
  245. public bool HasGridDeserialized { get; private set; }
  246. public void StartImport()
  247. {
  248. this.deserializing = true;
  249. }
  250. public GridIndex ConvertIslandCoordinateToGridIndex(Vector2 islandCoordinate)
  251. {
  252. Vector3 position = base.transform.position;
  253. float num = position.y - islandCoordinate.y + 0.5f * (islandCoordinate.x - position.x);
  254. GridIndex result;
  255. result.u = Mathf.FloorToInt(num / this.elementSize.y);
  256. if (result.u < 0 || result.u >= this.size.u)
  257. {
  258. return GridIndex.invalid;
  259. }
  260. num = position.y - islandCoordinate.y - 0.5f * (islandCoordinate.x - position.x);
  261. result.v = Mathf.FloorToInt(num / this.elementSize.y);
  262. if (result.v < 0 || result.v >= this.size.v)
  263. {
  264. return GridIndex.invalid;
  265. }
  266. return result;
  267. }
  268. public void FinishImport()
  269. {
  270. this.deserializing = false;
  271. this.serializing.Serialize();
  272. }
  273. public Vector2 GetPositionForGridPoint(GridPoint point)
  274. {
  275. return new Vector2((point.u - point.v) * this.elementSize.x * 0.5f, (point.u + point.v) * this.elementSize.y * -0.5f);
  276. }
  277. public float GetZForGridIndex(GridIndex index)
  278. {
  279. return this.GetZForGridPoint(new GridPoint(index));
  280. }
  281. public float GetZForGridPoint(GridPoint point)
  282. {
  283. float num = (point.u + point.v) / (float)(this.size.u + this.size.v);
  284. return this.zFar + (this.zNear - this.zFar) * num;
  285. }
  286. public bool CanSerialize(GridTile tile)
  287. {
  288. GameObjectManager instance = SingletonMonobehaviour<GameObjectManager>.Instance;
  289. return instance.HavePrefabWithName(tile.name);
  290. }
  291. public void AddTileAt(GridTile tile, GridIndex index, bool serialize)
  292. {
  293. for (int i = index.v; i > index.v - tile.currentSize.v; i--)
  294. {
  295. for (int j = index.u; j > index.u - tile.currentSize.u; j--)
  296. {
  297. GridElement gridElement = this.elements[j, i];
  298. gridElement.Tile = tile;
  299. }
  300. }
  301. if (serialize)
  302. {
  303. Serializing component = tile.GetComponent<Serializing>();
  304. if (component != null)
  305. {
  306. component.StorageLifecycle = StorageLifecycle.Game;
  307. component.StorageKey = this.GetKeyForIndex(index);
  308. }
  309. }
  310. this.tiles[index] = tile;
  311. if (serialize && !this.deserializing && this.serializing != null && this.CanSerialize(tile))
  312. {
  313. this.serializing.Serialize();
  314. }
  315. }
  316. public void RemoveAtIndex(GridIndex index, GridSize size, bool serialize)
  317. {
  318. if (!this.tiles.ContainsKey(index))
  319. {
  320. UnityEngine.Debug.LogWarning(string.Format("Tile does not exist at {0}.", index));
  321. return;
  322. }
  323. for (int i = index.v; i > index.v - size.v; i--)
  324. {
  325. for (int j = index.u; j > index.u - size.u; j--)
  326. {
  327. GridElement gridElement = this.elements[j, i];
  328. gridElement.Tile = null;
  329. }
  330. }
  331. GridTile gridTile = this.tiles[index];
  332. if (serialize)
  333. {
  334. Serializing component = gridTile.GetComponent<Serializing>();
  335. if (component != null)
  336. {
  337. component.Delete();
  338. }
  339. }
  340. this.tiles.Remove(index);
  341. if (serialize && this.serializing != null && this.CanSerialize(gridTile))
  342. {
  343. this.serializing.Serialize();
  344. }
  345. }
  346. public void MoveTileFrom(GridTile tile, GridIndex oldIndex, bool serialize)
  347. {
  348. int num = 0;
  349. if (this.tiles.ContainsKey(oldIndex))
  350. {
  351. for (int i = oldIndex.v; i > oldIndex.v - tile.size.v; i--)
  352. {
  353. for (int j = oldIndex.u; j > oldIndex.u - tile.size.u; j--)
  354. {
  355. GridElement gridElement = this.elements[j, i];
  356. if (!object.ReferenceEquals(gridElement.Tile, tile))
  357. {
  358. num++;
  359. }
  360. gridElement.Tile = null;
  361. }
  362. }
  363. this.tiles.Remove(oldIndex);
  364. }
  365. if (num > 0)
  366. {
  367. UnityEngine.Debug.LogWarning(string.Format("While moving {0} from {1} to {2}, notMatchCount is {3}.", new object[]
  368. {
  369. tile.name,
  370. oldIndex,
  371. tile.index,
  372. num
  373. }));
  374. }
  375. for (int k = tile.index.v; k > tile.index.v - tile.size.v; k--)
  376. {
  377. for (int l = tile.index.u; l > tile.index.u - tile.size.u; l--)
  378. {
  379. if (l < 0 || l >= this.size.u || k < 0 || k >= this.size.v)
  380. {
  381. UnityEngine.Debug.LogWarning(string.Format("While moving {0} from {1} to {2}, ({3},{4}) is oob.", new object[]
  382. {
  383. tile.name,
  384. oldIndex,
  385. tile.index,
  386. l,
  387. k
  388. }));
  389. }
  390. GridElement gridElement2 = this.elements[l, k];
  391. gridElement2.Tile = tile;
  392. }
  393. }
  394. if (serialize)
  395. {
  396. Serializing component = tile.GetComponent<Serializing>();
  397. if (component != null)
  398. {
  399. component.Rename(this.GetKeyForIndex(tile.index));
  400. }
  401. }
  402. if (this.tiles.ContainsKey(tile.index))
  403. {
  404. UnityEngine.Debug.LogWarning(string.Format("While moving {0} from {1} to {2}, tile.index already exists in this.tiles.", tile.name, oldIndex, tile.index));
  405. }
  406. this.tiles[tile.index] = tile;
  407. if (serialize && !this.deserializing && this.serializing != null && this.CanSerialize(tile))
  408. {
  409. this.serializing.Serialize();
  410. }
  411. }
  412. public GridTile FindTileAt(GridIndex index, GridSize size)
  413. {
  414. for (int i = index.v; i > index.v - size.v; i--)
  415. {
  416. for (int j = index.u; j > index.u - size.u; j--)
  417. {
  418. GridElement gridElement = this.elements[j, i];
  419. if (gridElement.Tile != null)
  420. {
  421. return gridElement.Tile;
  422. }
  423. }
  424. }
  425. return null;
  426. }
  427. public IEnumerator<GridTile> GetTileEnumerator()
  428. {
  429. return this.tiles.Values.GetEnumerator();
  430. }
  431. public List<GridTile> GetNeighbourTiles(GridTile tile)
  432. {
  433. GridIndex index = tile.index;
  434. GridSize gridSize = tile.size;
  435. List<GridTile> list = new List<GridTile>();
  436. for (int i = index.v; i > index.v - gridSize.v; i--)
  437. {
  438. foreach (int num in new int[]
  439. {
  440. index.u + 1,
  441. index.u - gridSize.u
  442. })
  443. {
  444. GridIndex index2 = new GridIndex(num, i);
  445. if (this.IsWithinBounds(index2))
  446. {
  447. GridElement gridElement = this.elements[num, i];
  448. if (gridElement.Tile != null)
  449. {
  450. list.Add(gridElement.Tile);
  451. }
  452. }
  453. }
  454. }
  455. for (int k = index.u; k > index.u - gridSize.u; k--)
  456. {
  457. foreach (int num2 in new int[]
  458. {
  459. index.v + 1,
  460. index.v - gridSize.v
  461. })
  462. {
  463. GridIndex index3 = new GridIndex(k, num2);
  464. if (this.IsWithinBounds(index3))
  465. {
  466. GridElement gridElement2 = this.elements[k, num2];
  467. if (gridElement2.Tile != null)
  468. {
  469. list.Add(gridElement2.Tile);
  470. }
  471. }
  472. }
  473. }
  474. return list;
  475. }
  476. public bool IsWithinBounds(GridIndex index)
  477. {
  478. return !index.isInvalid && index.u < this.Size.u && index.v < this.Size.v;
  479. }
  480. public bool IsWithinBounds(int u, int v)
  481. {
  482. return u >= 0 && v >= 0 && u < this.Size.u && v < this.Size.v;
  483. }
  484. public int sizeU = 100;
  485. public int sizeV = 100;
  486. public Vector2 elementSize = new Vector2(100f, 50f);
  487. public float zNear = -2f;
  488. public float zFar = -1f;
  489. public float zRoadOffset = 1f;
  490. public TextAsset elementTypes;
  491. public bool readOnlyGrid;
  492. public ReadOnlyWrapper readOnlyWapper;
  493. [ParentReference]
  494. public IsometricIsland island;
  495. [SelfReference]
  496. public Serializing serializing;
  497. [SelfReference]
  498. public GridOverlay overlay;
  499. protected GridSize size;
  500. protected GridElement[,] elements;
  501. protected Dictionary<GridIndex, GridTile> tiles;
  502. protected bool[] _availableSurfaceTypes;
  503. protected bool deserializing;
  504. public delegate void GridDeserializedEventHandler(UnityEngine.Object sender);
  505. }
  506. }