Merge pull request #87115 from groud/tilemap_layers_as_nodes
Make TileMapLayers extend Node2D and work as children of TileMap
This commit is contained in:
commit
788aab3a96
11 changed files with 1118 additions and 1082 deletions
1
editor/icons/TileMapLayer.svg
Normal file
1
editor/icons/TileMapLayer.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 7v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2zm3 0v2h2v-2z" fill="#8da5f3"/></svg>
|
After Width: | Height: | Size: 176 B |
|
@ -51,3 +51,11 @@ Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/texture_u
|
|||
Barrier arguments have been removed from all relevant functions as they're no longer required.
|
||||
Draw and compute list overlap no longer needs to be specified.
|
||||
Initial and final actions have been simplified into fewer options.
|
||||
|
||||
|
||||
GH-87115
|
||||
--------
|
||||
Validate extension JSON: Error: Field 'classes/TileMap/methods/get_collision_visibility_mode': is_const changed value in new API, from false to true.
|
||||
Validate extension JSON: Error: Field 'classes/TileMap/methods/get_navigation_visibility_mode': is_const changed value in new API, from false to true.
|
||||
|
||||
Two TileMap getters were made const. No adjustments should be necessary.
|
||||
|
|
|
@ -42,10 +42,20 @@ int TileMap::_get_quadrant_size_compat_81070() const {
|
|||
return get_rendering_quadrant_size();
|
||||
}
|
||||
|
||||
TileMap::VisibilityMode TileMap::_get_collision_visibility_mode_bind_compat_87115() {
|
||||
return get_collision_visibility_mode();
|
||||
}
|
||||
|
||||
TileMap::VisibilityMode TileMap::_get_navigation_visibility_mode_bind_compat_87115() {
|
||||
return get_navigation_visibility_mode();
|
||||
}
|
||||
|
||||
void TileMap::_bind_compatibility_methods() {
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_used_rect"), &TileMap::_get_used_rect_bind_compat_78328);
|
||||
ClassDB::bind_compatibility_method(D_METHOD("set_quadrant_size", "quadrant_size"), &TileMap::_set_quadrant_size_compat_81070);
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_quadrant_size"), &TileMap::_get_quadrant_size_compat_81070);
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_collision_visibility_mode"), &TileMap::_get_collision_visibility_mode_bind_compat_87115);
|
||||
ClassDB::bind_compatibility_method(D_METHOD("get_navigation_visibility_mode"), &TileMap::_get_navigation_visibility_mode_bind_compat_87115);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -71,18 +71,17 @@ private:
|
|||
VisibilityMode navigation_visibility_mode = VISIBILITY_MODE_DEFAULT;
|
||||
|
||||
// Layers.
|
||||
LocalVector<Ref<TileMapLayer>> layers;
|
||||
Ref<TileMapLayer> default_layer; // Dummy layer to fetch default values.
|
||||
LocalVector<TileMapLayer *> layers;
|
||||
TileMapLayer *default_layer; // Dummy layer to fetch default values.
|
||||
int selected_layer = -1;
|
||||
bool pending_update = false;
|
||||
|
||||
// Transforms for collision_animatable.
|
||||
Transform2D last_valid_transform;
|
||||
Transform2D new_transform;
|
||||
|
||||
void _tile_set_changed();
|
||||
|
||||
void _update_notify_local_transform();
|
||||
|
||||
protected:
|
||||
bool _set(const StringName &p_name, const Variant &p_value);
|
||||
bool _get(const StringName &p_name, Variant &r_ret) const;
|
||||
|
@ -97,6 +96,8 @@ protected:
|
|||
Rect2i _get_used_rect_bind_compat_78328();
|
||||
void _set_quadrant_size_compat_81070(int p_quadrant_size);
|
||||
int _get_quadrant_size_compat_81070() const;
|
||||
VisibilityMode _get_collision_visibility_mode_bind_compat_87115();
|
||||
VisibilityMode _get_navigation_visibility_mode_bind_compat_87115();
|
||||
|
||||
static void _bind_compatibility_methods();
|
||||
#endif
|
||||
|
@ -150,15 +151,15 @@ public:
|
|||
void set_selected_layer(int p_layer_id); // For editor use.
|
||||
int get_selected_layer() const;
|
||||
|
||||
void set_collision_animatable(bool p_enabled);
|
||||
void set_collision_animatable(bool p_collision_animatable);
|
||||
bool is_collision_animatable() const;
|
||||
|
||||
// Debug visibility modes.
|
||||
void set_collision_visibility_mode(VisibilityMode p_show_collision);
|
||||
VisibilityMode get_collision_visibility_mode();
|
||||
VisibilityMode get_collision_visibility_mode() const;
|
||||
|
||||
void set_navigation_visibility_mode(VisibilityMode p_show_navigation);
|
||||
VisibilityMode get_navigation_visibility_mode();
|
||||
VisibilityMode get_navigation_visibility_mode() const;
|
||||
|
||||
// Cells accessors.
|
||||
void set_cell(int p_layer, const Vector2i &p_coords, int p_source_id = TileSet::INVALID_SOURCE, const Vector2i p_atlas_coords = TileSetSource::INVALID_ATLAS_COORDS, int p_alternative_tile = 0);
|
||||
|
@ -192,7 +193,6 @@ public:
|
|||
|
||||
Vector2 map_to_local(const Vector2i &p_pos) const;
|
||||
Vector2i local_to_map(const Vector2 &p_pos) const;
|
||||
|
||||
bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const;
|
||||
Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ class TileSetAtlasSource;
|
|||
|
||||
class TerrainConstraint {
|
||||
private:
|
||||
const TileMap *tile_map = nullptr;
|
||||
Ref<TileSet> tile_set;
|
||||
Vector2i base_cell_coords;
|
||||
int bit = -1;
|
||||
int terrain = -1;
|
||||
|
@ -83,8 +83,8 @@ public:
|
|||
return priority;
|
||||
}
|
||||
|
||||
TerrainConstraint(const TileMap *p_tile_map, const Vector2i &p_position, int p_terrain); // For the center terrain bit
|
||||
TerrainConstraint(const TileMap *p_tile_map, const Vector2i &p_position, const TileSet::CellNeighbor &p_bit, int p_terrain); // For peering bits
|
||||
TerrainConstraint(Ref<TileSet> p_tile_set, const Vector2i &p_position, int p_terrain); // For the center terrain bit
|
||||
TerrainConstraint(Ref<TileSet> p_tile_set, const Vector2i &p_position, const TileSet::CellNeighbor &p_bit, int p_terrain); // For peering bits
|
||||
TerrainConstraint(){};
|
||||
};
|
||||
|
||||
|
@ -214,23 +214,24 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class TileMapLayer : public RefCounted {
|
||||
GDCLASS(TileMapLayer, RefCounted);
|
||||
class TileMapLayer : public Node2D {
|
||||
GDCLASS(TileMapLayer, Node2D);
|
||||
|
||||
public:
|
||||
enum DirtyFlags {
|
||||
DIRTY_FLAGS_LAYER_ENABLED = 0,
|
||||
DIRTY_FLAGS_LAYER_MODULATE,
|
||||
DIRTY_FLAGS_LAYER_IN_TREE,
|
||||
DIRTY_FLAGS_LAYER_IN_CANVAS,
|
||||
DIRTY_FLAGS_LAYER_LOCAL_TRANSFORM,
|
||||
DIRTY_FLAGS_LAYER_VISIBILITY,
|
||||
DIRTY_FLAGS_LAYER_SELF_MODULATE,
|
||||
DIRTY_FLAGS_LAYER_Y_SORT_ENABLED,
|
||||
DIRTY_FLAGS_LAYER_Y_SORT_ORIGIN,
|
||||
DIRTY_FLAGS_LAYER_Z_INDEX,
|
||||
DIRTY_FLAGS_LAYER_USE_KINEMATIC_BODIES,
|
||||
DIRTY_FLAGS_LAYER_NAVIGATION_ENABLED,
|
||||
DIRTY_FLAGS_LAYER_INDEX_IN_TILE_MAP_NODE,
|
||||
DIRTY_FLAGS_TILE_MAP_IN_TREE,
|
||||
DIRTY_FLAGS_TILE_MAP_IN_CANVAS,
|
||||
DIRTY_FLAGS_TILE_MAP_VISIBILITY,
|
||||
DIRTY_FLAGS_TILE_MAP_XFORM,
|
||||
DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM,
|
||||
|
||||
DIRTY_FLAGS_TILE_MAP_SELECTED_LAYER,
|
||||
DIRTY_FLAGS_TILE_MAP_LIGHT_MASK,
|
||||
DIRTY_FLAGS_TILE_MAP_MATERIAL,
|
||||
|
@ -239,7 +240,6 @@ public:
|
|||
DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT,
|
||||
DIRTY_FLAGS_TILE_MAP_TILE_SET,
|
||||
DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE,
|
||||
DIRTY_FLAGS_TILE_MAP_COLLISION_ANIMATABLE,
|
||||
DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE,
|
||||
DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE,
|
||||
DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED,
|
||||
|
@ -249,20 +249,15 @@ public:
|
|||
|
||||
private:
|
||||
// Exposed properties.
|
||||
String name;
|
||||
bool enabled = true;
|
||||
Color modulate = Color(1, 1, 1, 1);
|
||||
bool y_sort_enabled = false;
|
||||
int y_sort_origin = 0;
|
||||
int z_index = 0;
|
||||
bool use_kinematic_bodies = false;
|
||||
bool navigation_enabled = true;
|
||||
RID navigation_map;
|
||||
bool uses_world_navigation_map = false;
|
||||
|
||||
// Internal.
|
||||
TileMap *tile_map_node = nullptr;
|
||||
int layer_index_in_tile_map_node = -1;
|
||||
RID canvas_item;
|
||||
HashMap<Vector2i, CellData> tile_map;
|
||||
|
||||
// Dirty flag. Allows knowing what was modified since the last update.
|
||||
|
@ -278,6 +273,10 @@ private:
|
|||
mutable Rect2i used_rect_cache;
|
||||
mutable bool used_rect_cache_dirty = true;
|
||||
|
||||
// Method to fetch the TileSet to use
|
||||
TileMap *_fetch_tilemap() const;
|
||||
Ref<TileSet> _fetch_tileset() const;
|
||||
|
||||
// Runtime tile data.
|
||||
bool _runtime_update_tile_data_was_cleaned_up = false;
|
||||
void _build_runtime_update_tile_data();
|
||||
|
@ -296,6 +295,7 @@ private:
|
|||
HashMap<Vector2i, Ref<RenderingQuadrant>> rendering_quadrant_map;
|
||||
bool _rendering_was_cleaned_up = false;
|
||||
void _rendering_update();
|
||||
void _rendering_notification(int p_what);
|
||||
void _rendering_quadrants_update_cell(CellData &r_cell_data, SelfList<RenderingQuadrant>::List &r_dirty_rendering_quadrant_list);
|
||||
void _rendering_occluders_clear_cell(CellData &r_cell_data);
|
||||
void _rendering_occluders_update_cell(CellData &r_cell_data);
|
||||
|
@ -306,7 +306,7 @@ private:
|
|||
HashMap<RID, Vector2i> bodies_coords; // Mapping for RID to coords.
|
||||
bool _physics_was_cleaned_up = false;
|
||||
void _physics_update();
|
||||
void _physics_notify_tilemap_change(DirtyFlags p_what);
|
||||
void _physics_notification(int p_what);
|
||||
void _physics_clear_cell(CellData &r_cell_data);
|
||||
void _physics_update_cell(CellData &r_cell_data);
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
@ -315,6 +315,7 @@ private:
|
|||
|
||||
bool _navigation_was_cleaned_up = false;
|
||||
void _navigation_update();
|
||||
void _navigation_notification(int p_what);
|
||||
void _navigation_clear_cell(CellData &r_cell_data);
|
||||
void _navigation_update_cell(CellData &r_cell_data);
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
@ -334,9 +335,14 @@ private:
|
|||
RBSet<TerrainConstraint> _get_terrain_constraints_from_added_pattern(const Vector2i &p_position, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern) const;
|
||||
RBSet<TerrainConstraint> _get_terrain_constraints_from_painted_cells_list(const RBSet<Vector2i> &p_painted, int p_terrain_set, bool p_ignore_empty_terrains) const;
|
||||
|
||||
void _renamed();
|
||||
void _update_notify_local_transform();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
public:
|
||||
// TileMap node.
|
||||
void set_tile_map(TileMap *p_tile_map);
|
||||
void set_layer_index_in_tile_map_node(int p_index);
|
||||
|
||||
// Rect caching.
|
||||
|
@ -383,18 +389,15 @@ public:
|
|||
Rect2i get_used_rect() const;
|
||||
|
||||
// Layer properties.
|
||||
void set_name(String p_name);
|
||||
String get_name() const;
|
||||
void set_enabled(bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
void set_modulate(Color p_modulate);
|
||||
Color get_modulate() const;
|
||||
void set_y_sort_enabled(bool p_y_sort_enabled);
|
||||
bool is_y_sort_enabled() const;
|
||||
virtual void set_self_modulate(const Color &p_self_modulate) override;
|
||||
virtual void set_y_sort_enabled(bool p_y_sort_enabled) override;
|
||||
void set_y_sort_origin(int p_y_sort_origin);
|
||||
int get_y_sort_origin() const;
|
||||
void set_z_index(int p_z_index);
|
||||
int get_z_index() const;
|
||||
virtual void set_z_index(int p_z_index) override;
|
||||
void set_use_kinematic_bodies(bool p_use_kinematic_bodies);
|
||||
bool is_using_kinematic_bodies() const;
|
||||
void set_navigation_enabled(bool p_enabled);
|
||||
bool is_navigation_enabled() const;
|
||||
void set_navigation_map(RID p_map);
|
||||
|
@ -407,6 +410,7 @@ public:
|
|||
bool has_body_rid(RID p_physics_body) const;
|
||||
Vector2i get_coords_for_body_rid(RID p_physics_body) const; // For finding tiles from collision.
|
||||
|
||||
TileMapLayer();
|
||||
~TileMapLayer();
|
||||
};
|
||||
|
||||
|
|
|
@ -277,6 +277,8 @@ void CanvasItem::_notification(int p_what) {
|
|||
ERR_MAIN_THREAD_GUARD;
|
||||
ERR_FAIL_COND(!is_inside_tree());
|
||||
|
||||
_set_global_invalid(true);
|
||||
|
||||
Node *parent = get_parent();
|
||||
if (parent) {
|
||||
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
|
||||
|
|
|
@ -237,7 +237,7 @@ public:
|
|||
Color get_modulate() const;
|
||||
Color get_modulate_in_tree() const;
|
||||
|
||||
void set_self_modulate(const Color &p_self_modulate);
|
||||
virtual void set_self_modulate(const Color &p_self_modulate);
|
||||
Color get_self_modulate() const;
|
||||
|
||||
void set_visibility_layer(uint32_t p_visibility_layer);
|
||||
|
@ -248,7 +248,7 @@ public:
|
|||
|
||||
/* ORDERING */
|
||||
|
||||
void set_z_index(int p_z);
|
||||
virtual void set_z_index(int p_z);
|
||||
int get_z_index() const;
|
||||
int get_effective_z_index() const;
|
||||
|
||||
|
|
|
@ -1563,6 +1563,632 @@ void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform
|
|||
}
|
||||
}
|
||||
|
||||
Vector2 TileSet::map_to_local(const Vector2i &p_pos) const {
|
||||
// SHOULD RETURN THE CENTER OF THE CELL.
|
||||
Vector2 ret = p_pos;
|
||||
|
||||
if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
// Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap.
|
||||
// square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap.
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
switch (tile_layout) {
|
||||
case TileSet::TILE_LAYOUT_STACKED:
|
||||
ret = Vector2(ret.x + (Math::posmod(ret.y, 2) == 0 ? 0.0 : 0.5), ret.y);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STACKED_OFFSET:
|
||||
ret = Vector2(ret.x + (Math::posmod(ret.y, 2) == 1 ? 0.0 : 0.5), ret.y);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
|
||||
ret = Vector2(ret.x + ret.y / 2, ret.y);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_DOWN:
|
||||
ret = Vector2(ret.x / 2, ret.y * 2 + ret.x);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
|
||||
ret = Vector2((ret.x + ret.y) / 2, ret.y - ret.x);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
|
||||
ret = Vector2((ret.x - ret.y) / 2, ret.y + ret.x);
|
||||
break;
|
||||
}
|
||||
} else { // TILE_OFFSET_AXIS_VERTICAL.
|
||||
switch (tile_layout) {
|
||||
case TileSet::TILE_LAYOUT_STACKED:
|
||||
ret = Vector2(ret.x, ret.y + (Math::posmod(ret.x, 2) == 0 ? 0.0 : 0.5));
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STACKED_OFFSET:
|
||||
ret = Vector2(ret.x, ret.y + (Math::posmod(ret.x, 2) == 1 ? 0.0 : 0.5));
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
|
||||
ret = Vector2(ret.x * 2 + ret.y, ret.y / 2);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_DOWN:
|
||||
ret = Vector2(ret.x, ret.y + ret.x / 2);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
|
||||
ret = Vector2(ret.x + ret.y, (ret.y - ret.x) / 2);
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
|
||||
ret = Vector2(ret.x - ret.y, (ret.y + ret.x) / 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply by the overlapping ratio.
|
||||
double overlapping_ratio = 1.0;
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
overlapping_ratio = 0.5;
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
|
||||
overlapping_ratio = 0.75;
|
||||
}
|
||||
ret.y *= overlapping_ratio;
|
||||
} else { // TILE_OFFSET_AXIS_VERTICAL.
|
||||
if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
overlapping_ratio = 0.5;
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
|
||||
overlapping_ratio = 0.75;
|
||||
}
|
||||
ret.x *= overlapping_ratio;
|
||||
}
|
||||
|
||||
return (ret + Vector2(0.5, 0.5)) * tile_size;
|
||||
}
|
||||
|
||||
Vector2i TileSet::local_to_map(const Vector2 &p_local_position) const {
|
||||
Vector2 ret = p_local_position;
|
||||
ret /= tile_size;
|
||||
|
||||
// Divide by the overlapping ratio.
|
||||
double overlapping_ratio = 1.0;
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
overlapping_ratio = 0.5;
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
|
||||
overlapping_ratio = 0.75;
|
||||
}
|
||||
ret.y /= overlapping_ratio;
|
||||
} else { // TILE_OFFSET_AXIS_VERTICAL.
|
||||
if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
overlapping_ratio = 0.5;
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_HEXAGON) {
|
||||
overlapping_ratio = 0.75;
|
||||
}
|
||||
ret.x /= overlapping_ratio;
|
||||
}
|
||||
|
||||
// For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the local position accordingly.
|
||||
if (tile_shape == TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE || tile_shape == TileSet::TILE_SHAPE_HEXAGON || tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
// Technically, those 3 shapes are equivalent, as they are basically half-offset, but with different levels or overlap.
|
||||
// square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap.
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
// Smart floor of the position
|
||||
Vector2 raw_pos = ret;
|
||||
if (Math::posmod(Math::floor(ret.y), 2) ^ (tile_layout == TileSet::TILE_LAYOUT_STACKED_OFFSET)) {
|
||||
ret = Vector2(Math::floor(ret.x + 0.5) - 0.5, Math::floor(ret.y));
|
||||
} else {
|
||||
ret = ret.floor();
|
||||
}
|
||||
|
||||
// Compute the tile offset, and if we might the output for a neighbor top tile.
|
||||
Vector2 in_tile_pos = raw_pos - ret;
|
||||
bool in_top_left_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(-0.5, 1.0 / overlapping_ratio - 1)) <= 0;
|
||||
bool in_top_right_triangle = (in_tile_pos - Vector2(0.5, 0.0)).cross(Vector2(0.5, 1.0 / overlapping_ratio - 1)) > 0;
|
||||
|
||||
switch (tile_layout) {
|
||||
case TileSet::TILE_LAYOUT_STACKED:
|
||||
ret = ret.floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 0 : -1, -1);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 1 : 0, -1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STACKED_OFFSET:
|
||||
ret = ret.floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? -1 : 0, -1);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(Math::posmod(Math::floor(ret.y), 2) ? 0 : 1, -1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
|
||||
ret = Vector2(ret.x - ret.y / 2, ret.y).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(0, -1);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(1, -1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_DOWN:
|
||||
ret = Vector2(ret.x * 2, ret.y / 2 - ret.x).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, 0);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(1, -1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
|
||||
ret = Vector2(ret.x - ret.y / 2, ret.y / 2 + ret.x).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(0, -1);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(1, 0);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
|
||||
ret = Vector2(ret.x + ret.y / 2, ret.y / 2 - ret.x).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, 0);
|
||||
} else if (in_top_right_triangle) {
|
||||
ret += Vector2i(0, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else { // TILE_OFFSET_AXIS_VERTICAL.
|
||||
// Smart floor of the position.
|
||||
Vector2 raw_pos = ret;
|
||||
if (Math::posmod(Math::floor(ret.x), 2) ^ (tile_layout == TileSet::TILE_LAYOUT_STACKED_OFFSET)) {
|
||||
ret = Vector2(Math::floor(ret.x), Math::floor(ret.y + 0.5) - 0.5);
|
||||
} else {
|
||||
ret = ret.floor();
|
||||
}
|
||||
|
||||
// Compute the tile offset, and if we might the output for a neighbor top tile.
|
||||
Vector2 in_tile_pos = raw_pos - ret;
|
||||
bool in_top_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, -0.5)) > 0;
|
||||
bool in_bottom_left_triangle = (in_tile_pos - Vector2(0.0, 0.5)).cross(Vector2(1.0 / overlapping_ratio - 1, 0.5)) <= 0;
|
||||
|
||||
switch (tile_layout) {
|
||||
case TileSet::TILE_LAYOUT_STACKED:
|
||||
ret = ret.floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 0 : -1);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 1 : 0);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STACKED_OFFSET:
|
||||
ret = ret.floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? -1 : 0);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(-1, Math::posmod(Math::floor(ret.x), 2) ? 0 : 1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
|
||||
ret = Vector2(ret.x / 2 - ret.y, ret.y * 2).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(0, -1);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(-1, 1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_DOWN:
|
||||
ret = Vector2(ret.x, ret.y - ret.x / 2).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, 0);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(-1, 1);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
|
||||
ret = Vector2(ret.x / 2 - ret.y, ret.y + ret.x / 2).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(0, -1);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(-1, 0);
|
||||
}
|
||||
break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_DOWN:
|
||||
ret = Vector2(ret.x / 2 + ret.y, ret.y - ret.x / 2).floor();
|
||||
if (in_top_left_triangle) {
|
||||
ret += Vector2i(-1, 0);
|
||||
} else if (in_bottom_left_triangle) {
|
||||
ret += Vector2i(0, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ret = (ret + Vector2(0.00005, 0.00005)).floor();
|
||||
}
|
||||
return Vector2i(ret);
|
||||
}
|
||||
|
||||
bool TileSet::is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const {
|
||||
if (tile_shape == TileSet::TILE_SHAPE_SQUARE) {
|
||||
return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER;
|
||||
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC) {
|
||||
return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
|
||||
} else {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
return p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
|
||||
} else {
|
||||
return p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE ||
|
||||
p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2i TileSet::get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const {
|
||||
if (tile_shape == TileSet::TILE_SHAPE_SQUARE) {
|
||||
switch (p_cell_neighbor) {
|
||||
case TileSet::CELL_NEIGHBOR_RIGHT_SIDE:
|
||||
return p_coords + Vector2i(1, 0);
|
||||
case TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_CORNER:
|
||||
return p_coords + Vector2i(1, 1);
|
||||
case TileSet::CELL_NEIGHBOR_BOTTOM_SIDE:
|
||||
return p_coords + Vector2i(0, 1);
|
||||
case TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_CORNER:
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
case TileSet::CELL_NEIGHBOR_LEFT_SIDE:
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
case TileSet::CELL_NEIGHBOR_TOP_LEFT_CORNER:
|
||||
return p_coords + Vector2i(-1, -1);
|
||||
case TileSet::CELL_NEIGHBOR_TOP_SIDE:
|
||||
return p_coords + Vector2i(0, -1);
|
||||
case TileSet::CELL_NEIGHBOR_TOP_RIGHT_CORNER:
|
||||
return p_coords + Vector2i(1, -1);
|
||||
default:
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
} else { // Half-offset shapes (square and hexagon).
|
||||
switch (tile_layout) {
|
||||
case TileSet::TILE_LAYOUT_STACKED: {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
bool is_offset = p_coords.y % 2;
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 1 : 0, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(0, 2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 0 : -1, 1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 0 : -1, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(0, -2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 1 : 0, -1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
} else {
|
||||
bool is_offset = p_coords.x % 2;
|
||||
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, is_offset ? 1 : 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(2, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, is_offset ? 0 : -1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, is_offset ? 0 : -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-2, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, is_offset ? 1 : 0);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TileSet::TILE_LAYOUT_STACKED_OFFSET: {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
bool is_offset = p_coords.y % 2;
|
||||
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 0 : 1, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(0, 2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? -1 : 0, 1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? -1 : 0, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(0, -2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(is_offset ? 0 : 1, -1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
} else {
|
||||
bool is_offset = p_coords.x % 2;
|
||||
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, is_offset ? 0 : 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(2, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, is_offset ? -1 : 0);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, is_offset ? -1 : 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-2, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, is_offset ? 0 : 1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TileSet::TILE_LAYOUT_STAIRS_RIGHT:
|
||||
case TileSet::TILE_LAYOUT_STAIRS_DOWN: {
|
||||
if ((tile_layout == TileSet::TILE_LAYOUT_STAIRS_RIGHT) ^ (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(-1, 2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(1, -2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(2, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-2, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(2, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-2, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(1, -2);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_RIGHT:
|
||||
case TileSet::TILE_LAYOUT_DIAMOND_DOWN: {
|
||||
if ((tile_layout == TileSet::TILE_LAYOUT_DIAMOND_RIGHT) ^ (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL)) {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(-1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_SIDE)) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) {
|
||||
return p_coords + Vector2i(1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) {
|
||||
return p_coords + Vector2i(-1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
|
||||
} else {
|
||||
if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_SIDE)) {
|
||||
return p_coords + Vector2i(-1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(0, 1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_RIGHT_CORNER) {
|
||||
return p_coords + Vector2i(1, 1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE) {
|
||||
return p_coords + Vector2i(1, 0);
|
||||
} else if ((tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_CORNER) ||
|
||||
(tile_shape != TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_SIDE)) {
|
||||
return p_coords + Vector2i(1, -1);
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(0, -1);
|
||||
} else if (tile_shape == TileSet::TILE_SHAPE_ISOMETRIC && p_cell_neighbor == TileSet::CELL_NEIGHBOR_LEFT_CORNER) {
|
||||
return p_coords + Vector2i(-1, -1);
|
||||
|
||||
} else if (p_cell_neighbor == TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE) {
|
||||
return p_coords + Vector2i(-1, 0);
|
||||
} else {
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
ERR_FAIL_V(p_coords);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2i TileSet::map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern) {
|
||||
ERR_FAIL_COND_V(p_pattern.is_null(), Vector2i());
|
||||
ERR_FAIL_COND_V(!p_pattern->has_cell(p_coords_in_pattern), Vector2i());
|
||||
|
||||
Vector2i output = p_position_in_tilemap + p_coords_in_pattern;
|
||||
if (tile_shape != TileSet::TILE_SHAPE_SQUARE) {
|
||||
if (tile_layout == TileSet::TILE_LAYOUT_STACKED) {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(p_position_in_tilemap.y % 2) && bool(p_coords_in_pattern.y % 2)) {
|
||||
output.x += 1;
|
||||
} else if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(p_position_in_tilemap.x % 2) && bool(p_coords_in_pattern.x % 2)) {
|
||||
output.y += 1;
|
||||
}
|
||||
} else if (tile_layout == TileSet::TILE_LAYOUT_STACKED_OFFSET) {
|
||||
if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_HORIZONTAL && bool(p_position_in_tilemap.y % 2) && bool(p_coords_in_pattern.y % 2)) {
|
||||
output.x -= 1;
|
||||
} else if (tile_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL && bool(p_position_in_tilemap.x % 2) && bool(p_coords_in_pattern.x % 2)) {
|
||||
output.y -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
Vector<Point2> TileSet::get_terrain_polygon(int p_terrain_set) {
|
||||
if (tile_shape == TileSet::TILE_SHAPE_SQUARE) {
|
||||
return _get_square_terrain_polygon(tile_size);
|
||||
|
|
|
@ -530,6 +530,13 @@ public:
|
|||
Vector<Vector2> get_tile_shape_polygon();
|
||||
void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
|
||||
|
||||
// Used by TileMap/TileMapLayer
|
||||
Vector2 map_to_local(const Vector2i &p_pos) const;
|
||||
Vector2i local_to_map(const Vector2 &p_pos) const;
|
||||
bool is_existing_neighbor(TileSet::CellNeighbor p_cell_neighbor) const;
|
||||
Vector2i get_neighbor_cell(const Vector2i &p_coords, TileSet::CellNeighbor p_cell_neighbor) const;
|
||||
Vector2i map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern);
|
||||
|
||||
Vector<Point2> get_terrain_polygon(int p_terrain_set);
|
||||
Vector<Point2> get_terrain_peering_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);
|
||||
|
|
Loading…
Reference in a new issue