1/**************************************************************************/
2/* tile_set.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
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
31#ifndef TILE_SET_H
32#define TILE_SET_H
33
34#include "core/io/resource.h"
35#include "core/object/object.h"
36#include "core/templates/local_vector.h"
37#include "core/templates/rb_set.h"
38#include "scene/2d/light_occluder_2d.h"
39#include "scene/main/canvas_item.h"
40#include "scene/resources/concave_polygon_shape_2d.h"
41#include "scene/resources/convex_polygon_shape_2d.h"
42#include "scene/resources/image_texture.h"
43#include "scene/resources/navigation_polygon.h"
44#include "scene/resources/packed_scene.h"
45#include "scene/resources/physics_material.h"
46#include "scene/resources/shape_2d.h"
47
48#ifndef DISABLE_DEPRECATED
49#include "scene/resources/shader.h"
50#endif
51
52class TileMap;
53class TileSetSource;
54class TileSetAtlasSource;
55class TileData;
56
57// Forward-declare the plugins.
58class TileSetPlugin;
59class TileSetPluginAtlasRendering;
60class TileSetPluginAtlasPhysics;
61class TileSetPluginAtlasNavigation;
62
63union TileMapCell {
64 struct {
65 int16_t source_id;
66 int16_t coord_x;
67 int16_t coord_y;
68 int16_t alternative_tile;
69 };
70
71 uint64_t _u64t;
72
73 static uint32_t hash(const TileMapCell &p_hash) {
74 return hash_one_uint64(p_hash._u64t);
75 }
76
77 TileMapCell(int p_source_id = -1, Vector2i p_atlas_coords = Vector2i(-1, -1), int p_alternative_tile = -1) { // default are INVALID_SOURCE, INVALID_ATLAS_COORDS, INVALID_TILE_ALTERNATIVE
78 source_id = p_source_id;
79 set_atlas_coords(p_atlas_coords);
80 alternative_tile = p_alternative_tile;
81 }
82
83 Vector2i get_atlas_coords() const {
84 return Vector2i(coord_x, coord_y);
85 }
86
87 void set_atlas_coords(const Vector2i &r_coords) {
88 coord_x = r_coords.x;
89 coord_y = r_coords.y;
90 }
91
92 bool operator<(const TileMapCell &p_other) const {
93 if (source_id == p_other.source_id) {
94 if (coord_x == p_other.coord_x) {
95 if (coord_y == p_other.coord_y) {
96 return alternative_tile < p_other.alternative_tile;
97 } else {
98 return coord_y < p_other.coord_y;
99 }
100 } else {
101 return coord_x < p_other.coord_x;
102 }
103 } else {
104 return source_id < p_other.source_id;
105 }
106 }
107
108 bool operator!=(const TileMapCell &p_other) const {
109 return !(source_id == p_other.source_id && coord_x == p_other.coord_x && coord_y == p_other.coord_y && alternative_tile == p_other.alternative_tile);
110 }
111 bool operator==(const TileMapCell &p_other) const {
112 return source_id == p_other.source_id && coord_x == p_other.coord_x && coord_y == p_other.coord_y && alternative_tile == p_other.alternative_tile;
113 }
114};
115
116class TileMapPattern : public Resource {
117 GDCLASS(TileMapPattern, Resource);
118
119 Size2i size;
120 HashMap<Vector2i, TileMapCell> pattern;
121
122 void _set_tile_data(const Vector<int> &p_data);
123 Vector<int> _get_tile_data() const;
124
125protected:
126 bool _set(const StringName &p_name, const Variant &p_value);
127 bool _get(const StringName &p_name, Variant &r_ret) const;
128 void _get_property_list(List<PropertyInfo> *p_list) const;
129
130 static void _bind_methods();
131
132public:
133 void set_cell(const Vector2i &p_coords, int p_source_id, const Vector2i p_atlas_coords, int p_alternative_tile = 0);
134 bool has_cell(const Vector2i &p_coords) const;
135 void remove_cell(const Vector2i &p_coords, bool p_update_size = true);
136 int get_cell_source_id(const Vector2i &p_coords) const;
137 Vector2i get_cell_atlas_coords(const Vector2i &p_coords) const;
138 int get_cell_alternative_tile(const Vector2i &p_coords) const;
139
140 TypedArray<Vector2i> get_used_cells() const;
141
142 Size2i get_size() const;
143 void set_size(const Size2i &p_size);
144 bool is_empty() const;
145
146 void clear();
147};
148
149class TileSet : public Resource {
150 GDCLASS(TileSet, Resource);
151
152#ifndef DISABLE_DEPRECATED
153private:
154 struct CompatibilityShapeData {
155 Vector2i autotile_coords;
156 bool one_way;
157 float one_way_margin;
158 Ref<Shape2D> shape;
159 Transform2D transform;
160 };
161
162 struct CompatibilityTileData {
163 String name;
164 Ref<Texture2D> texture;
165 Vector2 tex_offset;
166 Ref<Material> material;
167 Rect2 region;
168 int tile_mode = 0;
169 Color modulate = Color(1, 1, 1);
170
171 // Atlas or autotiles data
172 int autotile_bitmask_mode = 0;
173 Vector2 autotile_icon_coordinate;
174 Size2i autotile_tile_size = Size2i(16, 16);
175
176 int autotile_spacing = 0;
177 HashMap<Vector2i, int> autotile_bitmask_flags;
178 HashMap<Vector2i, Ref<OccluderPolygon2D>> autotile_occluder_map;
179 HashMap<Vector2i, Ref<NavigationPolygon>> autotile_navpoly_map;
180 HashMap<Vector2i, int> autotile_priority_map;
181 HashMap<Vector2i, int> autotile_z_index_map;
182
183 Vector<CompatibilityShapeData> shapes;
184 Ref<OccluderPolygon2D> occluder;
185 Vector2 occluder_offset;
186 Ref<NavigationPolygon> navigation;
187 Vector2 navigation_offset;
188 int z_index = 0;
189 };
190
191 enum CompatibilityTileMode {
192 COMPATIBILITY_TILE_MODE_SINGLE_TILE = 0,
193 COMPATIBILITY_TILE_MODE_AUTO_TILE,
194 COMPATIBILITY_TILE_MODE_ATLAS_TILE,
195 };
196
197 HashMap<int, CompatibilityTileData *> compatibility_data;
198 HashMap<int, int> compatibility_tilemap_mapping_tile_modes;
199 HashMap<int, RBMap<Array, Array>> compatibility_tilemap_mapping;
200 HashMap<Vector2i, int> compatibility_size_count;
201
202 void _compatibility_conversion();
203
204public:
205 // Format of output array [source_id, atlas_coords, alternative]
206 Array compatibility_tilemap_map(int p_tile_id, Vector2i p_coords, bool p_flip_h, bool p_flip_v, bool p_transpose);
207#endif // DISABLE_DEPRECATED
208
209public:
210 static const int INVALID_SOURCE; // -1;
211
212 enum CellNeighbor {
213 CELL_NEIGHBOR_RIGHT_SIDE = 0,
214 CELL_NEIGHBOR_RIGHT_CORNER,
215 CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE,
216 CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER,
217 CELL_NEIGHBOR_BOTTOM_SIDE,
218 CELL_NEIGHBOR_BOTTOM_CORNER,
219 CELL_NEIGHBOR_BOTTOM_LEFT_SIDE,
220 CELL_NEIGHBOR_BOTTOM_LEFT_CORNER,
221 CELL_NEIGHBOR_LEFT_SIDE,
222 CELL_NEIGHBOR_LEFT_CORNER,
223 CELL_NEIGHBOR_TOP_LEFT_SIDE,
224 CELL_NEIGHBOR_TOP_LEFT_CORNER,
225 CELL_NEIGHBOR_TOP_SIDE,
226 CELL_NEIGHBOR_TOP_CORNER,
227 CELL_NEIGHBOR_TOP_RIGHT_SIDE,
228 CELL_NEIGHBOR_TOP_RIGHT_CORNER,
229 CELL_NEIGHBOR_MAX,
230 };
231
232 static const char *CELL_NEIGHBOR_ENUM_TO_TEXT[];
233
234 enum TerrainMode {
235 TERRAIN_MODE_MATCH_CORNERS_AND_SIDES = 0,
236 TERRAIN_MODE_MATCH_CORNERS,
237 TERRAIN_MODE_MATCH_SIDES,
238 };
239
240 enum TileShape {
241 TILE_SHAPE_SQUARE,
242 TILE_SHAPE_ISOMETRIC,
243 TILE_SHAPE_HALF_OFFSET_SQUARE,
244 TILE_SHAPE_HEXAGON,
245 };
246
247 enum TileLayout {
248 TILE_LAYOUT_STACKED,
249 TILE_LAYOUT_STACKED_OFFSET,
250 TILE_LAYOUT_STAIRS_RIGHT,
251 TILE_LAYOUT_STAIRS_DOWN,
252 TILE_LAYOUT_DIAMOND_RIGHT,
253 TILE_LAYOUT_DIAMOND_DOWN,
254 };
255
256 enum TileOffsetAxis {
257 TILE_OFFSET_AXIS_HORIZONTAL,
258 TILE_OFFSET_AXIS_VERTICAL,
259 };
260
261 struct PackedSceneSource {
262 Ref<PackedScene> scene;
263 Vector2 offset;
264 };
265
266 class TerrainsPattern {
267 bool valid = false;
268 int terrain = -1;
269 int bits[TileSet::CELL_NEIGHBOR_MAX];
270 bool is_valid_bit[TileSet::CELL_NEIGHBOR_MAX];
271
272 int not_empty_terrains_count = 0;
273
274 public:
275 bool is_valid() const;
276 bool is_erase_pattern() const;
277
278 bool operator<(const TerrainsPattern &p_terrains_pattern) const;
279 bool operator==(const TerrainsPattern &p_terrains_pattern) const;
280 bool operator!=(const TerrainsPattern &p_terrains_pattern) const {
281 return !operator==(p_terrains_pattern);
282 };
283
284 void set_terrain(int p_terrain);
285 int get_terrain() const;
286
287 void set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int p_terrain);
288 int get_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const;
289
290 void from_array(Array p_terrains);
291 Array as_array() const;
292
293 TerrainsPattern(const TileSet *p_tile_set, int p_terrain_set);
294 TerrainsPattern() {}
295 };
296
297protected:
298 bool _set(const StringName &p_name, const Variant &p_value);
299 bool _get(const StringName &p_name, Variant &r_ret) const;
300 void _get_property_list(List<PropertyInfo> *p_list) const;
301 void _validate_property(PropertyInfo &p_property) const;
302
303private:
304 // --- TileSet data ---
305 // Basic shape and layout.
306 TileShape tile_shape = TILE_SHAPE_SQUARE;
307 TileLayout tile_layout = TILE_LAYOUT_STACKED;
308 TileOffsetAxis tile_offset_axis = TILE_OFFSET_AXIS_HORIZONTAL;
309 Size2i tile_size = Size2i(16, 16); //Size2(64, 64);
310
311 // Rendering.
312 bool uv_clipping = false;
313 struct OcclusionLayer {
314 uint32_t light_mask = 1;
315 bool sdf_collision = false;
316 };
317 Vector<OcclusionLayer> occlusion_layers;
318
319 Ref<ArrayMesh> tile_lines_mesh;
320 Ref<ArrayMesh> tile_filled_mesh;
321 bool tile_meshes_dirty = true;
322
323 // Physics
324 struct PhysicsLayer {
325 uint32_t collision_layer = 1;
326 uint32_t collision_mask = 1;
327 Ref<PhysicsMaterial> physics_material;
328 };
329 Vector<PhysicsLayer> physics_layers;
330
331 // Terrains
332 struct Terrain {
333 String name;
334 Color color;
335 };
336 struct TerrainSet {
337 TerrainMode mode = TERRAIN_MODE_MATCH_CORNERS_AND_SIDES;
338 Vector<Terrain> terrains;
339 };
340 Vector<TerrainSet> terrain_sets;
341
342 HashMap<TerrainMode, Ref<ArrayMesh>> terrain_meshes;
343 HashMap<TerrainMode, HashMap<CellNeighbor, Ref<ArrayMesh>>> terrain_peering_bits_meshes;
344 bool terrain_bits_meshes_dirty = true;
345
346 LocalVector<RBMap<TileSet::TerrainsPattern, RBSet<TileMapCell>>> per_terrain_pattern_tiles; // Cached data.
347 bool terrains_cache_dirty = true;
348 void _update_terrains_cache();
349
350 // Navigation
351 struct NavigationLayer {
352 uint32_t layers = 1;
353 };
354 Vector<NavigationLayer> navigation_layers;
355
356 // CustomData
357 struct CustomDataLayer {
358 String name;
359 Variant::Type type = Variant::NIL;
360 };
361 Vector<CustomDataLayer> custom_data_layers;
362 HashMap<String, int> custom_data_layers_by_name;
363
364 // Per Atlas source data.
365 HashMap<int, Ref<TileSetSource>> sources;
366 Vector<int> source_ids;
367 int next_source_id = 0;
368 // ---------------------
369
370 LocalVector<Ref<TileMapPattern>> patterns;
371
372 void _compute_next_source_id();
373 void _source_changed();
374
375 // Tile proxies
376 RBMap<int, int> source_level_proxies;
377 RBMap<Array, Array> coords_level_proxies;
378 RBMap<Array, Array> alternative_level_proxies;
379
380 // Helpers
381 Vector<Point2> _get_square_terrain_polygon(Vector2i p_size);
382 Vector<Point2> _get_square_corner_or_side_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
383 Vector<Point2> _get_square_corner_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
384 Vector<Point2> _get_square_side_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
385
386 Vector<Point2> _get_isometric_terrain_polygon(Vector2i p_size);
387 Vector<Point2> _get_isometric_corner_or_side_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
388 Vector<Point2> _get_isometric_corner_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
389 Vector<Point2> _get_isometric_side_terrain_peering_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit);
390
391 Vector<Point2> _get_half_offset_terrain_polygon(Vector2i p_size, float p_overlap, TileSet::TileOffsetAxis p_offset_axis);
392 Vector<Point2> _get_half_offset_corner_or_side_terrain_peering_bit_polygon(Vector2i p_size, float p_overlap, TileSet::TileOffsetAxis p_offset_axis, TileSet::CellNeighbor p_bit);
393 Vector<Point2> _get_half_offset_corner_terrain_peering_bit_polygon(Vector2i p_size, float p_overlap, TileSet::TileOffsetAxis p_offset_axis, TileSet::CellNeighbor p_bit);
394 Vector<Point2> _get_half_offset_side_terrain_peering_bit_polygon(Vector2i p_size, float p_overlap, TileSet::TileOffsetAxis p_offset_axis, TileSet::CellNeighbor p_bit);
395
396protected:
397 static void _bind_methods();
398
399public:
400 // --- Plugins ---
401 Vector<TileSetPlugin *> get_tile_set_atlas_plugins() const;
402
403 // --- Accessors for TileSet data ---
404
405 // -- Shape and layout --
406 void set_tile_shape(TileShape p_shape);
407 TileShape get_tile_shape() const;
408 void set_tile_layout(TileLayout p_layout);
409 TileLayout get_tile_layout() const;
410 void set_tile_offset_axis(TileOffsetAxis p_alignment);
411 TileOffsetAxis get_tile_offset_axis() const;
412 void set_tile_size(Size2i p_size);
413 Size2i get_tile_size() const;
414
415 // -- Sources management --
416 int get_next_source_id() const;
417 int get_source_count() const;
418 int get_source_id(int p_index) const;
419 int add_source(Ref<TileSetSource> p_tile_set_source, int p_source_id_override = -1);
420 void set_source_id(int p_source_id, int p_new_id);
421 void remove_source(int p_source_id);
422 void remove_source_ptr(TileSetSource *p_tile_set_source); // Not exposed
423 bool has_source(int p_source_id) const;
424 Ref<TileSetSource> get_source(int p_source_id) const;
425
426 // Rendering
427 void set_uv_clipping(bool p_uv_clipping);
428 bool is_uv_clipping() const;
429
430 int get_occlusion_layers_count() const;
431 void add_occlusion_layer(int p_index = -1);
432 void move_occlusion_layer(int p_from_index, int p_to_pos);
433 void remove_occlusion_layer(int p_index);
434 void set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask);
435 int get_occlusion_layer_light_mask(int p_layer_index) const;
436 void set_occlusion_layer_sdf_collision(int p_layer_index, bool p_sdf_collision);
437 bool get_occlusion_layer_sdf_collision(int p_layer_index) const;
438
439 // Physics
440 int get_physics_layers_count() const;
441 void add_physics_layer(int p_index = -1);
442 void move_physics_layer(int p_from_index, int p_to_pos);
443 void remove_physics_layer(int p_index);
444 void set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer);
445 uint32_t get_physics_layer_collision_layer(int p_layer_index) const;
446 void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask);
447 uint32_t get_physics_layer_collision_mask(int p_layer_index) const;
448 void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material);
449 Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const;
450
451 // Terrain sets
452 int get_terrain_sets_count() const;
453 void add_terrain_set(int p_index = -1);
454 void move_terrain_set(int p_from_index, int p_to_pos);
455 void remove_terrain_set(int p_index);
456 void set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode);
457 TerrainMode get_terrain_set_mode(int p_terrain_set) const;
458
459 // Terrains
460 int get_terrains_count(int p_terrain_set) const;
461 void add_terrain(int p_terrain_set, int p_index = -1);
462 void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
463 void remove_terrain(int p_terrain_set, int p_index);
464 void set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name);
465 String get_terrain_name(int p_terrain_set, int p_terrain_index) const;
466 void set_terrain_color(int p_terrain_set, int p_terrain_index, Color p_color);
467 Color get_terrain_color(int p_terrain_set, int p_terrain_index) const;
468 bool is_valid_terrain_peering_bit_for_mode(TileSet::TerrainMode p_terrain_mode, TileSet::CellNeighbor p_peering_bit) const;
469 bool is_valid_terrain_peering_bit(int p_terrain_set, TileSet::CellNeighbor p_peering_bit) const;
470
471 // Navigation
472 int get_navigation_layers_count() const;
473 void add_navigation_layer(int p_index = -1);
474 void move_navigation_layer(int p_from_index, int p_to_pos);
475 void remove_navigation_layer(int p_index);
476 void set_navigation_layer_layers(int p_layer_index, uint32_t p_layers);
477 uint32_t get_navigation_layer_layers(int p_layer_index) const;
478 void set_navigation_layer_layer_value(int p_layer_index, int p_layer_number, bool p_value);
479 bool get_navigation_layer_layer_value(int p_layer_index, int p_layer_number) const;
480
481 // Custom data
482 int get_custom_data_layers_count() const;
483 void add_custom_data_layer(int p_index = -1);
484 void move_custom_data_layer(int p_from_index, int p_to_pos);
485 void remove_custom_data_layer(int p_index);
486 int get_custom_data_layer_by_name(String p_value) const;
487 void set_custom_data_layer_name(int p_layer_id, String p_value);
488 String get_custom_data_layer_name(int p_layer_id) const;
489 void set_custom_data_layer_type(int p_layer_id, Variant::Type p_value);
490 Variant::Type get_custom_data_layer_type(int p_layer_id) const;
491
492 // Tiles proxies.
493 void set_source_level_tile_proxy(int p_source_from, int p_source_to);
494 int get_source_level_tile_proxy(int p_source_from);
495 bool has_source_level_tile_proxy(int p_source_from);
496 void remove_source_level_tile_proxy(int p_source_from);
497
498 void set_coords_level_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_source_to, Vector2i p_coords_to);
499 Array get_coords_level_tile_proxy(int p_source_from, Vector2i p_coords_from);
500 bool has_coords_level_tile_proxy(int p_source_from, Vector2i p_coords_from);
501 void remove_coords_level_tile_proxy(int p_source_from, Vector2i p_coords_from);
502
503 void set_alternative_level_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_alternative_from, int p_source_to, Vector2i p_coords_to, int p_alternative_to);
504 Array get_alternative_level_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_alternative_from);
505 bool has_alternative_level_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_alternative_from);
506 void remove_alternative_level_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_alternative_from);
507
508 Array get_source_level_tile_proxies() const;
509 Array get_coords_level_tile_proxies() const;
510 Array get_alternative_level_tile_proxies() const;
511
512 Array map_tile_proxy(int p_source_from, Vector2i p_coords_from, int p_alternative_from) const;
513
514 void cleanup_invalid_tile_proxies();
515 void clear_tile_proxies();
516
517 // Patterns.
518 int add_pattern(Ref<TileMapPattern> p_pattern, int p_index = -1);
519 Ref<TileMapPattern> get_pattern(int p_index);
520 void remove_pattern(int p_index);
521 int get_patterns_count();
522
523 // Terrains.
524 RBSet<TerrainsPattern> get_terrains_pattern_set(int p_terrain_set);
525 RBSet<TileMapCell> get_tiles_for_terrains_pattern(int p_terrain_set, TerrainsPattern p_terrain_tile_pattern);
526 TileMapCell get_random_tile_from_terrains_pattern(int p_terrain_set, TerrainsPattern p_terrain_tile_pattern);
527
528 // Helpers
529 Vector<Vector2> get_tile_shape_polygon();
530 void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
531
532 Vector<Point2> get_terrain_polygon(int p_terrain_set);
533 Vector<Point2> get_terrain_peering_bit_polygon(int p_terrain_set, TileSet::CellNeighbor p_bit);
534 void draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, const TileData *p_tile_data);
535 Vector<Vector<Ref<Texture2D>>> generate_terrains_icons(Size2i p_size);
536
537 // Resource management
538 virtual void reset_state() override;
539
540 TileSet();
541 ~TileSet();
542};
543
544class TileSetSource : public Resource {
545 GDCLASS(TileSetSource, Resource);
546
547protected:
548 const TileSet *tile_set = nullptr;
549
550 static void _bind_methods();
551
552public:
553 static const Vector2i INVALID_ATLAS_COORDS; // Vector2i(-1, -1);
554 static const int INVALID_TILE_ALTERNATIVE; // -1;
555
556 // Not exposed.
557 virtual void set_tile_set(const TileSet *p_tile_set);
558 TileSet *get_tile_set() const;
559 virtual void notify_tile_data_properties_should_change(){};
560 virtual void add_occlusion_layer(int p_index){};
561 virtual void move_occlusion_layer(int p_from_index, int p_to_pos){};
562 virtual void remove_occlusion_layer(int p_index){};
563 virtual void add_physics_layer(int p_index){};
564 virtual void move_physics_layer(int p_from_index, int p_to_pos){};
565 virtual void remove_physics_layer(int p_index){};
566 virtual void add_terrain_set(int p_index){};
567 virtual void move_terrain_set(int p_from_index, int p_to_pos){};
568 virtual void remove_terrain_set(int p_index){};
569 virtual void add_terrain(int p_terrain_set, int p_index){};
570 virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos){};
571 virtual void remove_terrain(int p_terrain_set, int p_index){};
572 virtual void add_navigation_layer(int p_index){};
573 virtual void move_navigation_layer(int p_from_index, int p_to_pos){};
574 virtual void remove_navigation_layer(int p_index){};
575 virtual void add_custom_data_layer(int p_index){};
576 virtual void move_custom_data_layer(int p_from_index, int p_to_pos){};
577 virtual void remove_custom_data_layer(int p_index){};
578 virtual void reset_state() override;
579
580 // Tiles.
581 virtual int get_tiles_count() const = 0;
582 virtual Vector2i get_tile_id(int tile_index) const = 0;
583 virtual bool has_tile(Vector2i p_atlas_coords) const = 0;
584
585 // Alternative tiles.
586 virtual int get_alternative_tiles_count(const Vector2i p_atlas_coords) const = 0;
587 virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const = 0;
588 virtual bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const = 0;
589};
590
591class TileSetAtlasSource : public TileSetSource {
592 GDCLASS(TileSetAtlasSource, TileSetSource);
593
594public:
595 enum TileAnimationMode {
596 TILE_ANIMATION_MODE_DEFAULT,
597 TILE_ANIMATION_MODE_RANDOM_START_TIMES,
598 TILE_ANIMATION_MODE_MAX,
599 };
600
601 enum TransformBits {
602 TRANSFORM_FLIP_H = 1 << 12,
603 TRANSFORM_FLIP_V = 1 << 13,
604 TRANSFORM_TRANSPOSE = 1 << 14,
605 };
606
607private:
608 struct TileAlternativesData {
609 Vector2i size_in_atlas = Vector2i(1, 1);
610 Vector2i texture_offset;
611
612 // Animation
613 int animation_columns = 0;
614 Vector2i animation_separation;
615 real_t animation_speed = 1.0;
616 TileSetAtlasSource::TileAnimationMode animation_mode = TILE_ANIMATION_MODE_DEFAULT;
617 LocalVector<real_t> animation_frames_durations;
618
619 // Alternatives
620 HashMap<int, TileData *> alternatives;
621 Vector<int> alternatives_ids;
622 int next_alternative_id = 1;
623 };
624
625 Ref<Texture2D> texture;
626 Vector2i margins;
627 Vector2i separation;
628 Size2i texture_region_size = Size2i(16, 16);
629
630 HashMap<Vector2i, TileAlternativesData> tiles;
631 Vector<Vector2i> tiles_ids;
632 HashMap<Vector2i, Vector2i> _coords_mapping_cache; // Maps any coordinate to the including tile
633
634 TileData *_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile);
635 const TileData *_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) const;
636
637 void _compute_next_alternative_id(const Vector2i p_atlas_coords);
638
639 void _clear_coords_mapping_cache(Vector2i p_atlas_coords);
640 void _create_coords_mapping_cache(Vector2i p_atlas_coords);
641
642 bool use_texture_padding = true;
643 Ref<ImageTexture> padded_texture;
644 bool padded_texture_needs_update = false;
645 void _queue_update_padded_texture();
646 void _update_padded_texture();
647
648protected:
649 bool _set(const StringName &p_name, const Variant &p_value);
650 bool _get(const StringName &p_name, Variant &r_ret) const;
651 void _get_property_list(List<PropertyInfo> *p_list) const;
652
653 static void _bind_methods();
654
655public:
656 // Not exposed.
657 virtual void set_tile_set(const TileSet *p_tile_set) override;
658 const TileSet *get_tile_set() const;
659 virtual void notify_tile_data_properties_should_change() override;
660 virtual void add_occlusion_layer(int p_index) override;
661 virtual void move_occlusion_layer(int p_from_index, int p_to_pos) override;
662 virtual void remove_occlusion_layer(int p_index) override;
663 virtual void add_physics_layer(int p_index) override;
664 virtual void move_physics_layer(int p_from_index, int p_to_pos) override;
665 virtual void remove_physics_layer(int p_index) override;
666 virtual void add_terrain_set(int p_index) override;
667 virtual void move_terrain_set(int p_from_index, int p_to_pos) override;
668 virtual void remove_terrain_set(int p_index) override;
669 virtual void add_terrain(int p_terrain_set, int p_index) override;
670 virtual void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos) override;
671 virtual void remove_terrain(int p_terrain_set, int p_index) override;
672 virtual void add_navigation_layer(int p_index) override;
673 virtual void move_navigation_layer(int p_from_index, int p_to_pos) override;
674 virtual void remove_navigation_layer(int p_index) override;
675 virtual void add_custom_data_layer(int p_index) override;
676 virtual void move_custom_data_layer(int p_from_index, int p_to_pos) override;
677 virtual void remove_custom_data_layer(int p_index) override;
678 virtual void reset_state() override;
679
680 // Base properties.
681 void set_texture(Ref<Texture2D> p_texture);
682 Ref<Texture2D> get_texture() const;
683 void set_margins(Vector2i p_margins);
684 Vector2i get_margins() const;
685 void set_separation(Vector2i p_separation);
686 Vector2i get_separation() const;
687 void set_texture_region_size(Vector2i p_tile_size);
688 Vector2i get_texture_region_size() const;
689
690 // Padding.
691 void set_use_texture_padding(bool p_use_padding);
692 bool get_use_texture_padding() const;
693
694 // Base tiles.
695 void create_tile(const Vector2i p_atlas_coords, const Vector2i p_size = Vector2i(1, 1));
696 void remove_tile(Vector2i p_atlas_coords);
697 virtual bool has_tile(Vector2i p_atlas_coords) const override;
698 void move_tile_in_atlas(Vector2i p_atlas_coords, Vector2i p_new_atlas_coords = INVALID_ATLAS_COORDS, Vector2i p_new_size = Vector2i(-1, -1));
699 Vector2i get_tile_size_in_atlas(Vector2i p_atlas_coords) const;
700
701 virtual int get_tiles_count() const override;
702 virtual Vector2i get_tile_id(int p_index) const override;
703
704 bool has_room_for_tile(Vector2i p_atlas_coords, Vector2i p_size, int p_animation_columns, Vector2i p_animation_separation, int p_frames_count, Vector2i p_ignored_tile = INVALID_ATLAS_COORDS) const;
705 PackedVector2Array get_tiles_to_be_removed_on_change(Ref<Texture2D> p_texture, Vector2i p_margins, Vector2i p_separation, Vector2i p_texture_region_size);
706 Vector2i get_tile_at_coords(Vector2i p_atlas_coords) const;
707
708 bool has_tiles_outside_texture() const;
709 Vector<Vector2i> get_tiles_outside_texture() const;
710 void clear_tiles_outside_texture();
711
712 // Animation.
713 void set_tile_animation_columns(const Vector2i p_atlas_coords, int p_frame_columns);
714 int get_tile_animation_columns(const Vector2i p_atlas_coords) const;
715 void set_tile_animation_separation(const Vector2i p_atlas_coords, const Vector2i p_separation);
716 Vector2i get_tile_animation_separation(const Vector2i p_atlas_coords) const;
717 void set_tile_animation_speed(const Vector2i p_atlas_coords, real_t p_speed);
718 real_t get_tile_animation_speed(const Vector2i p_atlas_coords) const;
719 void set_tile_animation_mode(const Vector2i p_atlas_coords, const TileSetAtlasSource::TileAnimationMode p_mode);
720 TileSetAtlasSource::TileAnimationMode get_tile_animation_mode(const Vector2i p_atlas_coords) const;
721 void set_tile_animation_frames_count(const Vector2i p_atlas_coords, int p_frames_count);
722 int get_tile_animation_frames_count(const Vector2i p_atlas_coords) const;
723 void set_tile_animation_frame_duration(const Vector2i p_atlas_coords, int p_frame_index, real_t p_duration);
724 real_t get_tile_animation_frame_duration(const Vector2i p_atlas_coords, int p_frame_index) const;
725 real_t get_tile_animation_total_duration(const Vector2i p_atlas_coords) const;
726
727 // Alternative tiles.
728 int create_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_id_override = -1);
729 void remove_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile);
730 void set_alternative_tile_id(const Vector2i p_atlas_coords, int p_alternative_tile, int p_new_id);
731 virtual bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override;
732 int get_next_alternative_tile_id(const Vector2i p_atlas_coords) const;
733
734 virtual int get_alternative_tiles_count(const Vector2i p_atlas_coords) const override;
735 virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override;
736
737 // Get data associated to a tile.
738 TileData *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const;
739
740 // Helpers.
741 Vector2i get_atlas_grid_size() const;
742 Rect2i get_tile_texture_region(Vector2i p_atlas_coords, int p_frame = 0) const;
743 bool is_position_in_tile_texture_region(const Vector2i p_atlas_coords, int p_alternative_tile, Vector2 p_position) const;
744
745 static int alternative_no_transform(int p_alternative_id);
746
747 // Getters for texture and tile region (padded or not)
748 Ref<Texture2D> get_runtime_texture() const;
749 Rect2i get_runtime_tile_texture_region(Vector2i p_atlas_coords, int p_frame = 0) const;
750
751 ~TileSetAtlasSource();
752};
753
754class TileSetScenesCollectionSource : public TileSetSource {
755 GDCLASS(TileSetScenesCollectionSource, TileSetSource);
756
757private:
758 struct SceneData {
759 Ref<PackedScene> scene;
760 bool display_placeholder = false;
761 };
762 Vector<int> scenes_ids;
763 HashMap<int, SceneData> scenes;
764 int next_scene_id = 1;
765
766 void _compute_next_alternative_id();
767
768protected:
769 bool _set(const StringName &p_name, const Variant &p_value);
770 bool _get(const StringName &p_name, Variant &r_ret) const;
771 void _get_property_list(List<PropertyInfo> *p_list) const;
772
773 static void _bind_methods();
774
775public:
776 // Tiles.
777 int get_tiles_count() const override;
778 Vector2i get_tile_id(int p_tile_index) const override;
779 bool has_tile(Vector2i p_atlas_coords) const override;
780
781 // Alternative tiles.
782 int get_alternative_tiles_count(const Vector2i p_atlas_coords) const override;
783 int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override;
784 bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override;
785
786 // Scenes accessors. Lot are similar to "Alternative tiles".
787 int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); }
788 int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); };
789 bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); };
790 int create_scene_tile(Ref<PackedScene> p_packed_scene = Ref<PackedScene>(), int p_id_override = -1);
791 void set_scene_tile_id(int p_id, int p_new_id);
792 void set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene);
793 Ref<PackedScene> get_scene_tile_scene(int p_id) const;
794 void set_scene_tile_display_placeholder(int p_id, bool p_packed_scene);
795 bool get_scene_tile_display_placeholder(int p_id) const;
796 void remove_scene_tile(int p_id);
797 int get_next_scene_tile_id() const;
798};
799
800class TileData : public Object {
801 GDCLASS(TileData, Object);
802
803private:
804 const TileSet *tile_set = nullptr;
805 bool allow_transform = true;
806
807 // Rendering
808 bool flip_h = false;
809 bool flip_v = false;
810 bool transpose = false;
811 Vector2i texture_origin;
812 Ref<Material> material = Ref<Material>();
813 Color modulate = Color(1.0, 1.0, 1.0, 1.0);
814 int z_index = 0;
815 int y_sort_origin = 0;
816 Vector<Ref<OccluderPolygon2D>> occluders;
817
818 // Physics
819 struct PhysicsLayerTileData {
820 struct PolygonShapeTileData {
821 LocalVector<Vector2> polygon;
822 LocalVector<Ref<ConvexPolygonShape2D>> shapes;
823 bool one_way = false;
824 float one_way_margin = 1.0;
825 };
826
827 Vector2 linear_velocity;
828 double angular_velocity = 0.0;
829 Vector<PolygonShapeTileData> polygons;
830 };
831 Vector<PhysicsLayerTileData> physics;
832 // TODO add support for areas.
833
834 // Terrain
835 int terrain_set = -1;
836 int terrain = -1;
837 int terrain_peering_bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
838
839 // Navigation
840 Vector<Ref<NavigationPolygon>> navigation;
841
842 // Misc
843 double probability = 1.0;
844
845 // Custom data
846 Vector<Variant> custom_data;
847
848protected:
849 bool _set(const StringName &p_name, const Variant &p_value);
850 bool _get(const StringName &p_name, Variant &r_ret) const;
851 void _get_property_list(List<PropertyInfo> *p_list) const;
852 static void _bind_methods();
853
854public:
855 // Not exposed.
856 void set_tile_set(const TileSet *p_tile_set);
857 void notify_tile_data_properties_should_change();
858 void add_occlusion_layer(int p_index);
859 void move_occlusion_layer(int p_from_index, int p_to_pos);
860 void remove_occlusion_layer(int p_index);
861 void add_physics_layer(int p_index);
862 void move_physics_layer(int p_from_index, int p_to_pos);
863 void remove_physics_layer(int p_index);
864 void add_terrain_set(int p_index);
865 void move_terrain_set(int p_from_index, int p_to_pos);
866 void remove_terrain_set(int p_index);
867 void add_terrain(int p_terrain_set, int p_index);
868 void move_terrain(int p_terrain_set, int p_from_index, int p_to_pos);
869 void remove_terrain(int p_terrain_set, int p_index);
870 void add_navigation_layer(int p_index);
871 void move_navigation_layer(int p_from_index, int p_to_pos);
872 void remove_navigation_layer(int p_index);
873 void add_custom_data_layer(int p_index);
874 void move_custom_data_layer(int p_from_index, int p_to_pos);
875 void remove_custom_data_layer(int p_index);
876 void set_allow_transform(bool p_allow_transform);
877 bool is_allowing_transform() const;
878
879 // To duplicate a TileData object, needed for runtiume update.
880 TileData *duplicate();
881
882 // Rendering
883 void set_flip_h(bool p_flip_h);
884 bool get_flip_h() const;
885 void set_flip_v(bool p_flip_v);
886 bool get_flip_v() const;
887 void set_transpose(bool p_transpose);
888 bool get_transpose() const;
889
890 void set_texture_origin(Vector2i p_texture_origin);
891 Vector2i get_texture_origin() const;
892 void set_material(Ref<Material> p_material);
893 Ref<Material> get_material() const;
894 void set_modulate(Color p_modulate);
895 Color get_modulate() const;
896 void set_z_index(int p_z_index);
897 int get_z_index() const;
898 void set_y_sort_origin(int p_y_sort_origin);
899 int get_y_sort_origin() const;
900
901 void set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon);
902 Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const;
903
904 // Physics
905 void set_constant_linear_velocity(int p_layer_id, const Vector2 &p_velocity);
906 Vector2 get_constant_linear_velocity(int p_layer_id) const;
907 void set_constant_angular_velocity(int p_layer_id, real_t p_velocity);
908 real_t get_constant_angular_velocity(int p_layer_id) const;
909 void set_collision_polygons_count(int p_layer_id, int p_shapes_count);
910 int get_collision_polygons_count(int p_layer_id) const;
911 void add_collision_polygon(int p_layer_id);
912 void remove_collision_polygon(int p_layer_id, int p_polygon_index);
913 void set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon);
914 Vector<Vector2> get_collision_polygon_points(int p_layer_id, int p_polygon_index) const;
915 void set_collision_polygon_one_way(int p_layer_id, int p_polygon_index, bool p_one_way);
916 bool is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const;
917 void set_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index, float p_one_way_margin);
918 float get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const;
919 int get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_index) const;
920 Ref<ConvexPolygonShape2D> get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index) const;
921
922 // Terrain
923 void set_terrain_set(int p_terrain_id);
924 int get_terrain_set() const;
925 void set_terrain(int p_terrain_id);
926 int get_terrain() const;
927 void set_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit, int p_terrain_id);
928 int get_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const;
929 bool is_valid_terrain_peering_bit(TileSet::CellNeighbor p_peering_bit) const;
930
931 TileSet::TerrainsPattern get_terrains_pattern() const; // Not exposed.
932
933 // Navigation
934 void set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon);
935 Ref<NavigationPolygon> get_navigation_polygon(int p_layer_id) const;
936
937 // Misc
938 void set_probability(float p_probability);
939 float get_probability() const;
940
941 // Custom data.
942 void set_custom_data(String p_layer_name, Variant p_value);
943 Variant get_custom_data(String p_layer_name) const;
944 void set_custom_data_by_layer_id(int p_layer_id, Variant p_value);
945 Variant get_custom_data_by_layer_id(int p_layer_id) const;
946};
947
948VARIANT_ENUM_CAST(TileSet::CellNeighbor);
949VARIANT_ENUM_CAST(TileSet::TerrainMode);
950VARIANT_ENUM_CAST(TileSet::TileShape);
951VARIANT_ENUM_CAST(TileSet::TileLayout);
952VARIANT_ENUM_CAST(TileSet::TileOffsetAxis);
953
954VARIANT_ENUM_CAST(TileSetAtlasSource::TileAnimationMode);
955
956#endif // TILE_SET_H
957