tile_map.cpp 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770
  1. /*************************************************************************/
  2. /* tile_map.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
  9. /* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
  10. /* */
  11. /* Permission is hereby granted, free of charge, to any person obtaining */
  12. /* a copy of this software and associated documentation files (the */
  13. /* "Software"), to deal in the Software without restriction, including */
  14. /* without limitation the rights to use, copy, modify, merge, publish, */
  15. /* distribute, sublicense, and/or sell copies of the Software, and to */
  16. /* permit persons to whom the Software is furnished to do so, subject to */
  17. /* the following conditions: */
  18. /* */
  19. /* The above copyright notice and this permission notice shall be */
  20. /* included in all copies or substantial portions of the Software. */
  21. /* */
  22. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  23. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  24. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  25. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  26. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  27. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  28. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  29. /*************************************************************************/
  30. #include "tile_map.h"
  31. #include "core/io/marshalls.h"
  32. #include "core/math/geometry_2d.h"
  33. #include "core/os/os.h"
  34. void TileMapPattern::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
  35. ERR_FAIL_COND_MSG(p_coords.x < 0 || p_coords.y < 0, vformat("Cannot set cell with negative coords in a TileMapPattern. Wrong coords: %s", p_coords));
  36. size = size.max(p_coords + Vector2i(1, 1));
  37. pattern[p_coords] = TileMapCell(p_source_id, p_atlas_coords, p_alternative_tile);
  38. }
  39. bool TileMapPattern::has_cell(const Vector2i &p_coords) const {
  40. return pattern.has(p_coords);
  41. }
  42. void TileMapPattern::remove_cell(const Vector2i &p_coords, bool p_update_size) {
  43. ERR_FAIL_COND(!pattern.has(p_coords));
  44. pattern.erase(p_coords);
  45. if (p_update_size) {
  46. size = Vector2i();
  47. for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
  48. size = size.max(E->key() + Vector2i(1, 1));
  49. }
  50. }
  51. }
  52. int TileMapPattern::get_cell_source_id(const Vector2i &p_coords) const {
  53. ERR_FAIL_COND_V(!pattern.has(p_coords), -1);
  54. return pattern[p_coords].source_id;
  55. }
  56. Vector2i TileMapPattern::get_cell_atlas_coords(const Vector2i &p_coords) const {
  57. ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetAtlasSource::INVALID_ATLAS_COORDS);
  58. return pattern[p_coords].get_atlas_coords();
  59. }
  60. int TileMapPattern::get_cell_alternative_tile(const Vector2i &p_coords) const {
  61. ERR_FAIL_COND_V(!pattern.has(p_coords), TileSetAtlasSource::INVALID_TILE_ALTERNATIVE);
  62. return pattern[p_coords].alternative_tile;
  63. }
  64. TypedArray<Vector2i> TileMapPattern::get_used_cells() const {
  65. // Returns the cells used in the tilemap.
  66. TypedArray<Vector2i> a;
  67. a.resize(pattern.size());
  68. int i = 0;
  69. for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
  70. Vector2i p(E->key().x, E->key().y);
  71. a[i++] = p;
  72. }
  73. return a;
  74. }
  75. Vector2i TileMapPattern::get_size() const {
  76. return size;
  77. }
  78. void TileMapPattern::set_size(const Vector2i &p_size) {
  79. for (Map<Vector2i, TileMapCell>::Element *E = pattern.front(); E; E = E->next()) {
  80. Vector2i coords = E->key();
  81. if (p_size.x <= coords.x || p_size.y <= coords.y) {
  82. ERR_FAIL_MSG(vformat("Cannot set pattern size to %s, it contains a tile at %s. Size can only be increased.", p_size, coords));
  83. };
  84. }
  85. size = p_size;
  86. }
  87. bool TileMapPattern::is_empty() const {
  88. return pattern.is_empty();
  89. };
  90. void TileMapPattern::clear() {
  91. size = Vector2i();
  92. pattern.clear();
  93. };
  94. void TileMapPattern::_bind_methods() {
  95. ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMapPattern::set_cell, DEFVAL(-1), DEFVAL(TileSetAtlasSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetAtlasSource::INVALID_TILE_ALTERNATIVE));
  96. ClassDB::bind_method(D_METHOD("has_cell", "coords"), &TileMapPattern::has_cell);
  97. ClassDB::bind_method(D_METHOD("remove_cell", "coords"), &TileMapPattern::remove_cell);
  98. ClassDB::bind_method(D_METHOD("get_cell_source_id", "coords"), &TileMapPattern::get_cell_source_id);
  99. ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "coords"), &TileMapPattern::get_cell_atlas_coords);
  100. ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "coords"), &TileMapPattern::get_cell_alternative_tile);
  101. ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMapPattern::get_used_cells);
  102. ClassDB::bind_method(D_METHOD("get_size"), &TileMapPattern::get_size);
  103. ClassDB::bind_method(D_METHOD("set_size", "size"), &TileMapPattern::set_size);
  104. ClassDB::bind_method(D_METHOD("is_empty"), &TileMapPattern::is_empty);
  105. }
  106. Vector2i TileMap::transform_coords_layout(Vector2i p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout) {
  107. // Transform to stacked layout.
  108. Vector2i output = p_coords;
  109. if (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
  110. SWAP(output.x, output.y);
  111. }
  112. switch (p_from_layout) {
  113. case TileSet::TILE_LAYOUT_STACKED:
  114. break;
  115. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  116. if (output.y % 2) {
  117. output.x -= 1;
  118. }
  119. break;
  120. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  121. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  122. if ((p_from_layout == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  123. if (output.y < 0 && bool(output.y % 2)) {
  124. output = Vector2i(output.x + output.y / 2 - 1, output.y);
  125. } else {
  126. output = Vector2i(output.x + output.y / 2, output.y);
  127. }
  128. } else {
  129. if (output.x < 0 && bool(output.x % 2)) {
  130. output = Vector2i(output.x / 2 - 1, output.x + output.y * 2);
  131. } else {
  132. output = Vector2i(output.x / 2, output.x + output.y * 2);
  133. }
  134. }
  135. break;
  136. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  137. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  138. if ((p_from_layout == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  139. if ((output.x + output.y) < 0 && (output.x - output.y) % 2) {
  140. output = Vector2i((output.x + output.y) / 2 - 1, output.y - output.x);
  141. } else {
  142. output = Vector2i((output.x + output.y) / 2, -output.x + output.y);
  143. }
  144. } else {
  145. if ((output.x - output.y) < 0 && (output.x + output.y) % 2) {
  146. output = Vector2i((output.x - output.y) / 2 - 1, output.x + output.y);
  147. } else {
  148. output = Vector2i((output.x - output.y) / 2, output.x + output.y);
  149. }
  150. }
  151. break;
  152. }
  153. switch (p_to_layout) {
  154. case TileSet::TILE_LAYOUT_STACKED:
  155. break;
  156. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  157. if (output.y % 2) {
  158. output.x += 1;
  159. }
  160. break;
  161. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  162. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  163. if ((p_to_layout == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  164. if (output.y < 0 && (output.y % 2)) {
  165. output = Vector2i(output.x - output.y / 2 + 1, output.y);
  166. } else {
  167. output = Vector2i(output.x - output.y / 2, output.y);
  168. }
  169. } else {
  170. if (output.y % 2) {
  171. if (output.y < 0) {
  172. output = Vector2i(2 * output.x + 1, -output.x + output.y / 2 - 1);
  173. } else {
  174. output = Vector2i(2 * output.x + 1, -output.x + output.y / 2);
  175. }
  176. } else {
  177. output = Vector2i(2 * output.x, -output.x + output.y / 2);
  178. }
  179. }
  180. break;
  181. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  182. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  183. if ((p_to_layout == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  184. if (output.y % 2) {
  185. if (output.y > 0) {
  186. output = Vector2i(output.x - output.y / 2, output.x + output.y / 2 + 1);
  187. } else {
  188. output = Vector2i(output.x - output.y / 2 + 1, output.x + output.y / 2);
  189. }
  190. } else {
  191. output = Vector2i(output.x - output.y / 2, output.x + output.y / 2);
  192. }
  193. } else {
  194. if (output.y % 2) {
  195. if (output.y < 0) {
  196. output = Vector2i(output.x + output.y / 2, -output.x + output.y / 2 - 1);
  197. } else {
  198. output = Vector2i(output.x + output.y / 2 + 1, -output.x + output.y / 2);
  199. }
  200. } else {
  201. output = Vector2i(output.x + output.y / 2, -output.x + output.y / 2);
  202. }
  203. }
  204. break;
  205. }
  206. if (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
  207. SWAP(output.x, output.y);
  208. }
  209. return output;
  210. }
  211. int TileMap::get_effective_quadrant_size() const {
  212. // When using YSort, the quadrant size is reduced to 1 to have one CanvasItem per quadrant
  213. if (tile_set.is_valid() && tile_set->is_y_sorting()) {
  214. return 1;
  215. } else {
  216. return quadrant_size;
  217. }
  218. }
  219. Vector2i TileMap::_coords_to_quadrant_coords(const Vector2i &p_coords) const {
  220. int quadrant_size = get_effective_quadrant_size();
  221. // Rounding down, instead of simply rounding towards zero (truncating)
  222. return Vector2i(
  223. p_coords.x > 0 ? p_coords.x / quadrant_size : (p_coords.x - (quadrant_size - 1)) / quadrant_size,
  224. p_coords.y > 0 ? p_coords.y / quadrant_size : (p_coords.y - (quadrant_size - 1)) / quadrant_size);
  225. }
  226. void TileMap::_notification(int p_what) {
  227. switch (p_what) {
  228. case NOTIFICATION_ENTER_TREE: {
  229. pending_update = true;
  230. _recreate_quadrants();
  231. } break;
  232. case NOTIFICATION_EXIT_TREE: {
  233. _clear_quadrants();
  234. } break;
  235. }
  236. // Transfers the notification to tileset plugins.
  237. if (tile_set.is_valid()) {
  238. for (int i = 0; i < tile_set->get_tile_set_atlas_plugins().size(); i++) {
  239. tile_set->get_tile_set_atlas_plugins()[i]->tilemap_notification(this, p_what);
  240. }
  241. }
  242. }
  243. Ref<TileSet> TileMap::get_tileset() const {
  244. return tile_set;
  245. }
  246. void TileMap::set_tileset(const Ref<TileSet> &p_tileset) {
  247. if (p_tileset == tile_set) {
  248. return;
  249. }
  250. // Set the tileset, registering to its changes.
  251. if (tile_set.is_valid()) {
  252. tile_set->disconnect("changed", callable_mp(this, &TileMap::_make_all_quadrants_dirty));
  253. tile_set->disconnect("changed", callable_mp(this, &TileMap::_tile_set_changed));
  254. }
  255. if (!p_tileset.is_valid()) {
  256. _clear_quadrants();
  257. }
  258. tile_set = p_tileset;
  259. if (tile_set.is_valid()) {
  260. tile_set->connect("changed", callable_mp(this, &TileMap::_make_all_quadrants_dirty), varray(true));
  261. tile_set->connect("changed", callable_mp(this, &TileMap::_tile_set_changed));
  262. _recreate_quadrants();
  263. }
  264. emit_signal("changed");
  265. }
  266. int TileMap::get_quadrant_size() const {
  267. return quadrant_size;
  268. }
  269. void TileMap::set_quadrant_size(int p_size) {
  270. ERR_FAIL_COND_MSG(p_size < 1, "TileMapQuadrant size cannot be smaller than 1.");
  271. quadrant_size = p_size;
  272. _recreate_quadrants();
  273. emit_signal("changed");
  274. }
  275. void TileMap::_fix_cell_transform(Transform2D &xform, const TileMapCell &p_cell, const Vector2 &p_offset, const Size2 &p_sc) {
  276. Size2 s = p_sc;
  277. Vector2 offset = p_offset;
  278. // Flip/transpose: update the tile transform.
  279. TileSetSource *source = *tile_set->get_source(p_cell.source_id);
  280. TileSetAtlasSource *atlas_source = Object::cast_to<TileSetAtlasSource>(source);
  281. if (!atlas_source) {
  282. return;
  283. }
  284. TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(p_cell.get_atlas_coords(), p_cell.alternative_tile));
  285. if (tile_data->get_transpose()) {
  286. SWAP(xform.elements[0].x, xform.elements[0].y);
  287. SWAP(xform.elements[1].x, xform.elements[1].y);
  288. SWAP(offset.x, offset.y);
  289. SWAP(s.x, s.y);
  290. }
  291. if (tile_data->get_flip_h()) {
  292. xform.elements[0].x = -xform.elements[0].x;
  293. xform.elements[1].x = -xform.elements[1].x;
  294. offset.x = s.x - offset.x;
  295. }
  296. if (tile_data->get_flip_v()) {
  297. xform.elements[0].y = -xform.elements[0].y;
  298. xform.elements[1].y = -xform.elements[1].y;
  299. offset.y = s.y - offset.y;
  300. }
  301. xform.elements[2] += offset;
  302. }
  303. void TileMap::update_dirty_quadrants() {
  304. if (!pending_update) {
  305. return;
  306. }
  307. if (!is_inside_tree() || !tile_set.is_valid()) {
  308. pending_update = false;
  309. return;
  310. }
  311. // Update the coords cache.
  312. for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
  313. q->self()->map_to_world.clear();
  314. q->self()->world_to_map.clear();
  315. for (Set<Vector2i>::Element *E = q->self()->cells.front(); E; E = E->next()) {
  316. Vector2i pk = E->get();
  317. Vector2i pk_world_coords = map_to_world(pk);
  318. q->self()->map_to_world[pk] = pk_world_coords;
  319. q->self()->world_to_map[pk_world_coords] = pk;
  320. }
  321. }
  322. // Call the update_dirty_quadrant method on plugins.
  323. for (int i = 0; i < tile_set->get_tile_set_atlas_plugins().size(); i++) {
  324. tile_set->get_tile_set_atlas_plugins()[i]->update_dirty_quadrants(this, dirty_quadrant_list);
  325. }
  326. // Redraw the debug canvas_items.
  327. RenderingServer *rs = RenderingServer::get_singleton();
  328. for (SelfList<TileMapQuadrant> *q = dirty_quadrant_list.first(); q; q = q->next()) {
  329. rs->canvas_item_clear(q->self()->debug_canvas_item);
  330. Transform2D xform;
  331. xform.set_origin(map_to_world(q->self()->coords * get_effective_quadrant_size()));
  332. rs->canvas_item_set_transform(q->self()->debug_canvas_item, xform);
  333. for (int i = 0; i < tile_set->get_tile_set_atlas_plugins().size(); i++) {
  334. tile_set->get_tile_set_atlas_plugins()[i]->draw_quadrant_debug(this, q->self());
  335. }
  336. }
  337. // Clear the list
  338. while (dirty_quadrant_list.first()) {
  339. dirty_quadrant_list.remove(dirty_quadrant_list.first());
  340. }
  341. pending_update = false;
  342. _recompute_rect_cache();
  343. }
  344. void TileMap::_recompute_rect_cache() {
  345. // Compute the displayed area of the tilemap.
  346. #ifdef DEBUG_ENABLED
  347. if (!rect_cache_dirty) {
  348. return;
  349. }
  350. Rect2 r_total;
  351. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  352. Rect2 r;
  353. r.position = map_to_world(E->key() * get_effective_quadrant_size());
  354. r.expand_to(map_to_world((E->key() + Vector2i(1, 0)) * get_effective_quadrant_size()));
  355. r.expand_to(map_to_world((E->key() + Vector2i(1, 1)) * get_effective_quadrant_size()));
  356. r.expand_to(map_to_world((E->key() + Vector2i(0, 1)) * get_effective_quadrant_size()));
  357. if (E == quadrant_map.front()) {
  358. r_total = r;
  359. } else {
  360. r_total = r_total.merge(r);
  361. }
  362. }
  363. rect_cache = r_total;
  364. item_rect_changed();
  365. rect_cache_dirty = false;
  366. #endif
  367. }
  368. Map<Vector2i, TileMapQuadrant>::Element *TileMap::_create_quadrant(const Vector2i &p_qk) {
  369. TileMapQuadrant q;
  370. q.coords = p_qk;
  371. rect_cache_dirty = true;
  372. // Create the debug canvas item.
  373. RenderingServer *rs = RenderingServer::get_singleton();
  374. q.debug_canvas_item = rs->canvas_item_create();
  375. rs->canvas_item_set_z_index(q.debug_canvas_item, RS::CANVAS_ITEM_Z_MAX - 1);
  376. rs->canvas_item_set_parent(q.debug_canvas_item, get_canvas_item());
  377. // Call the create_quadrant method on plugins
  378. if (tile_set.is_valid()) {
  379. for (int i = 0; i < tile_set->get_tile_set_atlas_plugins().size(); i++) {
  380. tile_set->get_tile_set_atlas_plugins()[i]->create_quadrant(this, &q);
  381. }
  382. }
  383. return quadrant_map.insert(p_qk, q);
  384. }
  385. void TileMap::_erase_quadrant(Map<Vector2i, TileMapQuadrant>::Element *Q) {
  386. // Remove a quadrant.
  387. TileMapQuadrant *q = &(Q->get());
  388. // Call the cleanup_quadrant method on plugins.
  389. if (tile_set.is_valid()) {
  390. for (int i = 0; i < tile_set->get_tile_set_atlas_plugins().size(); i++) {
  391. tile_set->get_tile_set_atlas_plugins()[i]->cleanup_quadrant(this, q);
  392. }
  393. }
  394. // Remove the quadrant from the dirty_list if it is there.
  395. if (q->dirty_list_element.in_list()) {
  396. dirty_quadrant_list.remove(&(q->dirty_list_element));
  397. }
  398. // Free the debug canvas item.
  399. RenderingServer *rs = RenderingServer::get_singleton();
  400. rs->free(q->debug_canvas_item);
  401. quadrant_map.erase(Q);
  402. rect_cache_dirty = true;
  403. }
  404. void TileMap::_make_all_quadrants_dirty(bool p_update) {
  405. // Make all quandrants dirty, then trigger an update later.
  406. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  407. if (!E->value().dirty_list_element.in_list()) {
  408. dirty_quadrant_list.add(&E->value().dirty_list_element);
  409. }
  410. }
  411. if (pending_update) {
  412. return;
  413. }
  414. pending_update = true;
  415. if (!is_inside_tree()) {
  416. return;
  417. }
  418. if (p_update) {
  419. call_deferred("update_dirty_quadrants");
  420. }
  421. }
  422. void TileMap::_make_quadrant_dirty(Map<Vector2i, TileMapQuadrant>::Element *Q, bool p_update) {
  423. // Make the given quadrant dirty, then trigger an update later.
  424. TileMapQuadrant &q = Q->get();
  425. if (!q.dirty_list_element.in_list()) {
  426. dirty_quadrant_list.add(&q.dirty_list_element);
  427. }
  428. if (pending_update) {
  429. return;
  430. }
  431. pending_update = true;
  432. if (!is_inside_tree()) {
  433. return;
  434. }
  435. if (p_update) {
  436. call_deferred("update_dirty_quadrants");
  437. }
  438. }
  439. void TileMap::set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile) {
  440. // Set the current cell tile (using integer position).
  441. Vector2i pk(p_coords);
  442. Map<Vector2i, TileMapCell>::Element *E = tile_map.find(pk);
  443. int source_id = p_source_id;
  444. Vector2i atlas_coords = p_atlas_coords;
  445. int alternative_tile = p_alternative_tile;
  446. if ((source_id == -1 || atlas_coords == TileSetAtlasSource::INVALID_ATLAS_COORDS || alternative_tile == TileSetAtlasSource::INVALID_TILE_ALTERNATIVE) &&
  447. (source_id != -1 || atlas_coords != TileSetAtlasSource::INVALID_ATLAS_COORDS || alternative_tile != TileSetAtlasSource::INVALID_TILE_ALTERNATIVE)) {
  448. WARN_PRINT("Setting a cell a cell as empty requires both source_id, atlas_coord and alternative_tile to be set to their respective \"invalid\" values. Values were thus changes accordingly.");
  449. source_id = -1;
  450. atlas_coords = TileSetAtlasSource::INVALID_ATLAS_COORDS;
  451. alternative_tile = TileSetAtlasSource::INVALID_TILE_ALTERNATIVE;
  452. }
  453. if (!E && source_id == -1) {
  454. return; // Nothing to do, the tile is already empty.
  455. }
  456. // Get the quadrant
  457. Vector2i qk = _coords_to_quadrant_coords(pk);
  458. Map<Vector2i, TileMapQuadrant>::Element *Q = quadrant_map.find(qk);
  459. if (source_id == -1) {
  460. // Erase existing cell in the tile map.
  461. tile_map.erase(pk);
  462. // Erase existing cell in the quadrant.
  463. ERR_FAIL_COND(!Q);
  464. TileMapQuadrant &q = Q->get();
  465. q.cells.erase(pk);
  466. // Remove or make the quadrant dirty.
  467. if (q.cells.size() == 0) {
  468. _erase_quadrant(Q);
  469. } else {
  470. _make_quadrant_dirty(Q);
  471. }
  472. used_size_cache_dirty = true;
  473. } else {
  474. if (!E) {
  475. // Insert a new cell in the tile map.
  476. E = tile_map.insert(pk, TileMapCell());
  477. // Create a new quadrant if needed, then insert the cell if needed.
  478. if (!Q) {
  479. Q = _create_quadrant(qk);
  480. }
  481. TileMapQuadrant &q = Q->get();
  482. q.cells.insert(pk);
  483. } else {
  484. ERR_FAIL_COND(!Q); // TileMapQuadrant should exist...
  485. if (E->get().source_id == source_id && E->get().get_atlas_coords() == atlas_coords && E->get().alternative_tile == alternative_tile) {
  486. return; // Nothing changed.
  487. }
  488. }
  489. TileMapCell &c = E->get();
  490. c.source_id = source_id;
  491. c.set_atlas_coords(atlas_coords);
  492. c.alternative_tile = alternative_tile;
  493. _make_quadrant_dirty(Q);
  494. used_size_cache_dirty = true;
  495. }
  496. }
  497. int TileMap::get_cell_source_id(const Vector2i &p_coords) const {
  498. // Get a cell source id from position
  499. const Map<Vector2i, TileMapCell>::Element *E = tile_map.find(p_coords);
  500. if (!E) {
  501. return -1;
  502. }
  503. return E->get().source_id;
  504. }
  505. Vector2i TileMap::get_cell_atlas_coords(const Vector2i &p_coords) const {
  506. // Get a cell source id from position
  507. const Map<Vector2i, TileMapCell>::Element *E = tile_map.find(p_coords);
  508. if (!E) {
  509. return TileSetAtlasSource::INVALID_ATLAS_COORDS;
  510. }
  511. return E->get().get_atlas_coords();
  512. }
  513. int TileMap::get_cell_alternative_tile(const Vector2i &p_coords) const {
  514. // Get a cell source id from position
  515. const Map<Vector2i, TileMapCell>::Element *E = tile_map.find(p_coords);
  516. if (!E) {
  517. return TileSetAtlasSource::INVALID_TILE_ALTERNATIVE;
  518. }
  519. return E->get().alternative_tile;
  520. }
  521. TileMapPattern *TileMap::get_pattern(TypedArray<Vector2i> p_coords_array) {
  522. ERR_FAIL_COND_V(!tile_set.is_valid(), nullptr);
  523. TileMapPattern *output = memnew(TileMapPattern);
  524. if (p_coords_array.is_empty()) {
  525. return output;
  526. }
  527. Vector2i min = Vector2i(p_coords_array[0]);
  528. for (int i = 1; i < p_coords_array.size(); i++) {
  529. min = min.min(p_coords_array[i]);
  530. }
  531. Vector<Vector2i> coords_in_pattern_array;
  532. coords_in_pattern_array.resize(p_coords_array.size());
  533. Vector2i ensure_positive_offset;
  534. for (int i = 0; i < p_coords_array.size(); i++) {
  535. Vector2i coords = p_coords_array[i];
  536. Vector2i coords_in_pattern = coords - min;
  537. if (tile_set->get_tile_shape() != TileSet::TILE_SHAPE_SQUARE) {
  538. if (tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_STACKED) {
  539. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(min.y % 2) && bool(coords_in_pattern.y % 2)) {
  540. coords_in_pattern.x -= 1;
  541. if (coords_in_pattern.x < 0) {
  542. ensure_positive_offset.x = 1;
  543. }
  544. } else if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(min.x % 2) && bool(coords_in_pattern.x % 2)) {
  545. coords_in_pattern.y -= 1;
  546. if (coords_in_pattern.y < 0) {
  547. ensure_positive_offset.y = 1;
  548. }
  549. }
  550. } else if (tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_STACKED_OFFSET) {
  551. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(min.y % 2) && bool(coords_in_pattern.y % 2)) {
  552. coords_in_pattern.x += 1;
  553. } else if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(min.x % 2) && bool(coords_in_pattern.x % 2)) {
  554. coords_in_pattern.y += 1;
  555. }
  556. }
  557. }
  558. coords_in_pattern_array.write[i] = coords_in_pattern;
  559. }
  560. for (int i = 0; i < coords_in_pattern_array.size(); i++) {
  561. Vector2i coords = p_coords_array[i];
  562. Vector2i coords_in_pattern = coords_in_pattern_array[i];
  563. output->set_cell(coords_in_pattern + ensure_positive_offset, get_cell_source_id(coords), get_cell_atlas_coords(coords), get_cell_alternative_tile(coords));
  564. }
  565. return output;
  566. }
  567. Vector2i TileMap::map_pattern(Vector2i p_position_in_tilemap, Vector2i p_coords_in_pattern, const TileMapPattern *p_pattern) {
  568. ERR_FAIL_COND_V(!p_pattern->has_cell(p_coords_in_pattern), Vector2i());
  569. Vector2i output = p_position_in_tilemap + p_coords_in_pattern;
  570. if (tile_set->get_tile_shape() != TileSet::TILE_SHAPE_SQUARE) {
  571. if (tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_STACKED) {
  572. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(p_position_in_tilemap.y % 2) && bool(p_coords_in_pattern.y % 2)) {
  573. output.x += 1;
  574. } else if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(p_position_in_tilemap.x % 2) && bool(p_coords_in_pattern.x % 2)) {
  575. output.y += 1;
  576. }
  577. } else if (tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_STACKED_OFFSET) {
  578. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(p_position_in_tilemap.y % 2) && bool(p_coords_in_pattern.y % 2)) {
  579. output.x -= 1;
  580. } else if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(p_position_in_tilemap.x % 2) && bool(p_coords_in_pattern.x % 2)) {
  581. output.y -= 1;
  582. }
  583. }
  584. }
  585. return output;
  586. }
  587. void TileMap::set_pattern(Vector2i p_position, const TileMapPattern *p_pattern) {
  588. ERR_FAIL_COND(!tile_set.is_valid());
  589. TypedArray<Vector2i> used_cells = p_pattern->get_used_cells();
  590. for (int i = 0; i < used_cells.size(); i++) {
  591. Vector2i coords = map_pattern(p_position, used_cells[i], p_pattern);
  592. set_cell(coords, p_pattern->get_cell_source_id(coords), p_pattern->get_cell_atlas_coords(coords), p_pattern->get_cell_alternative_tile(coords));
  593. }
  594. }
  595. TileMapCell TileMap::get_cell(const Vector2i &p_coords) const {
  596. if (!tile_map.has(p_coords)) {
  597. return TileMapCell();
  598. } else {
  599. return tile_map.find(p_coords)->get();
  600. }
  601. }
  602. Map<Vector2i, TileMapQuadrant> &TileMap::get_quadrant_map() {
  603. return quadrant_map;
  604. }
  605. void TileMap::fix_invalid_tiles() {
  606. ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot fix invalid tiles if Tileset is not open.");
  607. for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
  608. TileSetSource *source = *tile_set->get_source(E->get().source_id);
  609. if (!source || !source->has_tile(E->get().get_atlas_coords()) || !source->has_alternative_tile(E->get().get_atlas_coords(), E->get().alternative_tile)) {
  610. set_cell(E->key(), -1, TileSetAtlasSource::INVALID_ATLAS_COORDS, TileSetAtlasSource::INVALID_TILE_ALTERNATIVE);
  611. }
  612. }
  613. }
  614. void TileMap::_recreate_quadrants() {
  615. // Clear then recreate all quadrants.
  616. _clear_quadrants();
  617. for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
  618. Vector2i qk = _coords_to_quadrant_coords(Vector2i(E->key().x, E->key().y));
  619. Map<Vector2i, TileMapQuadrant>::Element *Q = quadrant_map.find(qk);
  620. if (!Q) {
  621. Q = _create_quadrant(qk);
  622. dirty_quadrant_list.add(&Q->get().dirty_list_element);
  623. }
  624. Vector2i pk = E->key();
  625. Q->get().cells.insert(pk);
  626. _make_quadrant_dirty(Q, false);
  627. }
  628. update_dirty_quadrants();
  629. }
  630. void TileMap::_clear_quadrants() {
  631. // Clear quadrants.
  632. while (quadrant_map.size()) {
  633. _erase_quadrant(quadrant_map.front());
  634. }
  635. // Clear the dirty quadrants list.
  636. while (dirty_quadrant_list.first()) {
  637. dirty_quadrant_list.remove(dirty_quadrant_list.first());
  638. }
  639. }
  640. void TileMap::clear() {
  641. // Remove all tiles.
  642. _clear_quadrants();
  643. tile_map.clear();
  644. used_size_cache_dirty = true;
  645. }
  646. void TileMap::_set_tile_data(const Vector<int> &p_data) {
  647. // Set data for a given tile from raw data.
  648. ERR_FAIL_COND(format > FORMAT_3);
  649. int c = p_data.size();
  650. const int *r = p_data.ptr();
  651. int offset = (format >= FORMAT_2) ? 3 : 2;
  652. clear();
  653. for (int i = 0; i < c; i += offset) {
  654. const uint8_t *ptr = (const uint8_t *)&r[i];
  655. uint8_t local[12];
  656. for (int j = 0; j < ((format >= FORMAT_2) ? 12 : 8); j++) {
  657. local[j] = ptr[j];
  658. }
  659. #ifdef BIG_ENDIAN_ENABLED
  660. SWAP(local[0], local[3]);
  661. SWAP(local[1], local[2]);
  662. SWAP(local[4], local[7]);
  663. SWAP(local[5], local[6]);
  664. //TODO: ask someone to check this...
  665. if (FORMAT >= FORMAT_2) {
  666. SWAP(local[8], local[11]);
  667. SWAP(local[9], local[10]);
  668. }
  669. #endif
  670. int16_t x = decode_uint16(&local[0]);
  671. int16_t y = decode_uint16(&local[2]);
  672. if (format == FORMAT_3) {
  673. uint16_t source_id = decode_uint16(&local[4]);
  674. uint16_t atlas_coords_x = decode_uint16(&local[6]);
  675. uint16_t atlas_coords_y = decode_uint32(&local[8]);
  676. uint16_t alternative_tile = decode_uint16(&local[10]);
  677. set_cell(Vector2i(x, y), source_id, Vector2i(atlas_coords_x, atlas_coords_y), alternative_tile);
  678. } else {
  679. uint32_t v = decode_uint32(&local[4]);
  680. v &= (1 << 29) - 1;
  681. // We generate an alternative tile number out of the the flags
  682. // An option should create the alternative in the tileset for compatibility
  683. bool flip_h = v & (1 << 29);
  684. bool flip_v = v & (1 << 30);
  685. bool transpose = v & (1 << 31);
  686. int16_t coord_x = 0;
  687. int16_t coord_y = 0;
  688. if (format == FORMAT_2) {
  689. coord_x = decode_uint16(&local[8]);
  690. coord_y = decode_uint16(&local[10]);
  691. }
  692. int compatibility_alternative_tile = ((int)flip_h) + ((int)flip_v << 1) + ((int)transpose << 2);
  693. if (tile_set.is_valid()) {
  694. v = tile_set->compatibility_get_source_for_tile_id(v);
  695. }
  696. set_cell(Vector2i(x, y), v, Vector2i(coord_x, coord_y), compatibility_alternative_tile);
  697. }
  698. }
  699. }
  700. Vector<int> TileMap::_get_tile_data() const {
  701. // Export tile data to raw format
  702. Vector<int> data;
  703. data.resize(tile_map.size() * 3);
  704. int *w = data.ptrw();
  705. // Save in highest format
  706. int idx = 0;
  707. for (const Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
  708. uint8_t *ptr = (uint8_t *)&w[idx];
  709. encode_uint16((int16_t)(E->key().x), &ptr[0]);
  710. encode_uint16((int16_t)(E->key().y), &ptr[2]);
  711. encode_uint16(E->get().source_id, &ptr[4]);
  712. encode_uint16(E->get().coord_x, &ptr[6]);
  713. encode_uint16(E->get().coord_y, &ptr[8]);
  714. encode_uint16(E->get().alternative_tile, &ptr[10]);
  715. idx += 3;
  716. }
  717. return data;
  718. }
  719. #ifdef TOOLS_ENABLED
  720. Rect2 TileMap::_edit_get_rect() const {
  721. // Return the visible rect of the tilemap
  722. if (pending_update) {
  723. const_cast<TileMap *>(this)->update_dirty_quadrants();
  724. } else {
  725. const_cast<TileMap *>(this)->_recompute_rect_cache();
  726. }
  727. return rect_cache;
  728. }
  729. #endif
  730. bool TileMap::_set(const StringName &p_name, const Variant &p_value) {
  731. if (p_name == "format") {
  732. if (p_value.get_type() == Variant::INT) {
  733. format = (DataFormat)(p_value.operator int64_t()); // Set format used for loading
  734. return true;
  735. }
  736. } else if (p_name == "tile_data") {
  737. if (p_value.is_array()) {
  738. _set_tile_data(p_value);
  739. return true;
  740. }
  741. return false;
  742. }
  743. return false;
  744. }
  745. bool TileMap::_get(const StringName &p_name, Variant &r_ret) const {
  746. if (p_name == "format") {
  747. r_ret = FORMAT_3; // When saving, always save highest format
  748. return true;
  749. } else if (p_name == "tile_data") {
  750. r_ret = _get_tile_data();
  751. return true;
  752. }
  753. return false;
  754. }
  755. void TileMap::_get_property_list(List<PropertyInfo> *p_list) const {
  756. PropertyInfo p(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL);
  757. p_list->push_back(p);
  758. p = PropertyInfo(Variant::OBJECT, "tile_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL);
  759. p_list->push_back(p);
  760. }
  761. Vector2 TileMap::map_to_world(const Vector2i &p_pos) const {
  762. // SHOULD RETURN THE CENTER OF THE TILE
  763. ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2());
  764. Vector2 ret = p_pos;
  765. TileSet::TileShape tile_shape = tile_set->get_tile_shape();
  766. TileSet::TileOffsetAxis tile_offset_axis = tile_set->get_tile_offset_axis();
  767. if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  768. // Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap.
  769. // square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap
  770. if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  771. switch (tile_set->get_tile_layout()) {
  772. case TileSet::TILE_LAYOUT_STACKED:
  773. ret = Vector2(ret.x + (Math::posmod(ret.y, 2) == 0 ? 0.0 : 0.5), ret.y);
  774. break;
  775. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  776. ret = Vector2(ret.x + (Math::posmod(ret.y, 2) == 1 ? 0.0 : 0.5), ret.y);
  777. break;
  778. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  779. ret = Vector2(ret.x + ret.y / 2, ret.y);
  780. break;
  781. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  782. ret = Vector2(ret.x / 2, ret.y * 2 + ret.x);
  783. break;
  784. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  785. ret = Vector2((ret.x + ret.y) / 2, ret.y - ret.x);
  786. break;
  787. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  788. ret = Vector2((ret.x - ret.y) / 2, ret.y + ret.x);
  789. break;
  790. }
  791. } else { // TILE_OFFSET_AXIS_VERTICAL
  792. switch (tile_set->get_tile_layout()) {
  793. case TileSet::TILE_LAYOUT_STACKED:
  794. ret = Vector2(ret.x, ret.y + (Math::posmod(ret.x, 2) == 0 ? 0.0 : 0.5));
  795. break;
  796. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  797. ret = Vector2(ret.x, ret.y + (Math::posmod(ret.x, 2) == 1 ? 0.0 : 0.5));
  798. break;
  799. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  800. ret = Vector2(ret.x * 2 + ret.y, ret.y / 2);
  801. break;
  802. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  803. ret = Vector2(ret.x, ret.y + ret.x / 2);
  804. break;
  805. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  806. ret = Vector2(ret.x + ret.y, (ret.y - ret.x) / 2);
  807. break;
  808. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  809. ret = Vector2(ret.x - ret.y, (ret.y + ret.x) / 2);
  810. break;
  811. }
  812. }
  813. }
  814. // Multiply by the overlapping ratio
  815. double overlapping_ratio = 1.0;
  816. if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  817. if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  818. overlapping_ratio = 0.5;
  819. } else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
  820. overlapping_ratio = 0.75;
  821. }
  822. ret.y *= overlapping_ratio;
  823. } else { // TILE_OFFSET_AXIS_VERTICAL
  824. if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  825. overlapping_ratio = 0.5;
  826. } else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
  827. overlapping_ratio = 0.75;
  828. }
  829. ret.x *= overlapping_ratio;
  830. }
  831. return (ret + Vector2(0.5, 0.5)) * tile_set->get_tile_size();
  832. }
  833. Vector2i TileMap::world_to_map(const Vector2 &p_pos) const {
  834. ERR_FAIL_COND_V(!tile_set.is_valid(), Vector2i());
  835. Vector2 ret = p_pos;
  836. ret /= tile_set->get_tile_size();
  837. TileSet::TileShape tile_shape = tile_set->get_tile_shape();
  838. TileSet::TileOffsetAxis tile_offset_axis = tile_set->get_tile_offset_axis();
  839. TileSet::TileLayout tile_layout = tile_set->get_tile_layout();
  840. // Divide by the overlapping ratio
  841. double overlapping_ratio = 1.0;
  842. if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  843. if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  844. overlapping_ratio = 0.5;
  845. } else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
  846. overlapping_ratio = 0.75;
  847. }
  848. ret.y /= overlapping_ratio;
  849. } else { // TILE_OFFSET_AXIS_VERTICAL
  850. if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  851. overlapping_ratio = 0.5;
  852. } else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
  853. overlapping_ratio = 0.75;
  854. }
  855. ret.x /= overlapping_ratio;
  856. }
  857. // For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the world position accordingly.
  858. if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  859. // Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap.
  860. // square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap
  861. if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  862. // Smart floor of the position
  863. Vector2 raw_pos = ret;
  864. if (Math::posmod(Math::floor(ret.y), 2) ^ (tile_layout == TileSet::TILE_LAYOUT_STACKED_OFFSET)) {
  865. ret = Vector2(Math::floor(ret.x + 0.5) - 0.5, Math::floor(ret.y));
  866. } else {
  867. ret = ret.floor();
  868. }
  869. // Compute the tile offset, and if we might the output for a neighbour top tile
  870. Vector2 in_tile_pos = raw_pos - ret;
  871. bool in_top_left_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(-0.5, 1.0 / overlapping_ratio - 1)) <= 0;
  872. bool in_top_right_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(0.5, 1.0 / overlapping_ratio - 1)) > 0;
  873. switch (tile_layout) {
  874. case TileSet::TILE_LAYOUT_STACKED:
  875. ret = ret.floor();
  876. if (in_top_left_triangle) {
  877. ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 0 : -1, -1);
  878. } else if (in_top_right_triangle) {
  879. ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 1 : 0, -1);
  880. }
  881. break;
  882. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  883. ret = ret.floor();
  884. if (in_top_left_triangle) {
  885. ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? -1 : 0, -1);
  886. } else if (in_top_right_triangle) {
  887. ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 0 : 1, -1);
  888. }
  889. break;
  890. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  891. ret = Vector2(ret.x - ret.y / 2, ret.y).floor();
  892. if (in_top_left_triangle) {
  893. ret += Vector2i(0, -1);
  894. } else if (in_top_right_triangle) {
  895. ret += Vector2i(1, -1);
  896. }
  897. break;
  898. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  899. ret = Vector2(ret.x * 2, ret.y / 2 - ret.x).floor();
  900. if (in_top_left_triangle) {
  901. ret += Vector2i(-1, 0);
  902. } else if (in_top_right_triangle) {
  903. ret += Vector2i(1, -1);
  904. }
  905. break;
  906. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  907. ret = Vector2(ret.x - ret.y / 2, ret.y / 2 + ret.x).floor();
  908. if (in_top_left_triangle) {
  909. ret += Vector2i(0, -1);
  910. } else if (in_top_right_triangle) {
  911. ret += Vector2i(1, 0);
  912. }
  913. break;
  914. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  915. ret = Vector2(ret.x + ret.y / 2, ret.y / 2 - ret.x).floor();
  916. if (in_top_left_triangle) {
  917. ret += Vector2i(-1, 0);
  918. } else if (in_top_right_triangle) {
  919. ret += Vector2i(0, -1);
  920. }
  921. break;
  922. }
  923. } else { // TILE_OFFSET_AXIS_VERTICAL
  924. // Smart floor of the position
  925. Vector2 raw_pos = ret;
  926. if (Math::posmod(Math::floor(ret.x), 2) ^ (tile_layout == TileSet::TILE_LAYOUT_STACKED_OFFSET)) {
  927. ret = Vector2(Math::floor(ret.x), Math::floor(ret.y + 0.5) - 0.5);
  928. } else {
  929. ret = ret.floor();
  930. }
  931. // Compute the tile offset, and if we might the output for a neighbour top tile
  932. Vector2 in_tile_pos = raw_pos - ret;
  933. bool in_top_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, -0.5)) > 0;
  934. bool in_bottom_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, 0.5)) <= 0;
  935. switch (tile_layout) {
  936. case TileSet::TILE_LAYOUT_STACKED:
  937. ret = ret.floor();
  938. if (in_top_left_triangle) {
  939. ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 0 : -1);
  940. } else if (in_bottom_left_triangle) {
  941. ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 1 : 0);
  942. }
  943. break;
  944. case TileSet::TILE_LAYOUT_STACKED_OFFSET:
  945. ret = ret.floor();
  946. if (in_top_left_triangle) {
  947. ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? -1 : 0);
  948. } else if (in_bottom_left_triangle) {
  949. ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 0 : 1);
  950. }
  951. break;
  952. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  953. ret = Vector2(ret.x / 2 - ret.y, ret.y * 2).floor();
  954. if (in_top_left_triangle) {
  955. ret += Vector2i(0, -1);
  956. } else if (in_bottom_left_triangle) {
  957. ret += Vector2i(-1, 1);
  958. }
  959. break;
  960. case TileSet::TILE_LAYOUT_STAIRS_DOWN:
  961. ret = Vector2(ret.x, ret.y - ret.x / 2).floor();
  962. if (in_top_left_triangle) {
  963. ret += Vector2i(-1, 0);
  964. } else if (in_bottom_left_triangle) {
  965. ret += Vector2i(-1, 1);
  966. }
  967. break;
  968. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  969. ret = Vector2(ret.x / 2 - ret.y, ret.y + ret.x / 2).floor();
  970. if (in_top_left_triangle) {
  971. ret += Vector2i(0, -1);
  972. } else if (in_bottom_left_triangle) {
  973. ret += Vector2i(-1, 0);
  974. }
  975. break;
  976. case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
  977. ret = Vector2(ret.x / 2 + ret.y, ret.y - ret.x / 2).floor();
  978. if (in_top_left_triangle) {
  979. ret += Vector2i(-1, 0);
  980. } else if (in_bottom_left_triangle) {
  981. ret += Vector2i(0, 1);
  982. }
  983. break;
  984. }
  985. }
  986. } else {
  987. ret = (ret + Vector2(0.00005, 0.00005)).floor();
  988. }
  989. return Vector2i(ret);
  990. }
  991. bool TileMap::is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const {
  992. ERR_FAIL_COND_V(!tile_set.is_valid(), false);
  993. TileSet::TileShape shape = tile_set->get_tile_shape();
  994. if (shape == TileSet::TILE_SHAPE_SQUARE) {
  995. return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE ||
  996. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER ||
  997. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE ||
  998. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER ||
  999. p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE ||
  1000. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER ||
  1001. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE ||
  1002. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER;
  1003. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  1004. return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER ||
  1005. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
  1006. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER ||
  1007. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
  1008. p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER ||
  1009. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
  1010. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER ||
  1011. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1012. } else {
  1013. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1014. return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE ||
  1015. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
  1016. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
  1017. p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE ||
  1018. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
  1019. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1020. } else {
  1021. return p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
  1022. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE ||
  1023. p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
  1024. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
  1025. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE ||
  1026. p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
  1027. }
  1028. }
  1029. }
  1030. Vector2i TileMap::get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const {
  1031. ERR_FAIL_COND_V(!tile_set.is_valid(), p_coords);
  1032. TileSet::TileShape shape = tile_set->get_tile_shape();
  1033. if (shape == TileSet::TILE_SHAPE_SQUARE) {
  1034. switch (p_cell_neighbor) {
  1035. case TileSet::CELL_NEIGHBOR_RIGHT_SIDE:
  1036. return p_coords + Vector2i(1, 0);
  1037. case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
  1038. return p_coords + Vector2i(1, 1);
  1039. case TileSet::CELL_NEIGHBOR_BOTTOM_SIDE:
  1040. return p_coords + Vector2i(0, 1);
  1041. case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
  1042. return p_coords + Vector2i(-1, 1);
  1043. case TileSet::CELL_NEIGHBOR_LEFT_SIDE:
  1044. return p_coords + Vector2i(-1, 0);
  1045. case TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER:
  1046. return p_coords + Vector2i(-1, -1);
  1047. case TileSet::CELL_NEIGHBOR_TOP_SIDE:
  1048. return p_coords + Vector2i(0, -1);
  1049. case TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER:
  1050. return p_coords + Vector2i(1, -1);
  1051. default:
  1052. ERR_FAIL_V(p_coords);
  1053. }
  1054. } else { // Half-offset shapes (square and hexagon)
  1055. switch (tile_set->get_tile_layout()) {
  1056. case TileSet::TILE_LAYOUT_STACKED: {
  1057. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1058. bool is_offset = p_coords.y % 2;
  1059. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1060. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1061. return p_coords + Vector2i(1, 0);
  1062. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1063. return p_coords + Vector2i(is_offset ? 1 : 0, 1);
  1064. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1065. return p_coords + Vector2i(0, 2);
  1066. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1067. return p_coords + Vector2i(is_offset ? 0 : -1, 1);
  1068. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1069. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1070. return p_coords + Vector2i(-1, 0);
  1071. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1072. return p_coords + Vector2i(is_offset ? 0 : -1, -1);
  1073. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1074. return p_coords + Vector2i(0, -2);
  1075. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1076. return p_coords + Vector2i(is_offset ? 1 : 0, -1);
  1077. } else {
  1078. ERR_FAIL_V(p_coords);
  1079. }
  1080. } else {
  1081. bool is_offset = p_coords.x % 2;
  1082. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1083. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1084. return p_coords + Vector2i(0, 1);
  1085. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1086. return p_coords + Vector2i(1, is_offset ? 1 : 0);
  1087. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1088. return p_coords + Vector2i(2, 0);
  1089. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1090. return p_coords + Vector2i(1, is_offset ? 0 : -1);
  1091. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1092. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1093. return p_coords + Vector2i(0, -1);
  1094. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1095. return p_coords + Vector2i(-1, is_offset ? 0 : -1);
  1096. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1097. return p_coords + Vector2i(-2, 0);
  1098. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1099. return p_coords + Vector2i(-1, is_offset ? 1 : 0);
  1100. } else {
  1101. ERR_FAIL_V(p_coords);
  1102. }
  1103. }
  1104. } break;
  1105. case TileSet::TILE_LAYOUT_STACKED_OFFSET: {
  1106. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1107. bool is_offset = p_coords.y % 2;
  1108. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1109. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1110. return p_coords + Vector2i(1, 0);
  1111. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1112. return p_coords + Vector2i(is_offset ? 0 : 1, 1);
  1113. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1114. return p_coords + Vector2i(0, 2);
  1115. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1116. return p_coords + Vector2i(is_offset ? -1 : 0, 1);
  1117. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1118. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1119. return p_coords + Vector2i(-1, 0);
  1120. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1121. return p_coords + Vector2i(is_offset ? -1 : 0, -1);
  1122. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1123. return p_coords + Vector2i(0, -2);
  1124. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1125. return p_coords + Vector2i(is_offset ? 0 : 1, -1);
  1126. } else {
  1127. ERR_FAIL_V(p_coords);
  1128. }
  1129. } else {
  1130. bool is_offset = p_coords.x % 2;
  1131. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1132. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1133. return p_coords + Vector2i(0, 1);
  1134. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1135. return p_coords + Vector2i(1, is_offset ? 0 : 1);
  1136. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1137. return p_coords + Vector2i(2, 0);
  1138. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1139. return p_coords + Vector2i(1, is_offset ? -1 : 0);
  1140. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1141. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1142. return p_coords + Vector2i(0, -1);
  1143. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1144. return p_coords + Vector2i(-1, is_offset ? -1 : 0);
  1145. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1146. return p_coords + Vector2i(-2, 0);
  1147. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1148. return p_coords + Vector2i(-1, is_offset ? 0 : 1);
  1149. } else {
  1150. ERR_FAIL_V(p_coords);
  1151. }
  1152. }
  1153. } break;
  1154. case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
  1155. case TileSet::TILE_LAYOUT_STAIRS_DOWN: {
  1156. if ((tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  1157. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1158. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1159. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1160. return p_coords + Vector2i(1, 0);
  1161. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1162. return p_coords + Vector2i(0, 1);
  1163. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1164. return p_coords + Vector2i(-1, 2);
  1165. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1166. return p_coords + Vector2i(-1, 1);
  1167. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1168. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1169. return p_coords + Vector2i(-1, 0);
  1170. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1171. return p_coords + Vector2i(0, -1);
  1172. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1173. return p_coords + Vector2i(1, -2);
  1174. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1175. return p_coords + Vector2i(1, -1);
  1176. } else {
  1177. ERR_FAIL_V(p_coords);
  1178. }
  1179. } else {
  1180. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1181. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1182. return p_coords + Vector2i(0, 1);
  1183. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1184. return p_coords + Vector2i(1, 0);
  1185. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1186. return p_coords + Vector2i(2, -1);
  1187. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1188. return p_coords + Vector2i(1, -1);
  1189. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1190. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1191. return p_coords + Vector2i(0, -1);
  1192. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1193. return p_coords + Vector2i(-1, 0);
  1194. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1195. return p_coords + Vector2i(-2, 1);
  1196. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1197. return p_coords + Vector2i(-1, 1);
  1198. } else {
  1199. ERR_FAIL_V(p_coords);
  1200. }
  1201. }
  1202. } else {
  1203. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1204. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1205. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1206. return p_coords + Vector2i(2, -1);
  1207. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1208. return p_coords + Vector2i(1, 0);
  1209. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1210. return p_coords + Vector2i(0, 1);
  1211. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1212. return p_coords + Vector2i(-1, 1);
  1213. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1214. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1215. return p_coords + Vector2i(-2, 1);
  1216. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1217. return p_coords + Vector2i(-1, 0);
  1218. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1219. return p_coords + Vector2i(0, -1);
  1220. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1221. return p_coords + Vector2i(1, -1);
  1222. } else {
  1223. ERR_FAIL_V(p_coords);
  1224. }
  1225. } else {
  1226. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1227. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1228. return p_coords + Vector2i(-1, 2);
  1229. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1230. return p_coords + Vector2i(0, 1);
  1231. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1232. return p_coords + Vector2i(1, 0);
  1233. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1234. return p_coords + Vector2i(1, -1);
  1235. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1236. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1237. return p_coords + Vector2i(1, -2);
  1238. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1239. return p_coords + Vector2i(0, -1);
  1240. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1241. return p_coords + Vector2i(-1, 0);
  1242. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1243. return p_coords + Vector2i(-1, 1);
  1244. } else {
  1245. ERR_FAIL_V(p_coords);
  1246. }
  1247. }
  1248. }
  1249. } break;
  1250. case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
  1251. case TileSet::TILE_LAYOUT_DIAMOND_DOWN: {
  1252. if ((tile_set->get_tile_layout() == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
  1253. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1254. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1255. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1256. return p_coords + Vector2i(1, 1);
  1257. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1258. return p_coords + Vector2i(0, 1);
  1259. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1260. return p_coords + Vector2i(-1, 1);
  1261. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1262. return p_coords + Vector2i(-1, 0);
  1263. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1264. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1265. return p_coords + Vector2i(-1, -1);
  1266. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1267. return p_coords + Vector2i(0, -1);
  1268. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1269. return p_coords + Vector2i(1, -1);
  1270. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1271. return p_coords + Vector2i(1, 0);
  1272. } else {
  1273. ERR_FAIL_V(p_coords);
  1274. }
  1275. } else {
  1276. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1277. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1278. return p_coords + Vector2i(1, 1);
  1279. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1280. return p_coords + Vector2i(1, 0);
  1281. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1282. return p_coords + Vector2i(1, -1);
  1283. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1284. return p_coords + Vector2i(0, -1);
  1285. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1286. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1287. return p_coords + Vector2i(-1, -1);
  1288. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1289. return p_coords + Vector2i(-1, 0);
  1290. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1291. return p_coords + Vector2i(-1, 1);
  1292. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1293. return p_coords + Vector2i(0, 1);
  1294. } else {
  1295. ERR_FAIL_V(p_coords);
  1296. }
  1297. }
  1298. } else {
  1299. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1300. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
  1301. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
  1302. return p_coords + Vector2i(1, -1);
  1303. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1304. return p_coords + Vector2i(1, 0);
  1305. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
  1306. return p_coords + Vector2i(1, 1);
  1307. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1308. return p_coords + Vector2i(0, 1);
  1309. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
  1310. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
  1311. return p_coords + Vector2i(-1, 1);
  1312. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1313. return p_coords + Vector2i(-1, 0);
  1314. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
  1315. return p_coords + Vector2i(-1, -1);
  1316. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1317. return p_coords + Vector2i(0, -1);
  1318. } else {
  1319. ERR_FAIL_V(p_coords);
  1320. }
  1321. } else {
  1322. if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
  1323. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
  1324. return p_coords + Vector2i(-1, 1);
  1325. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
  1326. return p_coords + Vector2i(0, 1);
  1327. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
  1328. return p_coords + Vector2i(1, 1);
  1329. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
  1330. return p_coords + Vector2i(1, 0);
  1331. } else if ((shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
  1332. (shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
  1333. return p_coords + Vector2i(1, -1);
  1334. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
  1335. return p_coords + Vector2i(0, -1);
  1336. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
  1337. return p_coords + Vector2i(-1, -1);
  1338. } else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
  1339. return p_coords + Vector2i(-1, 0);
  1340. } else {
  1341. ERR_FAIL_V(p_coords);
  1342. }
  1343. }
  1344. }
  1345. } break;
  1346. default:
  1347. ERR_FAIL_V(p_coords);
  1348. }
  1349. }
  1350. }
  1351. TypedArray<Vector2i> TileMap::get_used_cells() const {
  1352. // Returns the cells used in the tilemap.
  1353. TypedArray<Vector2i> a;
  1354. a.resize(tile_map.size());
  1355. int i = 0;
  1356. for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
  1357. Vector2i p(E->key().x, E->key().y);
  1358. a[i++] = p;
  1359. }
  1360. return a;
  1361. }
  1362. Rect2 TileMap::get_used_rect() { // Not const because of cache
  1363. // Return the rect of the currently used area
  1364. if (used_size_cache_dirty) {
  1365. if (tile_map.size() > 0) {
  1366. used_size_cache = Rect2(tile_map.front()->key().x, tile_map.front()->key().y, 0, 0);
  1367. for (Map<Vector2i, TileMapCell>::Element *E = tile_map.front(); E; E = E->next()) {
  1368. used_size_cache.expand_to(Vector2(E->key().x, E->key().y));
  1369. }
  1370. used_size_cache.size += Vector2(1, 1);
  1371. } else {
  1372. used_size_cache = Rect2();
  1373. }
  1374. used_size_cache_dirty = false;
  1375. }
  1376. return used_size_cache;
  1377. }
  1378. // --- Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems ---
  1379. void TileMap::set_light_mask(int p_light_mask) {
  1380. // Occlusion: set light mask.
  1381. CanvasItem::set_light_mask(p_light_mask);
  1382. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1383. for (List<RID>::Element *F = E->get().canvas_items.front(); F; F = F->next()) {
  1384. RenderingServer::get_singleton()->canvas_item_set_light_mask(F->get(), get_light_mask());
  1385. }
  1386. }
  1387. }
  1388. void TileMap::set_material(const Ref<Material> &p_material) {
  1389. // Set material for the whole tilemap.
  1390. CanvasItem::set_material(p_material);
  1391. // Update material for the whole tilemap.
  1392. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1393. TileMapQuadrant &q = E->get();
  1394. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  1395. RS::get_singleton()->canvas_item_set_use_parent_material(F->get(), get_use_parent_material() || get_material().is_valid());
  1396. }
  1397. }
  1398. }
  1399. void TileMap::set_use_parent_material(bool p_use_parent_material) {
  1400. // Set use_parent_material for the whole tilemap.
  1401. CanvasItem::set_use_parent_material(p_use_parent_material);
  1402. // Update use_parent_material for the whole tilemap.
  1403. for (Map<Vector2i, TileMapQuadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
  1404. TileMapQuadrant &q = E->get();
  1405. for (List<RID>::Element *F = q.canvas_items.front(); F; F = F->next()) {
  1406. RS::get_singleton()->canvas_item_set_use_parent_material(F->get(), get_use_parent_material() || get_material().is_valid());
  1407. }
  1408. }
  1409. }
  1410. void TileMap::set_texture_filter(TextureFilter p_texture_filter) {
  1411. // Set a default texture filter for the whole tilemap
  1412. CanvasItem::set_texture_filter(p_texture_filter);
  1413. for (Map<Vector2i, TileMapQuadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
  1414. TileMapQuadrant &q = F->get();
  1415. for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
  1416. RenderingServer::get_singleton()->canvas_item_set_default_texture_filter(E->get(), RS::CanvasItemTextureFilter(p_texture_filter));
  1417. _make_quadrant_dirty(F);
  1418. }
  1419. }
  1420. }
  1421. void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
  1422. // Set a default texture repeat for the whole tilemap
  1423. CanvasItem::set_texture_repeat(p_texture_repeat);
  1424. for (Map<Vector2i, TileMapQuadrant>::Element *F = quadrant_map.front(); F; F = F->next()) {
  1425. TileMapQuadrant &q = F->get();
  1426. for (List<RID>::Element *E = q.canvas_items.front(); E; E = E->next()) {
  1427. RenderingServer::get_singleton()->canvas_item_set_default_texture_repeat(E->get(), RS::CanvasItemTextureRepeat(p_texture_repeat));
  1428. _make_quadrant_dirty(F);
  1429. }
  1430. }
  1431. }
  1432. TypedArray<Vector2i> TileMap::get_surrounding_tiles(Vector2i coords) {
  1433. if (!tile_set.is_valid()) {
  1434. return TypedArray<Vector2i>();
  1435. }
  1436. TypedArray<Vector2i> around;
  1437. TileSet::TileShape shape = tile_set->get_tile_shape();
  1438. if (shape == TileSet::TILE_SHAPE_SQUARE) {
  1439. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE));
  1440. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE));
  1441. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE));
  1442. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_SIDE));
  1443. } else if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
  1444. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE));
  1445. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE));
  1446. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE));
  1447. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE));
  1448. } else {
  1449. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
  1450. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_RIGHT_SIDE));
  1451. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE));
  1452. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE));
  1453. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_LEFT_SIDE));
  1454. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE));
  1455. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE));
  1456. } else {
  1457. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE));
  1458. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_SIDE));
  1459. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE));
  1460. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE));
  1461. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_SIDE));
  1462. around.push_back(get_neighbor_cell(coords, TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE));
  1463. }
  1464. }
  1465. return around;
  1466. }
  1467. void TileMap::draw_cells_outline(Control *p_control, Set<Vector2i> p_cells, Color p_color, Transform2D p_transform) {
  1468. if (!tile_set.is_valid()) {
  1469. return;
  1470. }
  1471. // Create a set.
  1472. Vector2i tile_size = tile_set->get_tile_size();
  1473. Vector<Vector2> uvs;
  1474. if (tile_set->get_tile_shape() == TileSet::TILE_SHAPE_SQUARE) {
  1475. uvs.append(Vector2(1.0, 0.0));
  1476. uvs.append(Vector2(1.0, 1.0));
  1477. uvs.append(Vector2(0.0, 1.0));
  1478. uvs.append(Vector2(0.0, 0.0));
  1479. } else {
  1480. float overlap = 0.0;
  1481. switch (tile_set->get_tile_shape()) {
  1482. case TileSet::TILE_SHAPE_ISOMETRIC:
  1483. overlap = 0.5;
  1484. break;
  1485. case TileSet::TILE_SHAPE_HEXAGON:
  1486. overlap = 0.25;
  1487. break;
  1488. case TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE:
  1489. overlap = 0.0;
  1490. break;
  1491. default:
  1492. break;
  1493. }
  1494. uvs.append(Vector2(1.0, overlap));
  1495. uvs.append(Vector2(1.0, 1.0 - overlap));
  1496. uvs.append(Vector2(0.5, 1.0));
  1497. uvs.append(Vector2(0.0, 1.0 - overlap));
  1498. uvs.append(Vector2(0.0, overlap));
  1499. uvs.append(Vector2(0.5, 0.0));
  1500. if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
  1501. for (int i = 0; i < uvs.size(); i++) {
  1502. uvs.write[i] = Vector2(uvs[i].y, uvs[i].x);
  1503. }
  1504. }
  1505. }
  1506. for (Set<Vector2i>::Element *E = p_cells.front(); E; E = E->next()) {
  1507. Vector2 top_left = map_to_world(E->get()) - tile_size / 2;
  1508. TypedArray<Vector2i> surrounding_tiles = get_surrounding_tiles(E->get());
  1509. for (int i = 0; i < surrounding_tiles.size(); i++) {
  1510. if (!p_cells.has(surrounding_tiles[i])) {
  1511. p_control->draw_line(p_transform.xform(top_left + uvs[i] * tile_size), p_transform.xform(top_left + uvs[(i + 1) % uvs.size()] * tile_size), p_color);
  1512. }
  1513. }
  1514. }
  1515. }
  1516. void TileMap::_bind_methods() {
  1517. ClassDB::bind_method(D_METHOD("set_tileset", "tileset"), &TileMap::set_tileset);
  1518. ClassDB::bind_method(D_METHOD("get_tileset"), &TileMap::get_tileset);
  1519. ClassDB::bind_method(D_METHOD("set_quadrant_size", "size"), &TileMap::set_quadrant_size);
  1520. ClassDB::bind_method(D_METHOD("get_quadrant_size"), &TileMap::get_quadrant_size);
  1521. ClassDB::bind_method(D_METHOD("set_cell", "coords", "source_id", "atlas_coords", "alternative_tile"), &TileMap::set_cell, DEFVAL(-1), DEFVAL(TileSetAtlasSource::INVALID_ATLAS_COORDS), DEFVAL(TileSetAtlasSource::INVALID_TILE_ALTERNATIVE));
  1522. ClassDB::bind_method(D_METHOD("get_cell_source_id", "coords"), &TileMap::get_cell_source_id);
  1523. ClassDB::bind_method(D_METHOD("get_cell_atlas_coords", "coords"), &TileMap::get_cell_atlas_coords);
  1524. ClassDB::bind_method(D_METHOD("get_cell_alternative_tile", "coords"), &TileMap::get_cell_alternative_tile);
  1525. ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles);
  1526. ClassDB::bind_method(D_METHOD("get_surrounding_tiles", "coords"), &TileMap::get_surrounding_tiles);
  1527. ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
  1528. ClassDB::bind_method(D_METHOD("get_used_cells"), &TileMap::get_used_cells);
  1529. ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
  1530. ClassDB::bind_method(D_METHOD("map_to_world", "map_position"), &TileMap::map_to_world);
  1531. ClassDB::bind_method(D_METHOD("world_to_map", "world_position"), &TileMap::world_to_map);
  1532. ClassDB::bind_method(D_METHOD("get_neighbor_cell", "coords", "neighbor"), &TileMap::get_neighbor_cell);
  1533. ClassDB::bind_method(D_METHOD("update_dirty_quadrants"), &TileMap::update_dirty_quadrants);
  1534. ClassDB::bind_method(D_METHOD("_set_tile_data"), &TileMap::_set_tile_data);
  1535. ClassDB::bind_method(D_METHOD("_get_tile_data"), &TileMap::_get_tile_data);
  1536. ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "tile_set", PROPERTY_HINT_RESOURCE_TYPE, "TileSet"), "set_tileset", "get_tileset");
  1537. ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_quadrant_size", PROPERTY_HINT_RANGE, "1,128,1"), "set_quadrant_size", "get_quadrant_size");
  1538. ADD_PROPERTY_DEFAULT("format", FORMAT_1);
  1539. ADD_SIGNAL(MethodInfo("changed"));
  1540. }
  1541. void TileMap::_tile_set_changed() {
  1542. emit_signal("changed");
  1543. _make_all_quadrants_dirty(true);
  1544. }
  1545. TileMap::TileMap() {
  1546. rect_cache_dirty = true;
  1547. used_size_cache_dirty = true;
  1548. pending_update = false;
  1549. quadrant_size = 16;
  1550. format = FORMAT_1; // Assume lowest possible format if none is present
  1551. set_notify_transform(true);
  1552. set_notify_local_transform(false);
  1553. }
  1554. TileMap::~TileMap() {
  1555. if (tile_set.is_valid()) {
  1556. tile_set->disconnect("changed", callable_mp(this, &TileMap::_tile_set_changed));
  1557. }
  1558. _clear_quadrants();
  1559. }