diff options
Diffstat (limited to 'scene/resources/tile_set.h')
-rw-r--r-- | scene/resources/tile_set.h | 748 |
1 files changed, 599 insertions, 149 deletions
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 0a8721f35b..dbf6dbabe6 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -32,226 +32,676 @@ #define TILE_SET_H #include "core/io/resource.h" -#include "core/variant/array.h" +#include "core/object/object.h" +#include "core/templates/local_vector.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/navigation_region_2d.h" +#include "scene/main/canvas_item.h" +#include "scene/resources/concave_polygon_shape_2d.h" #include "scene/resources/convex_polygon_shape_2d.h" +#include "scene/resources/packed_scene.h" +#include "scene/resources/physics_material.h" #include "scene/resources/shape_2d.h" + +#ifndef DISABLE_DEPRECATED +#include "scene/resources/shader.h" #include "scene/resources/texture.h" +#endif + +class TileMap; +struct TileMapQuadrant; +class TileSetSource; +class TileSetAtlasSource; +class TileData; + +// Forward-declare the plugins. +class TileSetPlugin; +class TileSetPluginAtlasRendering; +class TileSetPluginAtlasPhysics; +class TileSetPluginAtlasNavigation; class TileSet : public Resource { GDCLASS(TileSet, Resource); -public: - struct ShapeData { +#ifndef DISABLE_DEPRECATED +private: + struct CompatibilityShapeData { + Vector2i autotile_coords; + bool one_way; + float one_way_margin; Ref<Shape2D> shape; - Transform2D shape_transform; - Vector2 autotile_coord; - bool one_way_collision = false; - float one_way_collision_margin = 1.0; + Transform2D transform; + }; - ShapeData() {} + struct CompatibilityTileData { + String name; + Ref<Texture2D> texture; + Vector2 tex_offset; + Ref<ShaderMaterial> material; + Rect2 region; + int tile_mode; + Color modulate; + + // Atlas or autotiles data + int autotile_bitmask_mode; + Vector2 autotile_icon_coordinate; + Size2i autotile_tile_size = Size2i(16, 16); + + int autotile_spacing; + Map<Vector2i, int> autotile_bitmask_flags; + Map<Vector2i, Ref<OccluderPolygon2D>> autotile_occluder_map; + Map<Vector2i, Ref<NavigationPolygon>> autotile_navpoly_map; + Map<Vector2i, int> autotile_priority_map; + Map<Vector2i, int> autotile_z_index_map; + + Vector<CompatibilityShapeData> shapes; + Ref<OccluderPolygon2D> occluder; + Vector2 occluder_offset; + Ref<NavigationPolygon> navigation; + Vector2 navigation_offset; + int z_index; }; - enum BitmaskMode { - BITMASK_2X2, - BITMASK_3X3_MINIMAL, - BITMASK_3X3 + Map<int, CompatibilityTileData *> compatibility_data = Map<int, CompatibilityTileData *>(); + Map<int, int> compatibility_source_mapping = Map<int, int>(); + +private: + void compatibility_conversion(); + +public: + int compatibility_get_source_for_tile_id(int p_old_source) { + return compatibility_source_mapping[p_old_source]; }; - enum AutotileBindings { - BIND_TOPLEFT = 1, - BIND_TOP = 2, - BIND_TOPRIGHT = 4, - BIND_LEFT = 8, - BIND_CENTER = 16, - BIND_RIGHT = 32, - BIND_BOTTOMLEFT = 64, - BIND_BOTTOM = 128, - BIND_BOTTOMRIGHT = 256, - - BIND_IGNORE_TOPLEFT = 1 << 16, - BIND_IGNORE_TOP = 1 << 17, - BIND_IGNORE_TOPRIGHT = 1 << 18, - BIND_IGNORE_LEFT = 1 << 19, - BIND_IGNORE_CENTER = 1 << 20, - BIND_IGNORE_RIGHT = 1 << 21, - BIND_IGNORE_BOTTOMLEFT = 1 << 22, - BIND_IGNORE_BOTTOM = 1 << 23, - BIND_IGNORE_BOTTOMRIGHT = 1 << 24 +#endif // DISABLE_DEPRECATED + +public: + enum CellNeighbor { + CELL_NEIGHBOR_RIGHT_SIDE = 0, + CELL_NEIGHBOR_RIGHT_CORNER, + CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, + CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER, + CELL_NEIGHBOR_BOTTOM_SIDE, + CELL_NEIGHBOR_BOTTOM_CORNER, + CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, + CELL_NEIGHBOR_BOTTOM_LEFT_CORNER, + CELL_NEIGHBOR_LEFT_SIDE, + CELL_NEIGHBOR_LEFT_CORNER, + CELL_NEIGHBOR_TOP_LEFT_SIDE, + CELL_NEIGHBOR_TOP_LEFT_CORNER, + CELL_NEIGHBOR_TOP_SIDE, + CELL_NEIGHBOR_TOP_CORNER, + CELL_NEIGHBOR_TOP_RIGHT_SIDE, + CELL_NEIGHBOR_TOP_RIGHT_CORNER, + CELL_NEIGHBOR_MAX, }; - enum TileMode { - SINGLE_TILE, - AUTO_TILE, - ATLAS_TILE + static const char *CELL_NEIGHBOR_ENUM_TO_TEXT[]; + + enum TerrainMode { + TERRAIN_MODE_MATCH_CORNERS_AND_SIDES = 0, + TERRAIN_MODE_MATCH_CORNERS, + TERRAIN_MODE_MATCH_SIDES, }; - struct AutotileData { - BitmaskMode bitmask_mode = BITMASK_2X2; - // Default size to prevent invalid value - Size2 size = Size2(64, 64); - Vector2 icon_coord = Vector2(0, 0); - int spacing = 0; - Map<Vector2, uint32_t> flags; - Map<Vector2, Ref<OccluderPolygon2D>> occluder_map; - Map<Vector2, Ref<NavigationPolygon>> navpoly_map; - Map<Vector2, int> priority_map; - Map<Vector2, int> z_index_map; - - explicit AutotileData() {} + enum TileShape { + TILE_SHAPE_SQUARE, + TILE_SHAPE_ISOMETRIC, + TILE_SHAPE_HALF_OFFSET_SQUARE, + TILE_SHAPE_HEXAGON, }; -private: - struct TileData { - String name; - Ref<Texture2D> texture; - Vector2 offset; - Rect2i region; - Vector<ShapeData> shapes_data; - Vector2 occluder_offset; - Ref<OccluderPolygon2D> occluder; - Vector2 navigation_polygon_offset; - Ref<NavigationPolygon> navigation_polygon; - Ref<ShaderMaterial> material; - TileMode tile_mode = SINGLE_TILE; - // Default modulate for back-compat - Color modulate = Color(1, 1, 1); - AutotileData autotile_data; - int z_index = 0; + enum TileLayout { + TILE_LAYOUT_STACKED, + TILE_LAYOUT_STACKED_OFFSET, + TILE_LAYOUT_STAIRS_RIGHT, + TILE_LAYOUT_STAIRS_DOWN, + TILE_LAYOUT_DIAMOND_RIGHT, + TILE_LAYOUT_DIAMOND_DOWN, + }; - explicit TileData() {} + enum TileOffsetAxis { + TILE_OFFSET_AXIS_HORIZONTAL, + TILE_OFFSET_AXIS_VERTICAL, }; - Map<int, TileData> tile_map; +public: + struct PackedSceneSource { + Ref<PackedScene> scene; + Vector2 offset; + }; protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; - void _tile_set_shapes(int p_id, const Array &p_shapes); - Array _tile_get_shapes(int p_id) const; - Array _get_tiles_ids() const; - void _decompose_convex_shape(Ref<Shape2D> p_shape); +private: + // --- TileSet data --- + // Basic shape and layout. + TileShape tile_shape = TILE_SHAPE_SQUARE; + TileLayout tile_layout = TILE_LAYOUT_STACKED; + TileOffsetAxis tile_offset_axis = TILE_OFFSET_AXIS_HORIZONTAL; + Size2i tile_size = Size2i(16, 16); //Size2(64, 64); + Vector2 tile_skew = Vector2(0, 0); + + // Rendering. + bool y_sorting = false; + bool uv_clipping = false; + struct OcclusionLayer { + uint32_t light_mask = 1; + bool sdf_collision = false; + }; + Vector<OcclusionLayer> occlusion_layers; + + Ref<ArrayMesh> tile_lines_mesh; + Ref<ArrayMesh> tile_filled_mesh; + bool tile_meshes_dirty = true; + + // Physics + struct PhysicsLayer { + uint32_t collision_layer = 1; + uint32_t collision_mask = 1; + Ref<PhysicsMaterial> physics_material; + }; + Vector<PhysicsLayer> physics_layers; + + // Terrains + struct Terrain { + String name; + Color color; + }; + struct TerrainSet { + TerrainMode mode = TERRAIN_MODE_MATCH_CORNERS_AND_SIDES; + Vector<Terrain> terrains; + }; + Vector<TerrainSet> terrain_sets; + + Map<TerrainMode, Map<CellNeighbor, Ref<ArrayMesh>>> terrain_bits_meshes; + bool terrain_bits_meshes_dirty = true; + + // Navigation + struct Navigationlayer { + uint32_t layers = 1; + }; + Vector<Navigationlayer> navigation_layers; + + // CustomData + struct CustomDataLayer { + String name; + Variant::Type type = Variant::NIL; + }; + Vector<CustomDataLayer> custom_data_layers; + Map<String, int> custom_data_layers_by_name; + + // Per Atlas source data. + Map<int, Ref<TileSetSource>> sources; + Vector<int> source_ids; + int next_source_id = 0; + // --------------------- + + // Plugins themselves. + Vector<TileSetPlugin *> tile_set_plugins_vector; + + void _compute_next_source_id(); + void _source_changed(); + + // Helpers + Vector<Point2> _get_square_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + Vector<Point2> _get_square_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + Vector<Point2> _get_square_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + + Vector<Point2> _get_isometric_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + Vector<Point2> _get_isometric_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + Vector<Point2> _get_isometric_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit); + + Vector<Point2> _get_half_offset_corner_or_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis); + Vector<Point2> _get_half_offset_corner_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis); + Vector<Point2> _get_half_offset_side_terrain_bit_polygon(Vector2i p_size, TileSet::CellNeighbor p_bit, float p_overlap, TileSet::TileOffsetAxis p_offset_axis); + +protected: static void _bind_methods(); +public: + // --- Plugins --- + Vector<TileSetPlugin *> get_tile_set_atlas_plugins() const; + + // --- Accessors for TileSet data --- + + // -- Shape and layout -- + void set_tile_shape(TileShape p_shape); + TileShape get_tile_shape() const; + void set_tile_layout(TileLayout p_layout); + TileLayout get_tile_layout() const; + void set_tile_offset_axis(TileOffsetAxis p_alignment); + TileOffsetAxis get_tile_offset_axis() const; + void set_tile_size(Size2i p_size); + Size2i get_tile_size() const; + + // -- Sources management -- + int get_next_source_id() const; + int get_source_count() const; + int get_source_id(int p_index) const; + int add_source(Ref<TileSetSource> p_tile_set_source, int p_source_id_override = -1); + void set_source_id(int p_source_id, int p_new_id); + void remove_source(int p_source_id); + bool has_source(int p_source_id) const; + Ref<TileSetSource> get_source(int p_source_id) const; + + // Rendering + void set_y_sorting(bool p_y_sort); + bool is_y_sorting() const; + + void set_uv_clipping(bool p_uv_clipping); + bool is_uv_clipping() const; + + void set_occlusion_layers_count(int p_occlusion_layers_count); + int get_occlusion_layers_count() const; + void set_occlusion_layer_light_mask(int p_layer_index, int p_light_mask); + int get_occlusion_layer_light_mask(int p_layer_index) const; + void set_occlusion_layer_sdf_collision(int p_layer_index, int p_sdf_collision); + bool get_occlusion_layer_sdf_collision(int p_layer_index) const; + + // Physics + void set_physics_layers_count(int p_physics_layers_count); + int get_physics_layers_count() const; + void set_physics_layer_collision_layer(int p_layer_index, uint32_t p_layer); + uint32_t get_physics_layer_collision_layer(int p_layer_index) const; + void set_physics_layer_collision_mask(int p_layer_index, uint32_t p_mask); + uint32_t get_physics_layer_collision_mask(int p_layer_index) const; + void set_physics_layer_physics_material(int p_layer_index, Ref<PhysicsMaterial> p_physics_material); + Ref<PhysicsMaterial> get_physics_layer_physics_material(int p_layer_index) const; + + // Terrains + void set_terrain_sets_count(int p_terrains_sets_count); + int get_terrain_sets_count() const; + void set_terrain_set_mode(int p_terrain_set, TerrainMode p_terrain_mode); + TerrainMode get_terrain_set_mode(int p_terrain_set) const; + void set_terrains_count(int p_terrain_set, int p_terrains_count); + int get_terrains_count(int p_terrain_set) const; + void set_terrain_name(int p_terrain_set, int p_terrain_index, String p_name); + String get_terrain_name(int p_terrain_set, int p_terrain_index) const; + void set_terrain_color(int p_terrain_set, int p_terrain_index, Color p_color); + Color get_terrain_color(int p_terrain_set, int p_terrain_index) const; + bool is_valid_peering_bit_for_mode(TileSet::TerrainMode p_terrain_mode, TileSet::CellNeighbor p_peering_bit) const; + bool is_valid_peering_bit_terrain(int p_terrain_set, TileSet::CellNeighbor p_peering_bit) const; + + // Navigation + void set_navigation_layers_count(int p_navigation_layers_count); + int get_navigation_layers_count() const; + void set_navigation_layer_layers(int p_layer_index, uint32_t p_layers); + uint32_t get_navigation_layer_layers(int p_layer_index) const; + + // Custom data + void set_custom_data_layers_count(int p_custom_data_layers_count); + int get_custom_data_layers_count() const; + int get_custom_data_layer_by_name(String p_value) const; + void set_custom_data_name(int p_layer_id, String p_value); + String get_custom_data_name(int p_layer_id) const; + void set_custom_data_type(int p_layer_id, Variant::Type p_value); + Variant::Type get_custom_data_type(int p_layer_id) const; + + // Helpers + Vector<Vector2> get_tile_shape_polygon(); + void draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>()); + + Vector<Point2> get_terrain_bit_polygon(int p_terrain_set, TileSet::CellNeighbor p_bit); + void draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, const TileData *p_tile_data); + Vector<Vector<Ref<Texture2D>>> generate_terrains_icons(Size2i p_size); + + // Resource management virtual void reset_state() override; + TileSet(); + ~TileSet(); +}; + +class TileSetSource : public Resource { + GDCLASS(TileSetSource, Resource); + +protected: + const TileSet *tile_set = nullptr; + public: - void create_tile(int p_id); + static const Vector2i INVALID_ATLAS_COORDS; // Vector2i(-1, -1); + static const int INVALID_TILE_ALTERNATIVE; // -1; + + // Not exposed. + virtual void set_tile_set(const TileSet *p_tile_set); + virtual void notify_tile_data_properties_should_change(){}; + virtual void reset_state() override{}; + + // Tiles. + virtual int get_tiles_count() const = 0; + virtual Vector2i get_tile_id(int tile_index) const = 0; + virtual bool has_tile(Vector2i p_atlas_coords) const = 0; + + // Alternative tiles. + virtual int get_alternative_tiles_count(const Vector2i p_atlas_coords) const = 0; + virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const = 0; + virtual bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const = 0; +}; - void autotile_set_bitmask_mode(int p_id, BitmaskMode p_mode); - BitmaskMode autotile_get_bitmask_mode(int p_id) const; +class TileSetAtlasSource : public TileSetSource { + GDCLASS(TileSetAtlasSource, TileSetSource); - void tile_set_name(int p_id, const String &p_name); - String tile_get_name(int p_id) const; +public: + struct TileAlternativesData { + Vector2i size_in_atlas = Vector2i(1, 1); + Vector2i texture_offset; + Map<int, TileData *> alternatives; + Vector<int> alternatives_ids; + int next_alternative_id = 1; + }; - void tile_set_texture(int p_id, const Ref<Texture2D> &p_texture); - Ref<Texture2D> tile_get_texture(int p_id) const; +private: + Ref<Texture2D> texture; + Vector2i margins; + Vector2i separation; + Size2i texture_region_size = Size2i(16, 16); - void tile_set_texture_offset(int p_id, const Vector2 &p_offset); - Vector2 tile_get_texture_offset(int p_id) const; + Map<Vector2i, TileAlternativesData> tiles; + Vector<Vector2i> tiles_ids; + Map<Vector2i, Vector2i> _coords_mapping_cache; // Maps any coordinate to the including tile - void tile_set_region(int p_id, const Rect2 &p_region); - Rect2 tile_get_region(int p_id) const; + TileData *_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile); + const TileData *_get_atlas_tile_data(Vector2i p_atlas_coords, int p_alternative_tile) const; - void tile_set_tile_mode(int p_id, TileMode p_tile_mode); - TileMode tile_get_tile_mode(int p_id) const; + void _compute_next_alternative_id(const Vector2i p_atlas_coords); - void autotile_set_icon_coordinate(int p_id, Vector2 coord); - Vector2 autotile_get_icon_coordinate(int p_id) const; +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; - void autotile_set_spacing(int p_id, int p_spacing); - int autotile_get_spacing(int p_id) const; + static void _bind_methods(); - void autotile_set_size(int p_id, Size2 p_size); - Size2 autotile_get_size(int p_id) const; +public: + // Not exposed. + virtual void set_tile_set(const TileSet *p_tile_set) override; + virtual void notify_tile_data_properties_should_change() override; + virtual void reset_state() override; - void autotile_clear_bitmask_map(int p_id); - void autotile_set_subtile_priority(int p_id, const Vector2 &p_coord, int p_priority); - int autotile_get_subtile_priority(int p_id, const Vector2 &p_coord); - const Map<Vector2, int> &autotile_get_priority_map(int p_id) const; + // Base properties. + void set_texture(Ref<Texture2D> p_texture); + Ref<Texture2D> get_texture() const; + void set_margins(Vector2i p_margins); + Vector2i get_margins() const; + void set_separation(Vector2i p_separation); + Vector2i get_separation() const; + void set_texture_region_size(Vector2i p_tile_size); + Vector2i get_texture_region_size() const; + + // Base tiles. + void create_tile(const Vector2i p_atlas_coords, const Vector2i p_size = Vector2i(1, 1)); // Create a tile if it does not exists, or add alternative tile if it does. + void remove_tile(Vector2i p_atlas_coords); // Remove a tile. If p_tile_key.alternative_tile if different from 0, remove the alternative + virtual bool has_tile(Vector2i p_atlas_coords) const override; + bool can_move_tile_in_atlas(Vector2i p_atlas_coords, Vector2i p_new_atlas_coords = INVALID_ATLAS_COORDS, Vector2i p_new_size = Vector2i(-1, -1)) const; + void move_tile_in_atlas(Vector2i p_atlas_coords, Vector2i p_new_atlas_coords = INVALID_ATLAS_COORDS, Vector2i p_new_size = Vector2i(-1, -1)); + Vector2i get_tile_size_in_atlas(Vector2i p_atlas_coords) const; + + virtual int get_tiles_count() const override; + virtual Vector2i get_tile_id(int p_index) const override; + + Vector2i get_tile_at_coords(Vector2i p_atlas_coords) const; + + // Alternative tiles. + int create_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_id_override = -1); + void remove_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile); + void set_alternative_tile_id(const Vector2i p_atlas_coords, int p_alternative_tile, int p_new_id); + virtual bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override; + int get_next_alternative_tile_id(const Vector2i p_atlas_coords) const; + + virtual int get_alternative_tiles_count(const Vector2i p_atlas_coords) const override; + virtual int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override; + + // Get data associated to a tile. + Object *get_tile_data(const Vector2i p_atlas_coords, int p_alternative_tile) const; + + // Helpers. + Vector2i get_atlas_grid_size() const; + bool has_tiles_outside_texture(); + void clear_tiles_outside_texture(); + Rect2i get_tile_texture_region(Vector2i p_atlas_coords) const; + Vector2i get_tile_effective_texture_offset(Vector2i p_atlas_coords, int p_alternative_tile) const; + + ~TileSetAtlasSource(); +}; - void autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index); - int autotile_get_z_index(int p_id, const Vector2 &p_coord); - const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const; +class TileSetScenesCollectionSource : public TileSetSource { + GDCLASS(TileSetScenesCollectionSource, TileSetSource); - void autotile_set_bitmask(int p_id, Vector2 p_coord, uint32_t p_flag); - uint32_t autotile_get_bitmask(int p_id, Vector2 p_coord); - const Map<Vector2, uint32_t> &autotile_get_bitmask_map(int p_id); - Vector2 autotile_get_subtile_for_bitmask(int p_id, uint16_t p_bitmask, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2()); - Vector2 atlastile_get_subtile_by_priority(int p_id, const Node *p_tilemap_node = nullptr, const Vector2 &p_tile_location = Vector2()); +private: + struct SceneData { + Ref<PackedScene> scene; + bool display_placeholder = false; + }; + Vector<int> scenes_ids; + Map<int, SceneData> scenes; + int next_scene_id = 1; - void tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_shape); - Ref<Shape2D> tile_get_shape(int p_id, int p_shape_id) const; + void _compute_next_alternative_id(); - void tile_set_shape_transform(int p_id, int p_shape_id, const Transform2D &p_offset); - Transform2D tile_get_shape_transform(int p_id, int p_shape_id) const; +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; - void tile_set_shape_offset(int p_id, int p_shape_id, const Vector2 &p_offset); - Vector2 tile_get_shape_offset(int p_id, int p_shape_id) const; + static void _bind_methods(); - void tile_set_shape_one_way(int p_id, int p_shape_id, bool p_one_way); - bool tile_get_shape_one_way(int p_id, int p_shape_id) const; +public: + // Tiles. + int get_tiles_count() const override; + Vector2i get_tile_id(int p_tile_index) const override; + bool has_tile(Vector2i p_atlas_coords) const override; + + // Alternative tiles. + int get_alternative_tiles_count(const Vector2i p_atlas_coords) const override; + int get_alternative_tile_id(const Vector2i p_atlas_coords, int p_index) const override; + bool has_alternative_tile(const Vector2i p_atlas_coords, int p_alternative_tile) const override; + + // Scenes sccessors. Lot are similar to "Alternative tiles". + int get_scene_tiles_count() { return get_alternative_tiles_count(Vector2i()); } + int get_scene_tile_id(int p_index) { return get_alternative_tile_id(Vector2i(), p_index); }; + bool has_scene_tile_id(int p_id) { return has_alternative_tile(Vector2i(), p_id); }; + int create_scene_tile(Ref<PackedScene> p_packed_scene = Ref<PackedScene>(), int p_id_override = -1); + void set_scene_tile_id(int p_id, int p_new_id); + void set_scene_tile_scene(int p_id, Ref<PackedScene> p_packed_scene); + Ref<PackedScene> get_scene_tile_scene(int p_id) const; + void set_scene_tile_display_placeholder(int p_id, bool p_packed_scene); + bool get_scene_tile_display_placeholder(int p_id) const; + void remove_scene_tile(int p_id); + int get_next_scene_tile_id() const; +}; - void tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_margin); - float tile_get_shape_one_way_margin(int p_id, int p_shape_id) const; +class TileData : public Object { + GDCLASS(TileData, Object); - void tile_clear_shapes(int p_id); - void tile_add_shape(int p_id, const Ref<Shape2D> &p_shape, const Transform2D &p_transform, bool p_one_way = false, const Vector2 &p_autotile_coord = Vector2()); - int tile_get_shape_count(int p_id) const; +private: + const TileSet *tile_set = nullptr; + bool allow_transform = true; + + // Rendering + bool flip_h = false; + bool flip_v = false; + bool transpose = false; + Vector2i tex_offset = Vector2i(); + Ref<ShaderMaterial> material = Ref<ShaderMaterial>(); + Color modulate = Color(1.0, 1.0, 1.0, 1.0); + int z_index = 0; + int y_sort_origin = 0; + Vector<Ref<OccluderPolygon2D>> occluders; + + // Physics + struct PhysicsLayerTileData { + struct PolygonShapeTileData { + LocalVector<Vector2> polygon; + LocalVector<Ref<ConvexPolygonShape2D>> shapes; + bool one_way = false; + float one_way_margin = 1.0; + }; + + Vector<PolygonShapeTileData> polygons; + }; + Vector<PhysicsLayerTileData> physics; + // TODO add support for areas. - void tile_set_shapes(int p_id, const Vector<ShapeData> &p_shapes); - Vector<ShapeData> tile_get_shapes(int p_id) const; + // Terrain + int terrain_set = -1; + int terrain_peering_bits[16] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; - void tile_set_material(int p_id, const Ref<ShaderMaterial> &p_material); - Ref<ShaderMaterial> tile_get_material(int p_id) const; + // Navigation + Vector<Ref<NavigationPolygon>> navigation; - void tile_set_modulate(int p_id, const Color &p_modulate); - Color tile_get_modulate(int p_id) const; + // Misc + double probability = 1.0; - void tile_set_occluder_offset(int p_id, const Vector2 &p_offset); - Vector2 tile_get_occluder_offset(int p_id) const; + // Custom data + Vector<Variant> custom_data; - void tile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder); - Ref<OccluderPolygon2D> tile_get_light_occluder(int p_id) const; +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + static void _bind_methods(); - void autotile_set_light_occluder(int p_id, const Ref<OccluderPolygon2D> &p_light_occluder, const Vector2 &p_coord); - Ref<OccluderPolygon2D> autotile_get_light_occluder(int p_id, const Vector2 &p_coord) const; - const Map<Vector2, Ref<OccluderPolygon2D>> &autotile_get_light_oclusion_map(int p_id) const; +public: + // Not exposed. + void set_tile_set(const TileSet *p_tile_set); + void notify_tile_data_properties_should_change(); + void reset_state(); + void set_allow_transform(bool p_allow_transform); + bool is_allowing_transform() const; + + // Rendering + void set_flip_h(bool p_flip_h); + bool get_flip_h() const; + void set_flip_v(bool p_flip_v); + bool get_flip_v() const; + void set_transpose(bool p_transpose); + bool get_transpose() const; + + void set_texture_offset(Vector2i p_texture_offset); + Vector2i get_texture_offset() const; + void tile_set_material(Ref<ShaderMaterial> p_material); + Ref<ShaderMaterial> tile_get_material() const; + void set_modulate(Color p_modulate); + Color get_modulate() const; + void set_z_index(int p_z_index); + int get_z_index() const; + void set_y_sort_origin(int p_y_sort_origin); + int get_y_sort_origin() const; + + void set_occluder(int p_layer_id, Ref<OccluderPolygon2D> p_occluder_polygon); + Ref<OccluderPolygon2D> get_occluder(int p_layer_id) const; + + // Physics + int get_collision_polygons_count(int p_layer_id) const; + void set_collision_polygons_count(int p_layer_id, int p_shapes_count); + void add_collision_polygon(int p_layer_id); + void remove_collision_polygon(int p_layer_id, int p_polygon_index); + void set_collision_polygon_points(int p_layer_id, int p_polygon_index, Vector<Vector2> p_polygon); + Vector<Vector2> get_collision_polygon_points(int p_layer_id, int p_polygon_index) const; + void set_collision_polygon_one_way(int p_layer_id, int p_polygon_index, bool p_one_way); + bool is_collision_polygon_one_way(int p_layer_id, int p_polygon_index) const; + void set_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index, float p_one_way_margin); + float get_collision_polygon_one_way_margin(int p_layer_id, int p_polygon_index) const; + int get_collision_polygon_shapes_count(int p_layer_id, int p_polygon_index) const; + Ref<ConvexPolygonShape2D> get_collision_polygon_shape(int p_layer_id, int p_polygon_index, int shape_index) const; + + // Terrain + void set_terrain_set(int p_terrain_id); + int get_terrain_set() const; + void set_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit, int p_terrain_id); + int get_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit) const; + bool is_valid_peering_bit_terrain(TileSet::CellNeighbor p_peering_bit) const; + + // Navigation + void set_navigation_polygon(int p_layer_id, Ref<NavigationPolygon> p_navigation_polygon); + Ref<NavigationPolygon> get_navigation_polygon(int p_layer_id) const; + + // Misc + void set_probability(float p_probability); + float get_probability() const; + + // Custom data. + void set_custom_data(String p_layer_name, Variant p_value); + Variant get_custom_data(String p_layer_name) const; + void set_custom_data_by_layer_id(int p_layer_id, Variant p_value); + Variant get_custom_data_by_layer_id(int p_layer_id) const; +}; - void tile_set_navigation_polygon_offset(int p_id, const Vector2 &p_offset); - Vector2 tile_get_navigation_polygon_offset(int p_id) const; +#include "scene/2d/tile_map.h" - void tile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon); - Ref<NavigationPolygon> tile_get_navigation_polygon(int p_id) const; +class TileSetPlugin : public Object { + GDCLASS(TileSetPlugin, Object); - void autotile_set_navigation_polygon(int p_id, const Ref<NavigationPolygon> &p_navigation_polygon, const Vector2 &p_coord); - Ref<NavigationPolygon> autotile_get_navigation_polygon(int p_id, const Vector2 &p_coord) const; - const Map<Vector2, Ref<NavigationPolygon>> &autotile_get_navigation_map(int p_id) const; +public: + // Tilemap updates. + virtual void tilemap_notification(TileMap *p_tile_map, int p_what){}; + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list){}; + virtual void create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant){}; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant){}; - void tile_set_z_index(int p_id, int p_z_index); - int tile_get_z_index(int p_id) const; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant){}; +}; + +class TileSetPluginAtlasRendering : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasRendering, TileSetPlugin); + +private: + static constexpr float fp_adjust = 0.00001; + bool quadrant_order_dirty = false; - void remove_tile(int p_id); +public: + // Tilemap updates + virtual void tilemap_notification(TileMap *p_tile_map, int p_what) override; + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; + virtual void create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + + // Other. + static void draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0)); +}; - bool has_tile(int p_id) const; +class TileSetPluginAtlasPhysics : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasPhysics, TileSetPlugin); - bool is_tile_bound(int p_drawn_id, int p_neighbor_id); +public: + // Tilemap updates + virtual void tilemap_notification(TileMap *p_tile_map, int p_what) override; + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; + virtual void create_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; +}; - int find_tile_by_name(const String &p_name) const; - void get_tile_list(List<int> *p_tiles) const; +class TileSetPluginAtlasNavigation : public TileSetPlugin { + GDCLASS(TileSetPluginAtlasNavigation, TileSetPlugin); - void clear(); +public: + // Tilemap updates + virtual void tilemap_notification(TileMap *p_tile_map, int p_what) override; + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; +}; - int get_last_unused_tile_id() const; +class TileSetPluginScenesCollections : public TileSetPlugin { + GDCLASS(TileSetPluginScenesCollections, TileSetPlugin); - TileSet(); +public: + // Tilemap updates + virtual void update_dirty_quadrants(TileMap *p_tile_map, SelfList<TileMapQuadrant>::List &r_dirty_quadrant_list) override; + virtual void cleanup_quadrant(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; + virtual void draw_quadrant_debug(TileMap *p_tile_map, TileMapQuadrant *p_quadrant) override; }; -VARIANT_ENUM_CAST(TileSet::AutotileBindings); -VARIANT_ENUM_CAST(TileSet::BitmaskMode); -VARIANT_ENUM_CAST(TileSet::TileMode); +VARIANT_ENUM_CAST(TileSet::CellNeighbor); +VARIANT_ENUM_CAST(TileSet::TerrainMode); +VARIANT_ENUM_CAST(TileSet::TileShape); +VARIANT_ENUM_CAST(TileSet::TileLayout); +VARIANT_ENUM_CAST(TileSet::TileOffsetAxis); #endif // TILE_SET_H |