BetterTerrainData.gd 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. @tool
  2. ## Data functions for [TileSet] properties.
  3. ##
  4. ## This data class has functions for retrieving data regarding the mathematical
  5. ## properties of a tile set.
  6. const _terrain_peering_square_tiles : Array[int] = [0, 3, 4, 7, 8, 11, 12, 15]
  7. const _terrain_peering_square_vertices : Array[int] = [3, 7, 11, 15]
  8. const _terrain_peering_isometric_tiles : Array[int] = [1, 2, 5, 6, 9, 10, 13, 14]
  9. const _terrain_peering_isometric_vertices : Array[int] = [1, 5, 9, 13]
  10. const _terrain_peering_horiztonal_tiles : Array[int] = [0, 2, 6, 8, 10, 14]
  11. const _terrain_peering_horiztonal_vertices : Array[int] = [3, 5, 7, 11, 13, 15]
  12. const _terrain_peering_vertical_tiles : Array[int] = [2, 4, 6, 10, 12, 14]
  13. const _terrain_peering_vertical_vertices : Array[int] = [1, 3, 7, 9, 11, 15]
  14. const _terrain_peering_non_modifying : Array[int] = []
  15. const _terrain_peering_hflip : Array[int] = [8, 9, 6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11]
  16. const _terrain_peering_vflip : Array[int] = [0, 1, 14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3]
  17. const _terrain_peering_transpose : Array[int] = [4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9, 6, 7]
  18. const symmetry_mapping := {
  19. BetterTerrain.SymmetryType.NONE: [0],
  20. BetterTerrain.SymmetryType.MIRROR: [0, TileSetAtlasSource.TRANSFORM_FLIP_H],
  21. BetterTerrain.SymmetryType.FLIP: [0, TileSetAtlasSource.TRANSFORM_FLIP_V],
  22. BetterTerrain.SymmetryType.REFLECT: [
  23. 0,
  24. TileSetAtlasSource.TRANSFORM_FLIP_H,
  25. TileSetAtlasSource.TRANSFORM_FLIP_V,
  26. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V
  27. ],
  28. BetterTerrain.SymmetryType.ROTATE_CLOCKWISE: [0, TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_TRANSPOSE],
  29. BetterTerrain.SymmetryType.ROTATE_COUNTER_CLOCKWISE: [0, TileSetAtlasSource.TRANSFORM_FLIP_V | TileSetAtlasSource.TRANSFORM_TRANSPOSE],
  30. BetterTerrain.SymmetryType.ROTATE_180: [0, TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V],
  31. BetterTerrain.SymmetryType.ROTATE_ALL: [
  32. 0,
  33. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_TRANSPOSE,
  34. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V,
  35. TileSetAtlasSource.TRANSFORM_FLIP_V | TileSetAtlasSource.TRANSFORM_TRANSPOSE
  36. ],
  37. BetterTerrain.SymmetryType.ALL: [
  38. 0,
  39. TileSetAtlasSource.TRANSFORM_FLIP_H,
  40. TileSetAtlasSource.TRANSFORM_FLIP_V,
  41. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V,
  42. TileSetAtlasSource.TRANSFORM_TRANSPOSE,
  43. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_TRANSPOSE,
  44. TileSetAtlasSource.TRANSFORM_FLIP_V | TileSetAtlasSource.TRANSFORM_TRANSPOSE,
  45. TileSetAtlasSource.TRANSFORM_FLIP_H | TileSetAtlasSource.TRANSFORM_FLIP_V | TileSetAtlasSource.TRANSFORM_TRANSPOSE
  46. ]
  47. }
  48. ## Returns an [Array] of ints of type [enum TileSet.CellNeighbor] which represent
  49. ## the valid neighboring tiles for a terrain of [code]type[/code] in TileSet
  50. static func get_terrain_peering_cells(ts: TileSet, type: int) -> Array[int]:
  51. if !ts or type < 0 or type >= BetterTerrain.TerrainType.MAX:
  52. return []
  53. if type == BetterTerrain.TerrainType.CATEGORY:
  54. return _terrain_peering_non_modifying
  55. if type == BetterTerrain.TerrainType.DECORATION:
  56. type = BetterTerrain.TerrainType.MATCH_TILES
  57. match [ts.tile_shape, type]:
  58. [TileSet.TILE_SHAPE_SQUARE, BetterTerrain.TerrainType.MATCH_TILES]:
  59. return _terrain_peering_square_tiles
  60. [TileSet.TILE_SHAPE_SQUARE, BetterTerrain.TerrainType.MATCH_VERTICES]:
  61. return _terrain_peering_square_vertices
  62. [TileSet.TILE_SHAPE_ISOMETRIC, BetterTerrain.TerrainType.MATCH_TILES]:
  63. return _terrain_peering_isometric_tiles
  64. [TileSet.TILE_SHAPE_ISOMETRIC, BetterTerrain.TerrainType.MATCH_VERTICES]:
  65. return _terrain_peering_isometric_vertices
  66. match [ts.tile_offset_axis, type]:
  67. [TileSet.TILE_OFFSET_AXIS_VERTICAL, BetterTerrain.TerrainType.MATCH_TILES]:
  68. return _terrain_peering_vertical_tiles
  69. [TileSet.TILE_OFFSET_AXIS_VERTICAL, BetterTerrain.TerrainType.MATCH_VERTICES]:
  70. return _terrain_peering_vertical_vertices
  71. [TileSet.TILE_OFFSET_AXIS_HORIZONTAL, BetterTerrain.TerrainType.MATCH_TILES]:
  72. return _terrain_peering_horiztonal_tiles
  73. [TileSet.TILE_OFFSET_AXIS_HORIZONTAL, BetterTerrain.TerrainType.MATCH_VERTICES]:
  74. return _terrain_peering_horiztonal_vertices
  75. return []
  76. ## Returns true if [code]peering[/code] is a valid neighboring cell for a terrain of
  77. ## [code]type[/code] in [TileSet]
  78. static func is_terrain_peering_cell(ts: TileSet, type: int, peering: int) -> bool:
  79. return peering in get_terrain_peering_cells(ts, type)
  80. static func _peering_polygon_square_tiles(peering: int) -> PackedVector2Array:
  81. const t := 1.0 / 3.0
  82. var result : PackedVector2Array
  83. match peering:
  84. TileSet.CELL_NEIGHBOR_RIGHT_SIDE: result.append(Vector2(2*t, t))
  85. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER: result.append(Vector2(2*t, 2*t))
  86. TileSet.CELL_NEIGHBOR_BOTTOM_SIDE: result.append(Vector2(t, 2*t))
  87. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER: result.append(Vector2(0, 2*t))
  88. TileSet.CELL_NEIGHBOR_LEFT_SIDE: result.append(Vector2(0, t))
  89. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER: result.append(Vector2(0, 0))
  90. TileSet.CELL_NEIGHBOR_TOP_SIDE: result.append(Vector2(t, 0))
  91. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER: result.append(Vector2(2*t, 0))
  92. -1: result.append(Vector2(t, t))
  93. result.append(result[0] + Vector2(t, 0))
  94. result.append(result[0] + Vector2(t, t))
  95. result.append(result[0] + Vector2(0, t))
  96. return result
  97. static func _peering_polygon_square_vertices(peering: int) -> PackedVector2Array:
  98. const t := 1.0 / 2.0
  99. var result : PackedVector2Array
  100. match peering:
  101. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  102. result.append(Vector2(1, t))
  103. result.append(Vector2(1, 1))
  104. result.append(Vector2(t, 1))
  105. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  106. result.append(Vector2(0, t))
  107. result.append(Vector2(t, 1))
  108. result.append(Vector2(0, 1))
  109. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  110. result.append(Vector2(0, 0))
  111. result.append(Vector2(t, 0))
  112. result.append(Vector2(0, t))
  113. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  114. result.append(Vector2(t, 0))
  115. result.append(Vector2(1, 0))
  116. result.append(Vector2(1, t))
  117. -1:
  118. result.append(Vector2(t, 0))
  119. result.append(Vector2(1, t))
  120. result.append(Vector2(t, 1))
  121. result.append(Vector2(0, t))
  122. return result
  123. static func _peering_polygon_isometric_tiles(peering: int) -> PackedVector2Array:
  124. const t := 1.0 / 4.0
  125. match peering:
  126. -1: return PackedVector2Array([Vector2(2 * t, t), Vector2(3 * t, 2 * t), Vector2(2 * t, 3 * t), Vector2(t, 2 * t)])
  127. TileSet.CELL_NEIGHBOR_RIGHT_CORNER:
  128. return PackedVector2Array([Vector2(3 * t, 2 * t), Vector2(1, t), Vector2(1, 3 * t)])
  129. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  130. return PackedVector2Array([Vector2(3 * t, 2 * t), Vector2(1, 3 * t), Vector2(3 * t, 1), Vector2(2 * t, 3 * t)])
  131. TileSet.CELL_NEIGHBOR_BOTTOM_CORNER:
  132. return PackedVector2Array([Vector2(2 * t, 3 * t), Vector2(3 * t, 1), Vector2(t, 1)])
  133. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  134. return PackedVector2Array([Vector2(t, 2 * t), Vector2(2 * t, 3 * t), Vector2(t, 1), Vector2(0, 3 * t)])
  135. TileSet.CELL_NEIGHBOR_LEFT_CORNER:
  136. return PackedVector2Array([Vector2(0, t), Vector2(t, 2 * t), Vector2(0, 3 * t)])
  137. TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE:
  138. return PackedVector2Array([Vector2(t, 0), Vector2(2 * t, t), Vector2(t, 2 * t), Vector2(0, t)])
  139. TileSet.CELL_NEIGHBOR_TOP_CORNER:
  140. return PackedVector2Array([Vector2(t, 0), Vector2(3 * t, 0), Vector2(2 * t, t)])
  141. TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  142. return PackedVector2Array([Vector2(3 * t, 0), Vector2(1, t), Vector2(3 * t, 2 * t), Vector2(2 * t, t)])
  143. return PackedVector2Array()
  144. static func _peering_polygon_isometric_vertices(peering: int) -> PackedVector2Array:
  145. const t := 1.0 / 4.0
  146. const ttt := 3.0 * t
  147. match peering:
  148. -1: return PackedVector2Array([Vector2(t, t), Vector2(ttt, t), Vector2(ttt, ttt), Vector2(t, ttt)])
  149. TileSet.CELL_NEIGHBOR_RIGHT_CORNER:
  150. return PackedVector2Array([Vector2(ttt, t), Vector2(1, 0), Vector2(1, 1), Vector2(ttt, ttt)])
  151. TileSet.CELL_NEIGHBOR_BOTTOM_CORNER:
  152. return PackedVector2Array([Vector2(t, ttt), Vector2(ttt, ttt), Vector2(1, 1), Vector2(0, 1)])
  153. TileSet.CELL_NEIGHBOR_LEFT_CORNER:
  154. return PackedVector2Array([Vector2(0, 0), Vector2(t, t), Vector2(t, ttt), Vector2(0, 1)])
  155. TileSet.CELL_NEIGHBOR_TOP_CORNER:
  156. return PackedVector2Array([Vector2(0, 0), Vector2(1, 0), Vector2(ttt, t), Vector2(t, t)])
  157. return PackedVector2Array()
  158. static func _peering_polygon_horizontal_tiles(peering: int) -> PackedVector2Array:
  159. const e := 1.0 / (2.0 * sqrt(3.0))
  160. const w := sqrt(3.0) / 8.0
  161. const t := 1.0 / 2.0
  162. const s := 1.0 / 8.0
  163. match peering:
  164. -1:
  165. return PackedVector2Array([
  166. Vector2(t, 2 * s),
  167. Vector2(t + w, t - s),
  168. Vector2(t + w, t + s),
  169. Vector2(t, 6 * s),
  170. Vector2(t - w, t + s),
  171. Vector2(t - w, t - s)
  172. ])
  173. TileSet.CELL_NEIGHBOR_RIGHT_SIDE:
  174. return PackedVector2Array([
  175. Vector2(t + w, t - s),
  176. Vector2(1, t - e),
  177. Vector2(1, t + e),
  178. Vector2(t + w, t + s)
  179. ])
  180. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  181. return PackedVector2Array([
  182. Vector2(t + w, t + s),
  183. Vector2(1, t + e),
  184. Vector2(t, 1),
  185. Vector2(t, 6 * s)
  186. ])
  187. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  188. return PackedVector2Array([
  189. Vector2(t, 6 * s),
  190. Vector2(t, 1),
  191. Vector2(0, t + e),
  192. Vector2(t - w, t + s)
  193. ])
  194. TileSet.CELL_NEIGHBOR_LEFT_SIDE:
  195. return PackedVector2Array([
  196. Vector2(t - w, t + s),
  197. Vector2(0, t + e),
  198. Vector2(0, t - e),
  199. Vector2(t - w, t - s)
  200. ])
  201. TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE:
  202. return PackedVector2Array([
  203. Vector2(t - w, t - s),
  204. Vector2(0, t - e),
  205. Vector2(t, 0),
  206. Vector2(t, 2 * s)
  207. ])
  208. TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  209. return PackedVector2Array([
  210. Vector2(t, 2 * s),
  211. Vector2(t, 0),
  212. Vector2(1, t - e),
  213. Vector2(t + w, t - s)
  214. ])
  215. return PackedVector2Array()
  216. static func _peering_polygon_horizontal_vertices(peering: int) -> PackedVector2Array:
  217. const e := 1.0 / (2.0 * sqrt(3.0))
  218. const w := sqrt(3.0) / 8.0
  219. const t := 1.0 / 2.0
  220. const s := 1.0 / 8.0
  221. match peering:
  222. -1:
  223. return PackedVector2Array([
  224. Vector2(t - s, t - w),
  225. Vector2(t + s, t - w),
  226. Vector2(6 * s, t),
  227. Vector2(t + s, t + w),
  228. Vector2(t - s, t + w),
  229. Vector2(2 * s, t)
  230. ])
  231. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  232. return PackedVector2Array([
  233. Vector2(6 * s, t),
  234. Vector2(1, t),
  235. Vector2(1, t + e),
  236. Vector2(t + e, 1 - s),
  237. Vector2(t + s, t + w)
  238. ])
  239. TileSet.CELL_NEIGHBOR_BOTTOM_CORNER:
  240. return PackedVector2Array([
  241. Vector2(t - s, t + w),
  242. Vector2(t + s, t + w),
  243. Vector2(t + e, 1 - s),
  244. Vector2(t, 1),
  245. Vector2(t - e, 1 - s)
  246. ])
  247. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  248. return PackedVector2Array([
  249. Vector2(0, t),
  250. Vector2(2 * s, t),
  251. Vector2(t - s, t + w),
  252. Vector2(t - e, 1 - s),
  253. Vector2(0, t + e)
  254. ])
  255. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  256. return PackedVector2Array([
  257. Vector2(t - e, s),
  258. Vector2(t - s, t - w),
  259. Vector2(2 * s, t),
  260. Vector2(0, t),
  261. Vector2(0, t - e)
  262. ])
  263. TileSet.CELL_NEIGHBOR_TOP_CORNER:
  264. return PackedVector2Array([
  265. Vector2(t, 0),
  266. Vector2(t + e, s),
  267. Vector2(t + s, t - w),
  268. Vector2(t - s, t - w),
  269. Vector2(t - e, s)
  270. ])
  271. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  272. return PackedVector2Array([
  273. Vector2(t + e, s),
  274. Vector2(1, t - e),
  275. Vector2(1, t),
  276. Vector2(6 * s, t),
  277. Vector2(t + s, t - w)
  278. ])
  279. return PackedVector2Array()
  280. static func _peering_polygon_vertical_tiles(peering: int) -> PackedVector2Array:
  281. const e := 1.0 / (2.0 * sqrt(3.0))
  282. const w := sqrt(3.0) / 8.0
  283. const t := 1.0 / 2.0
  284. const s := 1.0 / 8.0
  285. match peering:
  286. -1:
  287. return PackedVector2Array([
  288. Vector2(t - s, t - w),
  289. Vector2(t + s, t - w),
  290. Vector2(6 * s, t),
  291. Vector2(t + s, t + w),
  292. Vector2(t - s, t + w),
  293. Vector2(2 * s, t)
  294. ])
  295. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE:
  296. return PackedVector2Array([
  297. Vector2(6 * s, t),
  298. Vector2(1, t),
  299. Vector2(t + e, 1),
  300. Vector2(t + s, t + w)
  301. ])
  302. TileSet.CELL_NEIGHBOR_BOTTOM_SIDE:
  303. return PackedVector2Array([
  304. Vector2(t - s, t + w),
  305. Vector2(t + s, t + w),
  306. Vector2(t + e, 1),
  307. Vector2(t - e, 1)
  308. ])
  309. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_SIDE:
  310. return PackedVector2Array([
  311. Vector2(0, t),
  312. Vector2(2 * s, t),
  313. Vector2(t - s, t + w),
  314. Vector2(t - e, 1)
  315. ])
  316. TileSet.CELL_NEIGHBOR_TOP_LEFT_SIDE:
  317. return PackedVector2Array([
  318. Vector2(t - e, 0),
  319. Vector2(t - s, t - w),
  320. Vector2(2 * s, t),
  321. Vector2(0, t)
  322. ])
  323. TileSet.CELL_NEIGHBOR_TOP_SIDE:
  324. return PackedVector2Array([
  325. Vector2(t - e, 0),
  326. Vector2(t + e, 0),
  327. Vector2(t + s, t - w),
  328. Vector2(t - s, t - w)
  329. ])
  330. TileSet.CELL_NEIGHBOR_TOP_RIGHT_SIDE:
  331. return PackedVector2Array([
  332. Vector2(t + e, 0),
  333. Vector2(1, t),
  334. Vector2(6 * s, t),
  335. Vector2(t + s, t - w)
  336. ])
  337. return PackedVector2Array()
  338. static func _peering_polygon_vertical_vertices(peering: int) -> PackedVector2Array:
  339. const e := 1.0 / (2.0 * sqrt(3.0))
  340. const w := sqrt(3.0) / 8.0
  341. const t := 1.0 / 2.0
  342. const s := 1.0 / 8.0
  343. match peering:
  344. -1:
  345. return PackedVector2Array([
  346. Vector2(t, 2 * s),
  347. Vector2(t + w, t - s),
  348. Vector2(t + w, t + s),
  349. Vector2(t, 6 * s),
  350. Vector2(t - w, t + s),
  351. Vector2(t - w, t - s)
  352. ])
  353. TileSet.CELL_NEIGHBOR_RIGHT_CORNER:
  354. return PackedVector2Array([
  355. Vector2(1 - s, t - e),
  356. Vector2(1, t),
  357. Vector2(1 - s, t + e),
  358. Vector2(t + w, t + s),
  359. Vector2(t + w, t - s)
  360. ])
  361. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  362. return PackedVector2Array([
  363. Vector2(t + w, t + s),
  364. Vector2(1 - s, t + e),
  365. Vector2(t + e, 1),
  366. Vector2(t, 1),
  367. Vector2(t, 6 * s)
  368. ])
  369. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  370. return PackedVector2Array([
  371. Vector2(t - w, t + s),
  372. Vector2(t, 6 * s),
  373. Vector2(t, 1),
  374. Vector2(t - e, 1),
  375. Vector2(s, t + e)
  376. ])
  377. TileSet.CELL_NEIGHBOR_LEFT_CORNER:
  378. return PackedVector2Array([
  379. Vector2(s, t - e),
  380. Vector2(t - w, t - s),
  381. Vector2(t - w, t + s),
  382. Vector2(s, t + e),
  383. Vector2(0, t)
  384. ])
  385. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  386. return PackedVector2Array([
  387. Vector2(t - e, 0),
  388. Vector2(t, 0),
  389. Vector2(t, 2 * s),
  390. Vector2(t - w, t - s),
  391. Vector2(s, t - e)
  392. ])
  393. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  394. return PackedVector2Array([
  395. Vector2(t, 0),
  396. Vector2(t + e, 0),
  397. Vector2(1 - s, t - e),
  398. Vector2(t + w, t - s),
  399. Vector2(t, 2 * s)
  400. ])
  401. return PackedVector2Array()
  402. static func _peering_non_modifying() -> PackedVector2Array:
  403. const t := 1.0 / 3.0
  404. return PackedVector2Array([
  405. Vector2(t, 0),
  406. Vector2(2 * t, 0),
  407. Vector2(1, t),
  408. Vector2(1, 2 * t),
  409. Vector2(2 * t, 1),
  410. Vector2(t, 1),
  411. Vector2(0, 2 * t),
  412. Vector2(0, t)
  413. ])
  414. ## Returns a parameterized polygon (coordinated are between 0 and 1) for [code]peering[/code]
  415. ## direction for a terrain of [code]type[/code] in [TileSet]
  416. static func peering_polygon(ts: TileSet, type: int, peering: int) -> PackedVector2Array:
  417. if type == BetterTerrain.TerrainType.CATEGORY:
  418. return _peering_non_modifying()
  419. if type == BetterTerrain.TerrainType.DECORATION:
  420. type = BetterTerrain.TerrainType.MATCH_TILES
  421. match [ts.tile_shape, type]:
  422. [TileSet.TILE_SHAPE_SQUARE, BetterTerrain.TerrainType.MATCH_TILES]:
  423. return _peering_polygon_square_tiles(peering)
  424. [TileSet.TILE_SHAPE_SQUARE, BetterTerrain.TerrainType.MATCH_VERTICES]:
  425. return _peering_polygon_square_vertices(peering)
  426. [TileSet.TILE_SHAPE_ISOMETRIC, BetterTerrain.TerrainType.MATCH_TILES]:
  427. return _peering_polygon_isometric_tiles(peering)
  428. [TileSet.TILE_SHAPE_ISOMETRIC, BetterTerrain.TerrainType.MATCH_VERTICES]:
  429. return _peering_polygon_isometric_vertices(peering)
  430. match [ts.tile_offset_axis, type]:
  431. [TileSet.TILE_OFFSET_AXIS_VERTICAL, BetterTerrain.TerrainType.MATCH_TILES]:
  432. return _peering_polygon_vertical_tiles(peering)
  433. [TileSet.TILE_OFFSET_AXIS_VERTICAL, BetterTerrain.TerrainType.MATCH_VERTICES]:
  434. return _peering_polygon_vertical_vertices(peering)
  435. [TileSet.TILE_OFFSET_AXIS_HORIZONTAL, BetterTerrain.TerrainType.MATCH_TILES]:
  436. return _peering_polygon_horizontal_tiles(peering)
  437. [TileSet.TILE_OFFSET_AXIS_HORIZONTAL, BetterTerrain.TerrainType.MATCH_VERTICES]:
  438. return _peering_polygon_horizontal_vertices(peering)
  439. return PackedVector2Array()
  440. ## Returns as polygon centered on 0, 0 which represents the shape of the cell of
  441. ## a tile from [TileSet].
  442. static func cell_polygon(ts: TileSet) -> PackedVector2Array:
  443. const t := 1.0 / 2.0
  444. if ts.tile_shape in [TileSet.TILE_SHAPE_SQUARE, TileSet.TILE_SHAPE_HALF_OFFSET_SQUARE]:
  445. return PackedVector2Array([Vector2(-t, -t), Vector2(t, -t), Vector2(t, t), Vector2(-t, t)])
  446. if ts.tile_shape == TileSet.TILE_SHAPE_ISOMETRIC:
  447. return PackedVector2Array([Vector2(0, -t), Vector2(t, 0), Vector2(0, t), Vector2(-t, 0)])
  448. const e := t - 1.0 / (2.0 * sqrt(3.0))
  449. if ts.tile_offset_axis == TileSet.TILE_OFFSET_AXIS_HORIZONTAL:
  450. return PackedVector2Array([
  451. Vector2(0, -t),
  452. Vector2(t, -e),
  453. Vector2(t, e),
  454. Vector2(0, t),
  455. Vector2(-t, e),
  456. Vector2(-t, -e),
  457. ])
  458. return PackedVector2Array([
  459. Vector2(-t, 0),
  460. Vector2(-e, -t),
  461. Vector2(e, -t),
  462. Vector2(t, 0),
  463. Vector2(e, t),
  464. Vector2(-e, t),
  465. ])
  466. ## Returns an [Array] of coordinated that neighbor [code]coord[/code] based on [code]peering[/code]
  467. ## [Array] of [enum TileSet.CellNeighbor] for a [TileSet].
  468. static func neighboring_coords(tm: TileMapLayer, coord: Vector2i, peerings: Array) -> Array:
  469. return peerings.map(func(p): return tm.get_neighbor_cell(coord, p))
  470. ## Returns an [Array] of coordinates which neighbor the vertex describe by [code]corner[/code]
  471. ## (which is of type [enum TileSet.CellNeighbor]) from [code]coord[/code] in [TileSet].
  472. static func associated_vertex_cells(tm: TileMapLayer, coord: Vector2i, corner: int) -> Array:
  473. # get array of associated peering bits
  474. if tm.tile_set.tile_shape in [TileSet.TILE_SHAPE_SQUARE, TileSet.TILE_SHAPE_ISOMETRIC]:
  475. match corner:
  476. # Square
  477. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  478. return neighboring_coords(tm, coord, [0, 3, 4])
  479. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  480. return neighboring_coords(tm, coord, [4, 7, 8])
  481. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  482. return neighboring_coords(tm, coord, [8, 11, 12])
  483. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  484. return neighboring_coords(tm, coord, [12, 15, 0])
  485. # Isometric
  486. TileSet.CELL_NEIGHBOR_RIGHT_CORNER:
  487. return neighboring_coords(tm, coord, [14, 1, 2])
  488. TileSet.CELL_NEIGHBOR_BOTTOM_CORNER:
  489. return neighboring_coords(tm, coord, [2, 5, 6])
  490. TileSet.CELL_NEIGHBOR_LEFT_CORNER:
  491. return neighboring_coords(tm, coord, [6, 9, 10])
  492. TileSet.CELL_NEIGHBOR_TOP_CORNER:
  493. return neighboring_coords(tm, coord, [10, 13, 14])
  494. if tm.tile_set.tile_offset_axis == TileSet.TILE_OFFSET_AXIS_HORIZONTAL:
  495. match corner:
  496. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  497. return neighboring_coords(tm, coord, [0, 2])
  498. TileSet.CELL_NEIGHBOR_BOTTOM_CORNER:
  499. return neighboring_coords(tm, coord, [2, 6])
  500. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  501. return neighboring_coords(tm, coord, [6, 8])
  502. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  503. return neighboring_coords(tm, coord, [8, 10])
  504. TileSet.CELL_NEIGHBOR_TOP_CORNER:
  505. return neighboring_coords(tm, coord, [10, 14])
  506. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  507. return neighboring_coords(tm, coord, [14, 0])
  508. # TileSet.TILE_OFFSET_AXIS_VERTICAL
  509. match corner:
  510. TileSet.CELL_NEIGHBOR_RIGHT_CORNER:
  511. return neighboring_coords(tm, coord, [14, 2])
  512. TileSet.CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  513. return neighboring_coords(tm, coord, [2, 4])
  514. TileSet.CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  515. return neighboring_coords(tm, coord, [4, 6])
  516. TileSet.CELL_NEIGHBOR_LEFT_CORNER:
  517. return neighboring_coords(tm, coord, [6, 10])
  518. TileSet.CELL_NEIGHBOR_TOP_LEFT_CORNER:
  519. return neighboring_coords(tm, coord, [10, 12])
  520. TileSet.CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  521. return neighboring_coords(tm, coord, [12, 14])
  522. return []
  523. ## Returns an [Array] of [enum TileSet.CellNeighbor] suitable for flood filling
  524. ## an area in [TileSet].
  525. static func cells_adjacent_for_fill(ts: TileSet) -> Array[int]:
  526. if ts.tile_shape == TileSet.TILE_SHAPE_SQUARE:
  527. return [0, 4, 8, 12]
  528. if ts.tile_shape == TileSet.TILE_SHAPE_ISOMETRIC:
  529. return [2, 6, 10, 14]
  530. if ts.tile_offset_axis == TileSet.TILE_OFFSET_AXIS_HORIZONTAL:
  531. return _terrain_peering_horiztonal_tiles
  532. return _terrain_peering_vertical_tiles
  533. static func peering_bit_after_symmetry(bit: int, altflags: int) -> int:
  534. if altflags & TileSetAtlasSource.TRANSFORM_TRANSPOSE:
  535. bit = _terrain_peering_transpose[bit]
  536. if altflags & TileSetAtlasSource.TRANSFORM_FLIP_H:
  537. bit = _terrain_peering_hflip[bit]
  538. if altflags & TileSetAtlasSource.TRANSFORM_FLIP_V:
  539. bit = _terrain_peering_vflip[bit]
  540. return bit
  541. static func peering_bits_after_symmetry(dict: Dictionary, altflags: int) -> Dictionary:
  542. # rearrange dictionary keys based on altflags
  543. var result := {}
  544. for k in dict:
  545. result[peering_bit_after_symmetry(k, altflags)] = dict[k]
  546. return result