2023-01-05 13:25:55 +01:00
/**************************************************************************/
/* tile_map.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
2018-01-05 00:50:27 +01:00
2014-02-10 02:10:30 +01:00
# include "tile_map.h"
2023-06-16 14:16:37 +02:00
# include "tile_map.compat.inc"
2017-12-10 16:40:31 +01:00
2023-06-16 14:16:37 +02:00
# include "core/core_string_names.h"
2024-01-05 11:58:21 +01:00
# include "scene/2d/tile_map_layer.h"
# include "scene/gui/control.h"
2014-02-10 02:10:30 +01:00
2023-06-16 14:16:37 +02:00
# define TILEMAP_CALL_FOR_LAYER(layer, function, ...) \
if ( layer < 0 ) { \
layer = layers . size ( ) + layer ; \
} ; \
ERR_FAIL_INDEX ( layer , ( int ) layers . size ( ) ) ; \
layers [ layer ] - > function ( __VA_ARGS__ ) ;
2017-12-09 17:44:26 +01:00
2023-06-16 14:16:37 +02:00
# define TILEMAP_CALL_FOR_LAYER_V(layer, err_value, function, ...) \
if ( layer < 0 ) { \
layer = layers . size ( ) + layer ; \
} ; \
ERR_FAIL_INDEX_V ( layer , ( int ) layers . size ( ) , err_value ) ; \
return layers [ layer ] - > function ( __VA_ARGS__ ) ;
2014-02-10 02:10:30 +01:00
2023-06-16 14:16:37 +02:00
Vector2i TileMap : : transform_coords_layout ( const Vector2i & p_coords , TileSet : : TileOffsetAxis p_offset_axis , TileSet : : TileLayout p_from_layout , TileSet : : TileLayout p_to_layout ) {
// Transform to stacked layout.
Vector2i output = p_coords ;
if ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) {
SWAP ( output . x , output . y ) ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
switch ( p_from_layout ) {
case TileSet : : TILE_LAYOUT_STACKED :
break ;
case TileSet : : TILE_LAYOUT_STACKED_OFFSET :
if ( output . y % 2 ) {
output . x - = 1 ;
2022-10-14 11:56:47 +02:00
}
2023-06-16 14:16:37 +02:00
break ;
case TileSet : : TILE_LAYOUT_STAIRS_RIGHT :
case TileSet : : TILE_LAYOUT_STAIRS_DOWN :
if ( ( p_from_layout = = TileSet : : TILE_LAYOUT_STAIRS_RIGHT ) ^ ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( output . y < 0 & & bool ( output . y % 2 ) ) {
output = Vector2i ( output . x + output . y / 2 - 1 , output . y ) ;
} else {
output = Vector2i ( output . x + output . y / 2 , output . y ) ;
}
} else {
if ( output . x < 0 & & bool ( output . x % 2 ) ) {
output = Vector2i ( output . x / 2 - 1 , output . x + output . y * 2 ) ;
} else {
output = Vector2i ( output . x / 2 , output . x + output . y * 2 ) ;
}
}
break ;
case TileSet : : TILE_LAYOUT_DIAMOND_RIGHT :
case TileSet : : TILE_LAYOUT_DIAMOND_DOWN :
if ( ( p_from_layout = = TileSet : : TILE_LAYOUT_DIAMOND_RIGHT ) ^ ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( ( output . x + output . y ) < 0 & & ( output . x - output . y ) % 2 ) {
output = Vector2i ( ( output . x + output . y ) / 2 - 1 , output . y - output . x ) ;
} else {
output = Vector2i ( ( output . x + output . y ) / 2 , - output . x + output . y ) ;
}
} else {
if ( ( output . x - output . y ) < 0 & & ( output . x + output . y ) % 2 ) {
output = Vector2i ( ( output . x - output . y ) / 2 - 1 , output . x + output . y ) ;
} else {
output = Vector2i ( ( output . x - output . y ) / 2 , output . x + output . y ) ;
}
}
break ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
switch ( p_to_layout ) {
case TileSet : : TILE_LAYOUT_STACKED :
break ;
case TileSet : : TILE_LAYOUT_STACKED_OFFSET :
if ( output . y % 2 ) {
output . x + = 1 ;
}
break ;
case TileSet : : TILE_LAYOUT_STAIRS_RIGHT :
case TileSet : : TILE_LAYOUT_STAIRS_DOWN :
if ( ( p_to_layout = = TileSet : : TILE_LAYOUT_STAIRS_RIGHT ) ^ ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( output . y < 0 & & ( output . y % 2 ) ) {
output = Vector2i ( output . x - output . y / 2 + 1 , output . y ) ;
} else {
output = Vector2i ( output . x - output . y / 2 , output . y ) ;
}
} else {
if ( output . y % 2 ) {
if ( output . y < 0 ) {
output = Vector2i ( 2 * output . x + 1 , - output . x + output . y / 2 - 1 ) ;
} else {
output = Vector2i ( 2 * output . x + 1 , - output . x + output . y / 2 ) ;
2022-10-14 11:56:47 +02:00
}
2023-06-16 14:16:37 +02:00
} else {
output = Vector2i ( 2 * output . x , - output . x + output . y / 2 ) ;
2021-10-21 16:42:06 +02:00
}
}
2023-06-16 14:16:37 +02:00
break ;
case TileSet : : TILE_LAYOUT_DIAMOND_RIGHT :
case TileSet : : TILE_LAYOUT_DIAMOND_DOWN :
if ( ( p_to_layout = = TileSet : : TILE_LAYOUT_DIAMOND_RIGHT ) ^ ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( output . y % 2 ) {
if ( output . y > 0 ) {
output = Vector2i ( output . x - output . y / 2 , output . x + output . y / 2 + 1 ) ;
} else {
output = Vector2i ( output . x - output . y / 2 + 1 , output . x + output . y / 2 ) ;
}
} else {
output = Vector2i ( output . x - output . y / 2 , output . x + output . y / 2 ) ;
}
} else {
if ( output . y % 2 ) {
if ( output . y < 0 ) {
output = Vector2i ( output . x + output . y / 2 , - output . x + output . y / 2 - 1 ) ;
} else {
output = Vector2i ( output . x + output . y / 2 + 1 , - output . x + output . y / 2 ) ;
}
} else {
output = Vector2i ( output . x + output . y / 2 , - output . x + output . y / 2 ) ;
}
}
break ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
if ( p_offset_axis = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) {
SWAP ( output . x , output . y ) ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
return output ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_selected_layer ( int p_layer_id ) {
ERR_FAIL_COND ( p_layer_id < - 1 | | p_layer_id > = ( int ) layers . size ( ) ) ;
2023-08-24 13:31:14 +02:00
if ( selected_layer = = p_layer_id ) {
return ;
}
2023-06-16 14:16:37 +02:00
selected_layer = p_layer_id ;
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
// Update the layers modulation.
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_SELECTED_LAYER ) ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_selected_layer ( ) const {
return selected_layer ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : _notification ( int p_what ) {
switch ( p_what ) {
case NOTIFICATION_ENTER_TREE : {
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_IN_TREE ) ;
}
2023-06-16 14:16:37 +02:00
} break ;
case NOTIFICATION_EXIT_TREE : {
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_IN_TREE ) ;
}
2023-06-16 14:16:37 +02:00
} break ;
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
case TileMap : : NOTIFICATION_ENTER_CANVAS : {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_IN_CANVAS ) ;
}
} break ;
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
case TileMap : : NOTIFICATION_EXIT_CANVAS : {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_IN_CANVAS ) ;
}
} break ;
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
case NOTIFICATION_DRAW : {
// Rendering.
if ( tile_set . is_valid ( ) ) {
RenderingServer : : get_singleton ( ) - > canvas_item_set_sort_children_by_y ( get_canvas_item ( ) , is_y_sort_enabled ( ) ) ;
}
} break ;
2023-06-16 14:16:37 +02:00
2023-08-24 13:31:14 +02:00
case TileMap : : NOTIFICATION_VISIBILITY_CHANGED : {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_VISIBILITY ) ;
}
} break ;
2023-06-16 14:16:37 +02:00
2023-08-24 13:31:14 +02:00
case TileMap : : NOTIFICATION_INTERNAL_PHYSICS_PROCESS : {
// Physics.
bool in_editor = false ;
2023-06-16 14:16:37 +02:00
# ifdef TOOLS_ENABLED
2023-08-24 13:31:14 +02:00
in_editor = Engine : : get_singleton ( ) - > is_editor_hint ( ) ;
2023-06-16 14:16:37 +02:00
# endif
2023-08-24 13:31:14 +02:00
if ( is_inside_tree ( ) & & collision_animatable & & ! in_editor ) {
// Update transform on the physics tick when in animatable mode.
last_valid_transform = new_transform ;
set_notify_local_transform ( false ) ;
set_global_transform ( new_transform ) ;
2023-09-18 16:30:06 +02:00
_update_notify_local_transform ( ) ;
2023-08-24 13:31:14 +02:00
}
} break ;
2023-06-16 14:16:37 +02:00
2023-08-24 13:31:14 +02:00
case NOTIFICATION_TRANSFORM_CHANGED : {
// Physics.
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_XFORM ) ;
}
} break ;
2023-06-16 14:16:37 +02:00
2023-08-24 13:31:14 +02:00
case TileMap : : NOTIFICATION_LOCAL_TRANSFORM_CHANGED : {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_LOCAL_XFORM ) ;
}
// Physics.
bool in_editor = false ;
2023-06-16 14:16:37 +02:00
# ifdef TOOLS_ENABLED
2023-08-24 13:31:14 +02:00
in_editor = Engine : : get_singleton ( ) - > is_editor_hint ( ) ;
2023-06-16 14:16:37 +02:00
# endif
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
// Only active when animatable. Send the new transform to the physics...
if ( is_inside_tree ( ) & & collision_animatable & & ! in_editor ) {
// Store last valid transform.
new_transform = get_global_transform ( ) ;
// ... but then revert changes.
set_notify_local_transform ( false ) ;
set_global_transform ( last_valid_transform ) ;
2023-09-18 16:30:06 +02:00
_update_notify_local_transform ( ) ;
2023-08-24 13:31:14 +02:00
}
} break ;
2023-06-16 14:16:37 +02:00
}
}
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
# ifndef DISABLE_DEPRECATED
// Deprecated methods.
void TileMap : : force_update ( int p_layer ) {
notify_runtime_tile_data_update ( p_layer ) ;
update_internals ( ) ;
}
# endif
void TileMap : : queue_internal_update ( ) {
if ( pending_update ) {
2023-06-16 14:16:37 +02:00
return ;
}
pending_update = true ;
2023-08-24 13:31:14 +02:00
callable_mp ( this , & TileMap : : _internal_update ) . call_deferred ( ) ;
2023-06-16 14:16:37 +02:00
}
2021-10-21 16:42:06 +02:00
2023-08-24 13:31:14 +02:00
void TileMap : : _internal_update ( ) {
// Other updates.
2023-06-16 14:16:37 +02:00
if ( ! pending_update ) {
return ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
// Update dirty quadrants on layers.
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > internal_update ( ) ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
pending_update = false ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_tileset ( const Ref < TileSet > & p_tileset ) {
if ( p_tileset = = tile_set ) {
return ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
// Set the tileset, registering to its changes.
if ( tile_set . is_valid ( ) ) {
tile_set - > disconnect_changed ( callable_mp ( this , & TileMap : : _tile_set_changed ) ) ;
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
tile_set = p_tileset ;
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
if ( tile_set . is_valid ( ) ) {
tile_set - > connect_changed ( callable_mp ( this , & TileMap : : _tile_set_changed ) ) ;
2023-08-24 13:31:14 +02:00
}
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_TILE_SET ) ;
2023-06-16 14:16:37 +02:00
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
Ref < TileSet > TileMap : : get_tileset ( ) const {
return tile_set ;
2022-02-23 17:25:50 +01:00
}
2023-08-24 13:31:14 +02:00
void TileMap : : set_rendering_quadrant_size ( int p_size ) {
2023-06-16 14:16:37 +02:00
ERR_FAIL_COND_MSG ( p_size < 1 , " TileMapQuadrant size cannot be smaller than 1. " ) ;
2022-02-23 17:25:50 +01:00
2023-08-24 13:31:14 +02:00
rendering_quadrant_size = p_size ;
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_QUADRANT_SIZE ) ;
}
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
}
2023-08-24 13:31:14 +02:00
int TileMap : : get_rendering_quadrant_size ( ) const {
return rendering_quadrant_size ;
2023-06-16 14:16:37 +02:00
}
void TileMap : : draw_tile ( RID p_canvas_item , const Vector2 & p_position , const Ref < TileSet > p_tile_set , int p_atlas_source_id , const Vector2i & p_atlas_coords , int p_alternative_tile , int p_frame , Color p_modulation , const TileData * p_tile_data_override , real_t p_animation_offset ) {
ERR_FAIL_COND ( ! p_tile_set . is_valid ( ) ) ;
ERR_FAIL_COND ( ! p_tile_set - > has_source ( p_atlas_source_id ) ) ;
ERR_FAIL_COND ( ! p_tile_set - > get_source ( p_atlas_source_id ) - > has_tile ( p_atlas_coords ) ) ;
ERR_FAIL_COND ( ! p_tile_set - > get_source ( p_atlas_source_id ) - > has_alternative_tile ( p_atlas_coords , p_alternative_tile ) ) ;
TileSetSource * source = * p_tile_set - > get_source ( p_atlas_source_id ) ;
TileSetAtlasSource * atlas_source = Object : : cast_to < TileSetAtlasSource > ( source ) ;
if ( atlas_source ) {
// Check for the frame.
if ( p_frame > = 0 ) {
ERR_FAIL_INDEX ( p_frame , atlas_source - > get_tile_animation_frames_count ( p_atlas_coords ) ) ;
2021-10-21 16:42:06 +02:00
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
// Get the texture.
Ref < Texture2D > tex = atlas_source - > get_runtime_texture ( ) ;
if ( ! tex . is_valid ( ) ) {
return ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
// Check if we are in the texture, return otherwise.
Vector2i grid_size = atlas_source - > get_atlas_grid_size ( ) ;
if ( p_atlas_coords . x > = grid_size . x | | p_atlas_coords . y > = grid_size . y ) {
return ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
// Get tile data.
const TileData * tile_data = p_tile_data_override ? p_tile_data_override : atlas_source - > get_tile_data ( p_atlas_coords , p_alternative_tile ) ;
// Get the tile modulation.
Color modulate = tile_data - > get_modulate ( ) * p_modulation ;
// Compute the offset.
Vector2 tile_offset = tile_data - > get_texture_origin ( ) ;
// Get destination rect.
Rect2 dest_rect ;
dest_rect . size = atlas_source - > get_runtime_tile_texture_region ( p_atlas_coords ) . size ;
dest_rect . size . x + = FP_ADJUST ;
dest_rect . size . y + = FP_ADJUST ;
2023-07-31 21:35:17 +02:00
bool transpose = tile_data - > get_transpose ( ) ^ bool ( p_alternative_tile & TileSetAtlasSource : : TRANSFORM_TRANSPOSE ) ;
2023-06-16 14:16:37 +02:00
if ( transpose ) {
dest_rect . position = ( p_position - Vector2 ( dest_rect . size . y , dest_rect . size . x ) / 2 - tile_offset ) ;
} else {
dest_rect . position = ( p_position - dest_rect . size / 2 - tile_offset ) ;
2022-02-23 17:25:50 +01:00
}
2023-07-31 21:35:17 +02:00
if ( tile_data - > get_flip_h ( ) ^ bool ( p_alternative_tile & TileSetAtlasSource : : TRANSFORM_FLIP_H ) ) {
2023-06-16 14:16:37 +02:00
dest_rect . size . x = - dest_rect . size . x ;
}
2022-02-23 17:25:50 +01:00
2023-07-31 21:35:17 +02:00
if ( tile_data - > get_flip_v ( ) ^ bool ( p_alternative_tile & TileSetAtlasSource : : TRANSFORM_FLIP_V ) ) {
2023-06-16 14:16:37 +02:00
dest_rect . size . y = - dest_rect . size . y ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
// Draw the tile.
if ( p_frame > = 0 ) {
Rect2i source_rect = atlas_source - > get_runtime_tile_texture_region ( p_atlas_coords , p_frame ) ;
tex - > draw_rect_region ( p_canvas_item , dest_rect , source_rect , modulate , transpose , p_tile_set - > is_uv_clipping ( ) ) ;
} else if ( atlas_source - > get_tile_animation_frames_count ( p_atlas_coords ) = = 1 ) {
Rect2i source_rect = atlas_source - > get_runtime_tile_texture_region ( p_atlas_coords , 0 ) ;
tex - > draw_rect_region ( p_canvas_item , dest_rect , source_rect , modulate , transpose , p_tile_set - > is_uv_clipping ( ) ) ;
} else {
real_t speed = atlas_source - > get_tile_animation_speed ( p_atlas_coords ) ;
real_t animation_duration = atlas_source - > get_tile_animation_total_duration ( p_atlas_coords ) / speed ;
2023-09-26 12:07:29 +02:00
// Accumulate durations unaffected by the speed to avoid accumulating floating point division errors.
// Aka do `sum(duration[i]) / speed` instead of `sum(duration[i] / speed)`.
real_t time_unscaled = 0.0 ;
2023-06-16 14:16:37 +02:00
for ( int frame = 0 ; frame < atlas_source - > get_tile_animation_frames_count ( p_atlas_coords ) ; frame + + ) {
2023-09-26 12:07:29 +02:00
real_t frame_duration_unscaled = atlas_source - > get_tile_animation_frame_duration ( p_atlas_coords , frame ) ;
real_t slice_start = time_unscaled / speed ;
real_t slice_end = ( time_unscaled + frame_duration_unscaled ) / speed ;
RenderingServer : : get_singleton ( ) - > canvas_item_add_animation_slice ( p_canvas_item , animation_duration , slice_start , slice_end , p_animation_offset ) ;
2023-06-16 14:16:37 +02:00
Rect2i source_rect = atlas_source - > get_runtime_tile_texture_region ( p_atlas_coords , frame ) ;
tex - > draw_rect_region ( p_canvas_item , dest_rect , source_rect , modulate , transpose , p_tile_set - > is_uv_clipping ( ) ) ;
2023-09-26 12:07:29 +02:00
time_unscaled + = frame_duration_unscaled ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
RenderingServer : : get_singleton ( ) - > canvas_item_add_animation_slice ( p_canvas_item , 1.0 , 0.0 , 1.0 , 0.0 ) ;
2021-10-21 16:42:06 +02:00
}
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_layers_count ( ) const {
return layers . size ( ) ;
}
void TileMap : : add_layer ( int p_to_pos ) {
if ( p_to_pos < 0 ) {
p_to_pos = layers . size ( ) + p_to_pos + 1 ;
2022-02-23 17:25:50 +01:00
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
ERR_FAIL_INDEX ( p_to_pos , ( int ) layers . size ( ) + 1 ) ;
// Must clear before adding the layer.
Ref < TileMapLayer > new_layer ;
new_layer . instantiate ( ) ;
new_layer - > set_tile_map ( this ) ;
layers . insert ( p_to_pos , new_layer ) ;
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 0 ; i < layers . size ( ) ; i + + ) {
2023-06-16 14:16:37 +02:00
layers [ i ] - > set_layer_index_in_tile_map_node ( i ) ;
}
2023-08-24 13:31:14 +02:00
queue_internal_update ( ) ;
2023-06-16 14:16:37 +02:00
notify_property_list_changed ( ) ;
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
update_configuration_warnings ( ) ;
2022-02-23 17:25:50 +01:00
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : move_layer ( int p_layer , int p_to_pos ) {
ERR_FAIL_INDEX ( p_layer , ( int ) layers . size ( ) ) ;
ERR_FAIL_INDEX ( p_to_pos , ( int ) layers . size ( ) + 1 ) ;
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
// Clear before shuffling layers.
Ref < TileMapLayer > layer = layers [ p_layer ] ;
layers . insert ( p_to_pos , layer ) ;
layers . remove_at ( p_to_pos < p_layer ? p_layer + 1 : p_layer ) ;
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 0 ; i < layers . size ( ) ; i + + ) {
2023-06-16 14:16:37 +02:00
layers [ i ] - > set_layer_index_in_tile_map_node ( i ) ;
2022-02-23 17:25:50 +01:00
}
2023-08-24 13:31:14 +02:00
queue_internal_update ( ) ;
2023-06-16 14:16:37 +02:00
notify_property_list_changed ( ) ;
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
if ( selected_layer = = p_layer ) {
selected_layer = p_to_pos < p_layer ? p_to_pos - 1 : p_to_pos ;
2021-10-21 16:42:06 +02:00
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
update_configuration_warnings ( ) ;
}
void TileMap : : remove_layer ( int p_layer ) {
ERR_FAIL_INDEX ( p_layer , ( int ) layers . size ( ) ) ;
// Clear before removing the layer.
layers . remove_at ( p_layer ) ;
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 0 ; i < layers . size ( ) ; i + + ) {
2023-06-16 14:16:37 +02:00
layers [ i ] - > set_layer_index_in_tile_map_node ( i ) ;
2022-02-23 17:25:50 +01:00
}
2023-08-24 13:31:14 +02:00
queue_internal_update ( ) ;
2023-06-16 14:16:37 +02:00
notify_property_list_changed ( ) ;
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
if ( selected_layer > = p_layer ) {
selected_layer - = 1 ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
update_configuration_warnings ( ) ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_name ( int p_layer , String p_name ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_name , p_name ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
String TileMap : : get_layer_name ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , " " , get_name ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_enabled ( int p_layer , bool p_enabled ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_enabled , p_enabled ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
bool TileMap : : is_layer_enabled ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , false , is_enabled ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_modulate ( int p_layer , Color p_modulate ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_modulate , p_modulate ) ;
}
2022-02-23 17:25:50 +01:00
2023-06-16 14:16:37 +02:00
Color TileMap : : get_layer_modulate ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , Color ( ) , get_modulate ) ;
2022-02-23 17:25:50 +01:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_y_sort_enabled ( int p_layer , bool p_y_sort_enabled ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_y_sort_enabled , p_y_sort_enabled ) ;
2023-09-18 16:30:06 +02:00
_update_notify_local_transform ( ) ;
2023-06-16 14:16:37 +02:00
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
bool TileMap : : is_layer_y_sort_enabled ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , false , is_y_sort_enabled ) ;
2022-02-23 17:25:50 +01:00
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_y_sort_origin ( int p_layer , int p_y_sort_origin ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_y_sort_origin , p_y_sort_origin ) ;
}
2021-10-21 16:42:06 +02:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_layer_y_sort_origin ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , 0 , get_y_sort_origin ) ;
}
2022-10-14 11:56:47 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_z_index ( int p_layer , int p_z_index ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_z_index , p_z_index ) ;
2021-10-21 16:42:06 +02:00
}
2023-06-16 14:16:37 +02:00
int TileMap : : get_layer_z_index ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , 0 , get_z_index ) ;
2018-07-29 23:09:59 +02:00
}
2023-10-13 17:22:51 +02:00
void TileMap : : set_layer_navigation_enabled ( int p_layer , bool p_enabled ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_navigation_enabled , p_enabled ) ;
}
bool TileMap : : is_layer_navigation_enabled ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , false , is_navigation_enabled ) ;
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_layer_navigation_map ( int p_layer , RID p_map ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_navigation_map , p_map ) ;
}
2021-07-28 18:10:01 +02:00
2023-06-16 14:16:37 +02:00
RID TileMap : : get_layer_navigation_map ( int p_layer ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , RID ( ) , get_navigation_map ) ;
2014-05-14 06:22:15 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_collision_animatable ( bool p_enabled ) {
if ( collision_animatable = = p_enabled ) {
return ;
}
collision_animatable = p_enabled ;
2023-09-18 16:30:06 +02:00
_update_notify_local_transform ( ) ;
2023-06-16 14:16:37 +02:00
set_physics_process_internal ( p_enabled ) ;
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_COLLISION_ANIMATABLE ) ;
}
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
}
bool TileMap : : is_collision_animatable ( ) const {
return collision_animatable ;
}
void TileMap : : set_collision_visibility_mode ( TileMap : : VisibilityMode p_show_collision ) {
if ( collision_visibility_mode = = p_show_collision ) {
return ;
}
collision_visibility_mode = p_show_collision ;
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_COLLISION_VISIBILITY_MODE ) ;
}
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2021-09-15 15:23:58 +02:00
}
2023-06-16 14:16:37 +02:00
TileMap : : VisibilityMode TileMap : : get_collision_visibility_mode ( ) {
return collision_visibility_mode ;
2023-04-19 06:22:46 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_navigation_visibility_mode ( TileMap : : VisibilityMode p_show_navigation ) {
if ( navigation_visibility_mode = = p_show_navigation ) {
return ;
2014-06-30 03:41:02 +02:00
}
2023-06-16 14:16:37 +02:00
navigation_visibility_mode = p_show_navigation ;
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_NAVIGATION_VISIBILITY_MODE ) ;
}
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2014-06-30 03:41:02 +02:00
}
2023-06-16 14:16:37 +02:00
TileMap : : VisibilityMode TileMap : : get_navigation_visibility_mode ( ) {
return navigation_visibility_mode ;
2014-05-14 06:22:15 +02:00
}
2023-06-16 14:16:37 +02:00
void TileMap : : set_y_sort_enabled ( bool p_enable ) {
if ( is_y_sort_enabled ( ) = = p_enable ) {
return ;
2021-07-28 18:10:01 +02:00
}
2023-06-16 14:16:37 +02:00
Node2D : : set_y_sort_enabled ( p_enable ) ;
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_Y_SORT_ENABLED ) ;
2023-06-16 14:16:37 +02:00
}
2023-08-24 13:31:14 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
update_configuration_warnings ( ) ;
2023-06-16 14:16:37 +02:00
}
2021-07-28 18:10:01 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_cell ( int p_layer , const Vector2i & p_coords , int p_source_id , const Vector2i p_atlas_coords , int p_alternative_tile ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_cell , p_coords , p_source_id , p_atlas_coords , p_alternative_tile ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : erase_cell ( int p_layer , const Vector2i & p_coords ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_cell , p_coords , TileSet : : INVALID_SOURCE , TileSetSource : : INVALID_ATLAS_COORDS , TileSetSource : : INVALID_TILE_ALTERNATIVE ) ;
}
2021-05-24 17:30:37 +02:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_cell_source_id ( int p_layer , const Vector2i & p_coords , bool p_use_proxies ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TileSet : : INVALID_SOURCE , get_cell_source_id , p_coords , p_use_proxies ) ;
}
2021-05-24 17:30:37 +02:00
2023-06-16 14:16:37 +02:00
Vector2i TileMap : : get_cell_atlas_coords ( int p_layer , const Vector2i & p_coords , bool p_use_proxies ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TileSetSource : : INVALID_ATLAS_COORDS , get_cell_atlas_coords , p_coords , p_use_proxies ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_cell_alternative_tile ( int p_layer , const Vector2i & p_coords , bool p_use_proxies ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TileSetSource : : INVALID_TILE_ALTERNATIVE , get_cell_alternative_tile , p_coords , p_use_proxies ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
TileData * TileMap : : get_cell_tile_data ( int p_layer , const Vector2i & p_coords , bool p_use_proxies ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , nullptr , get_cell_tile_data , p_coords , p_use_proxies ) ;
}
2021-05-07 15:41:39 +02:00
2023-06-16 14:16:37 +02:00
Ref < TileMapPattern > TileMap : : get_pattern ( int p_layer , TypedArray < Vector2i > p_coords_array ) {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , Ref < TileMapPattern > ( ) , get_pattern , p_coords_array ) ;
}
2021-07-06 14:43:03 +02:00
2023-06-16 14:16:37 +02:00
Vector2i TileMap : : 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 ( ) ) ;
2021-07-06 14:43:03 +02:00
2023-06-16 14:16:37 +02:00
Vector2i output = p_position_in_tilemap + p_coords_in_pattern ;
if ( tile_set - > get_tile_shape ( ) ! = TileSet : : TILE_SHAPE_SQUARE ) {
if ( tile_set - > get_tile_layout ( ) = = TileSet : : TILE_LAYOUT_STACKED ) {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL & & bool ( p_position_in_tilemap . y % 2 ) & & bool ( p_coords_in_pattern . y % 2 ) ) {
output . x + = 1 ;
} else if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_VERTICAL & & bool ( p_position_in_tilemap . x % 2 ) & & bool ( p_coords_in_pattern . x % 2 ) ) {
output . y + = 1 ;
2021-05-07 15:41:39 +02:00
}
2023-06-16 14:16:37 +02:00
} else if ( tile_set - > get_tile_layout ( ) = = TileSet : : TILE_LAYOUT_STACKED_OFFSET ) {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL & & bool ( p_position_in_tilemap . y % 2 ) & & bool ( p_coords_in_pattern . y % 2 ) ) {
output . x - = 1 ;
} else if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_VERTICAL & & bool ( p_position_in_tilemap . x % 2 ) & & bool ( p_coords_in_pattern . x % 2 ) ) {
output . y - = 1 ;
2021-05-07 15:41:39 +02:00
}
}
2014-10-03 05:10:51 +02:00
}
2023-06-16 14:16:37 +02:00
return output ;
}
2021-07-28 18:10:01 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_pattern ( int p_layer , const Vector2i & p_position , const Ref < TileMapPattern > p_pattern ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_pattern , p_position , p_pattern ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
HashMap < Vector2i , TileSet : : TerrainsPattern > TileMap : : terrain_fill_constraints ( int p_layer , const Vector < Vector2i > & p_to_replace , int p_terrain_set , const RBSet < TerrainConstraint > & p_constraints ) {
HashMap < Vector2i , TileSet : : TerrainsPattern > err_value ;
TILEMAP_CALL_FOR_LAYER_V ( p_layer , err_value , terrain_fill_constraints , p_to_replace , p_terrain_set , p_constraints ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
HashMap < Vector2i , TileSet : : TerrainsPattern > TileMap : : terrain_fill_connect ( int p_layer , const Vector < Vector2i > & p_coords_array , int p_terrain_set , int p_terrain , bool p_ignore_empty_terrains ) {
HashMap < Vector2i , TileSet : : TerrainsPattern > err_value ;
TILEMAP_CALL_FOR_LAYER_V ( p_layer , err_value , terrain_fill_connect , p_coords_array , p_terrain_set , p_terrain , p_ignore_empty_terrains ) ;
}
2014-10-03 05:10:51 +02:00
2023-06-16 14:16:37 +02:00
HashMap < Vector2i , TileSet : : TerrainsPattern > TileMap : : terrain_fill_path ( int p_layer , const Vector < Vector2i > & p_coords_array , int p_terrain_set , int p_terrain , bool p_ignore_empty_terrains ) {
HashMap < Vector2i , TileSet : : TerrainsPattern > err_value ;
TILEMAP_CALL_FOR_LAYER_V ( p_layer , err_value , terrain_fill_path , p_coords_array , p_terrain_set , p_terrain , p_ignore_empty_terrains ) ;
2014-10-03 05:10:51 +02:00
}
2023-06-16 14:16:37 +02:00
HashMap < Vector2i , TileSet : : TerrainsPattern > TileMap : : terrain_fill_pattern ( int p_layer , const Vector < Vector2i > & p_coords_array , int p_terrain_set , TileSet : : TerrainsPattern p_terrains_pattern , bool p_ignore_empty_terrains ) {
HashMap < Vector2i , TileSet : : TerrainsPattern > err_value ;
TILEMAP_CALL_FOR_LAYER_V ( p_layer , err_value , terrain_fill_pattern , p_coords_array , p_terrain_set , p_terrains_pattern , p_ignore_empty_terrains ) ;
}
2021-10-22 16:32:06 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_cells_terrain_connect ( int p_layer , TypedArray < Vector2i > p_cells , int p_terrain_set , int p_terrain , bool p_ignore_empty_terrains ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_cells_terrain_connect , p_cells , p_terrain_set , p_terrain , p_ignore_empty_terrains ) ;
}
2021-10-22 16:32:06 +02:00
2023-06-16 14:16:37 +02:00
void TileMap : : set_cells_terrain_path ( int p_layer , TypedArray < Vector2i > p_path , int p_terrain_set , int p_terrain , bool p_ignore_empty_terrains ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , set_cells_terrain_path , p_path , p_terrain_set , p_terrain , p_ignore_empty_terrains ) ;
}
2021-10-22 16:32:06 +02:00
2023-06-16 14:16:37 +02:00
TileMapCell TileMap : : get_cell ( int p_layer , const Vector2i & p_coords , bool p_use_proxies ) const {
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TileMapCell ( ) , get_cell , p_coords , p_use_proxies ) ;
}
2021-10-22 16:32:06 +02:00
2023-06-16 14:16:37 +02:00
Vector2i TileMap : : get_coords_for_body_rid ( RID p_physics_body ) {
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( layer - > has_body_rid ( p_physics_body ) ) {
return layer - > get_coords_for_body_rid ( p_physics_body ) ;
}
}
2023-08-01 17:30:21 +02:00
ERR_FAIL_V_MSG ( Vector2i ( ) , vformat ( " No tiles for the given body RID %d. " , p_physics_body . get_id ( ) ) ) ;
2023-06-16 14:16:37 +02:00
}
2021-10-22 16:32:06 +02:00
2023-06-16 14:16:37 +02:00
int TileMap : : get_layer_for_body_rid ( RID p_physics_body ) {
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 0 ; i < layers . size ( ) ; i + + ) {
2023-06-16 14:16:37 +02:00
if ( layers [ i ] - > has_body_rid ( p_physics_body ) ) {
return i ;
2021-10-22 16:32:06 +02:00
}
}
2023-08-01 17:30:21 +02:00
ERR_FAIL_V_MSG ( - 1 , vformat ( " No tiles for the given body RID %d. " , p_physics_body . get_id ( ) ) ) ;
2023-06-16 14:16:37 +02:00
}
void TileMap : : fix_invalid_tiles ( ) {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > fix_invalid_tiles ( ) ;
}
}
void TileMap : : clear_layer ( int p_layer ) {
TILEMAP_CALL_FOR_LAYER ( p_layer , clear )
}
void TileMap : : clear ( ) {
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > clear ( ) ;
}
}
2023-08-24 13:31:14 +02:00
void TileMap : : update_internals ( ) {
pending_update = true ;
_internal_update ( ) ;
}
void TileMap : : notify_runtime_tile_data_update ( int p_layer ) {
2023-06-16 14:16:37 +02:00
if ( p_layer > = 0 ) {
2023-08-24 13:31:14 +02:00
TILEMAP_CALL_FOR_LAYER ( p_layer , notify_tile_map_change , TileMapLayer : : DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE ) ;
2023-06-16 14:16:37 +02:00
} else {
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_RUNTIME_UPDATE ) ;
}
2023-06-16 14:16:37 +02:00
}
2021-10-22 16:32:06 +02:00
}
2021-05-07 15:41:39 +02:00
# ifdef TOOLS_ENABLED
Rect2 TileMap : : _edit_get_rect ( ) const {
2023-06-16 14:16:37 +02:00
// Return the visible rect of the tilemap.
if ( layers . is_empty ( ) ) {
return Rect2 ( ) ;
}
bool any_changed = false ;
bool changed = false ;
Rect2 rect = layers [ 0 ] - > get_rect ( changed ) ;
any_changed | = changed ;
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 1 ; i < layers . size ( ) ; i + + ) {
2023-06-16 14:16:37 +02:00
rect = rect . merge ( layers [ i ] - > get_rect ( changed ) ) ;
any_changed | = changed ;
}
const_cast < TileMap * > ( this ) - > item_rect_changed ( any_changed ) ;
return rect ;
2014-10-03 05:10:51 +02:00
}
2021-05-07 15:41:39 +02:00
# endif
2017-10-22 03:42:23 +02:00
bool TileMap : : _set ( const StringName & p_name , const Variant & p_value ) {
2021-07-28 18:10:01 +02:00
Vector < String > components = String ( p_name ) . split ( " / " , true , 2 ) ;
2017-10-22 03:42:23 +02:00
if ( p_name = = " format " ) {
if ( p_value . get_type ( ) = = Variant : : INT ) {
2024-01-05 11:58:21 +01:00
format = ( TileMapDataFormat ) ( p_value . operator int64_t ( ) ) ; // Set format used for loading.
2017-10-22 03:42:23 +02:00
return true ;
}
2023-11-28 12:43:59 +01:00
}
2023-08-24 13:31:14 +02:00
# ifndef DISABLE_DEPRECATED
2023-11-28 12:43:59 +01:00
else if ( p_name = = " tile_data " ) { // Kept for compatibility reasons.
2017-10-22 03:42:23 +02:00
if ( p_value . is_array ( ) ) {
2023-06-16 14:16:37 +02:00
if ( layers . size ( ) = = 0 ) {
Ref < TileMapLayer > new_layer ;
new_layer . instantiate ( ) ;
new_layer - > set_tile_map ( this ) ;
new_layer - > set_layer_index_in_tile_map_node ( 0 ) ;
layers . push_back ( new_layer ) ;
2021-07-28 18:10:01 +02:00
}
2023-06-16 14:16:37 +02:00
layers [ 0 ] - > set_tile_data ( format , p_value ) ;
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2017-10-22 03:42:23 +02:00
return true ;
}
return false ;
2023-11-28 12:43:59 +01:00
} else if ( p_name = = " cell_quadrant_size " ) {
2023-08-24 13:31:14 +02:00
set_rendering_quadrant_size ( p_value ) ;
2023-11-28 12:43:59 +01:00
return true ;
}
2023-08-24 13:31:14 +02:00
# endif // DISABLE_DEPRECATED
2023-11-28 12:43:59 +01:00
else if ( components . size ( ) = = 2 & & components [ 0 ] . begins_with ( " layer_ " ) & & components [ 0 ] . trim_prefix ( " layer_ " ) . is_valid_int ( ) ) {
2021-07-28 18:10:01 +02:00
int index = components [ 0 ] . trim_prefix ( " layer_ " ) . to_int ( ) ;
2021-09-26 21:44:26 +02:00
if ( index < 0 ) {
2021-07-28 18:10:01 +02:00
return false ;
}
2021-09-26 21:44:26 +02:00
if ( index > = ( int ) layers . size ( ) ) {
while ( index > = ( int ) layers . size ( ) ) {
2023-06-16 14:16:37 +02:00
Ref < TileMapLayer > new_layer ;
new_layer . instantiate ( ) ;
new_layer - > set_tile_map ( this ) ;
new_layer - > set_layer_index_in_tile_map_node ( index ) ;
layers . push_back ( new_layer ) ;
2021-09-26 21:44:26 +02:00
}
notify_property_list_changed ( ) ;
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2021-09-26 21:44:26 +02:00
update_configuration_warnings ( ) ;
}
2021-07-28 18:10:01 +02:00
if ( components [ 1 ] = = " name " ) {
set_layer_name ( index , p_value ) ;
return true ;
} else if ( components [ 1 ] = = " enabled " ) {
set_layer_enabled ( index , p_value ) ;
return true ;
2021-10-10 17:04:25 +02:00
} else if ( components [ 1 ] = = " modulate " ) {
set_layer_modulate ( index , p_value ) ;
return true ;
2021-07-28 18:10:01 +02:00
} else if ( components [ 1 ] = = " y_sort_enabled " ) {
set_layer_y_sort_enabled ( index , p_value ) ;
return true ;
} else if ( components [ 1 ] = = " y_sort_origin " ) {
set_layer_y_sort_origin ( index , p_value ) ;
return true ;
} else if ( components [ 1 ] = = " z_index " ) {
set_layer_z_index ( index , p_value ) ;
return true ;
2023-10-13 17:22:51 +02:00
} else if ( components [ 1 ] = = " navigation_enabled " ) {
set_layer_navigation_enabled ( index , p_value ) ;
return true ;
2021-07-28 18:10:01 +02:00
} else if ( components [ 1 ] = = " tile_data " ) {
2023-06-16 14:16:37 +02:00
layers [ index ] - > set_tile_data ( format , p_value ) ;
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2021-07-28 18:10:01 +02:00
return true ;
} else {
return false ;
}
2017-10-22 03:42:23 +02:00
}
return false ;
}
bool TileMap : : _get ( const StringName & p_name , Variant & r_ret ) const {
2021-07-28 18:10:01 +02:00
Vector < String > components = String ( p_name ) . split ( " / " , true , 2 ) ;
2017-10-22 03:42:23 +02:00
if ( p_name = = " format " ) {
2024-01-05 11:58:21 +01:00
r_ret = TileMapDataFormat : : FORMAT_MAX - 1 ; // When saving, always save highest format.
2017-10-22 03:42:23 +02:00
return true ;
2023-11-28 12:43:59 +01:00
}
# ifndef DISABLE_DEPRECATED
else if ( p_name = = " cell_quadrant_size " ) { // Kept for compatibility reasons.
r_ret = get_rendering_quadrant_size ( ) ;
return true ;
}
# endif
else if ( components . size ( ) = = 2 & & components [ 0 ] . begins_with ( " layer_ " ) & & components [ 0 ] . trim_prefix ( " layer_ " ) . is_valid_int ( ) ) {
2021-07-28 18:10:01 +02:00
int index = components [ 0 ] . trim_prefix ( " layer_ " ) . to_int ( ) ;
if ( index < 0 | | index > = ( int ) layers . size ( ) ) {
return false ;
}
if ( components [ 1 ] = = " name " ) {
r_ret = get_layer_name ( index ) ;
return true ;
} else if ( components [ 1 ] = = " enabled " ) {
r_ret = is_layer_enabled ( index ) ;
return true ;
2021-10-10 17:04:25 +02:00
} else if ( components [ 1 ] = = " modulate " ) {
r_ret = get_layer_modulate ( index ) ;
return true ;
2021-07-28 18:10:01 +02:00
} else if ( components [ 1 ] = = " y_sort_enabled " ) {
r_ret = is_layer_y_sort_enabled ( index ) ;
return true ;
} else if ( components [ 1 ] = = " y_sort_origin " ) {
r_ret = get_layer_y_sort_origin ( index ) ;
return true ;
} else if ( components [ 1 ] = = " z_index " ) {
r_ret = get_layer_z_index ( index ) ;
return true ;
2023-10-13 17:22:51 +02:00
} else if ( components [ 1 ] = = " navigation_enabled " ) {
r_ret = is_layer_navigation_enabled ( index ) ;
return true ;
2021-07-28 18:10:01 +02:00
} else if ( components [ 1 ] = = " tile_data " ) {
2023-06-16 14:16:37 +02:00
r_ret = layers [ index ] - > get_tile_data ( ) ;
2021-07-28 18:10:01 +02:00
return true ;
} else {
return false ;
}
2017-10-22 03:42:23 +02:00
}
return false ;
}
void TileMap : : _get_property_list ( List < PropertyInfo > * p_list ) const {
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : INT , " format " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL ) ) ;
2021-07-28 18:10:01 +02:00
p_list - > push_back ( PropertyInfo ( Variant : : NIL , " Layers " , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_GROUP ) ) ;
2023-10-24 13:38:29 +02:00
# define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \
{ \
const String property_name = vformat ( " layer_%d/ " m_name , i ) ; \
p_list - > push_back ( PropertyInfo ( m_type , property_name , PROPERTY_HINT_NONE , m_hint , ( get ( property_name ) = = property_get_revert ( property_name ) ) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT ) ) ; \
}
2023-12-07 18:18:18 +01:00
for ( uint32_t i = 0 ; i < layers . size ( ) ; i + + ) {
2023-10-24 13:38:29 +02:00
MAKE_LAYER_PROPERTY ( Variant : : STRING , " name " , " " ) ;
MAKE_LAYER_PROPERTY ( Variant : : BOOL , " enabled " , " " ) ;
MAKE_LAYER_PROPERTY ( Variant : : COLOR , " modulate " , " " ) ;
MAKE_LAYER_PROPERTY ( Variant : : BOOL , " y_sort_enabled " , " " ) ;
MAKE_LAYER_PROPERTY ( Variant : : INT , " y_sort_origin " , " suffix:px " ) ;
MAKE_LAYER_PROPERTY ( Variant : : INT , " z_index " , " " ) ;
MAKE_LAYER_PROPERTY ( Variant : : BOOL , " navigation_enabled " , " " ) ;
2021-11-03 23:06:17 +01:00
p_list - > push_back ( PropertyInfo ( Variant : : OBJECT , vformat ( " layer_%d/tile_data " , i ) , PROPERTY_HINT_NONE , " " , PROPERTY_USAGE_NO_EDITOR ) ) ;
2021-07-28 18:10:01 +02:00
}
2023-10-24 13:38:29 +02:00
# undef MAKE_LAYER_PROPERTY
}
bool TileMap : : _property_can_revert ( const StringName & p_name ) const {
Vector < String > components = String ( p_name ) . split ( " / " , true , 2 ) ;
if ( components . size ( ) = = 2 & & components [ 0 ] . begins_with ( " layer_ " ) ) {
int index = components [ 0 ] . trim_prefix ( " layer_ " ) . to_int ( ) ;
if ( index < = 0 | | index > = ( int ) layers . size ( ) ) {
return false ;
}
if ( components [ 1 ] = = " name " ) {
return layers [ index ] - > get_name ( ) ! = default_layer - > get_name ( ) ;
} else if ( components [ 1 ] = = " enabled " ) {
return layers [ index ] - > is_enabled ( ) ! = default_layer - > is_enabled ( ) ;
} else if ( components [ 1 ] = = " modulate " ) {
return layers [ index ] - > get_modulate ( ) ! = default_layer - > get_modulate ( ) ;
} else if ( components [ 1 ] = = " y_sort_enabled " ) {
return layers [ index ] - > is_y_sort_enabled ( ) ! = default_layer - > is_y_sort_enabled ( ) ;
} else if ( components [ 1 ] = = " y_sort_origin " ) {
return layers [ index ] - > get_y_sort_origin ( ) ! = default_layer - > get_y_sort_origin ( ) ;
} else if ( components [ 1 ] = = " z_index " ) {
return layers [ index ] - > get_z_index ( ) ! = default_layer - > get_z_index ( ) ;
} else if ( components [ 1 ] = = " navigation_enabled " ) {
return layers [ index ] - > is_navigation_enabled ( ) ! = default_layer - > is_navigation_enabled ( ) ;
}
}
return false ;
}
bool TileMap : : _property_get_revert ( const StringName & p_name , Variant & r_property ) const {
Vector < String > components = String ( p_name ) . split ( " / " , true , 2 ) ;
if ( components . size ( ) = = 2 & & components [ 0 ] . begins_with ( " layer_ " ) ) {
int index = components [ 0 ] . trim_prefix ( " layer_ " ) . to_int ( ) ;
if ( index < = 0 | | index > = ( int ) layers . size ( ) ) {
return false ;
}
if ( components [ 1 ] = = " name " ) {
r_property = default_layer - > get_name ( ) ;
return true ;
} else if ( components [ 1 ] = = " enabled " ) {
r_property = default_layer - > is_enabled ( ) ;
return true ;
} else if ( components [ 1 ] = = " modulate " ) {
r_property = default_layer - > get_modulate ( ) ;
return true ;
} else if ( components [ 1 ] = = " y_sort_enabled " ) {
r_property = default_layer - > is_y_sort_enabled ( ) ;
return true ;
} else if ( components [ 1 ] = = " y_sort_origin " ) {
r_property = default_layer - > get_y_sort_origin ( ) ;
return true ;
} else if ( components [ 1 ] = = " z_index " ) {
r_property = default_layer - > get_z_index ( ) ;
return true ;
} else if ( components [ 1 ] = = " navigation_enabled " ) {
r_property = default_layer - > is_navigation_enabled ( ) ;
return true ;
}
}
return false ;
2017-10-22 03:42:23 +02:00
}
2022-08-20 18:39:05 +02:00
Vector2 TileMap : : map_to_local ( const Vector2i & p_pos ) const {
2023-06-16 14:16:37 +02:00
// SHOULD RETURN THE CENTER OF THE CELL.
2021-05-07 15:41:39 +02:00
ERR_FAIL_COND_V ( ! tile_set . is_valid ( ) , Vector2 ( ) ) ;
Vector2 ret = p_pos ;
TileSet : : TileShape tile_shape = tile_set - > get_tile_shape ( ) ;
TileSet : : TileOffsetAxis tile_offset_axis = tile_set - > get_tile_offset_axis ( ) ;
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.
2023-06-16 14:16:37 +02:00
// square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap.
2021-05-07 15:41:39 +02:00
if ( tile_offset_axis = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
switch ( tile_set - > get_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 ;
}
2023-06-16 14:16:37 +02:00
} else { // TILE_OFFSET_AXIS_VERTICAL.
2021-05-07 15:41:39 +02:00
switch ( tile_set - > get_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 ;
}
}
}
2023-06-16 14:16:37 +02:00
// Multiply by the overlapping ratio.
2021-05-07 15:41:39 +02:00
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 ;
2023-06-16 14:16:37 +02:00
} else { // TILE_OFFSET_AXIS_VERTICAL.
2021-05-07 15:41:39 +02:00
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 ;
2019-02-06 00:45:40 +01:00
}
2021-05-07 15:41:39 +02:00
return ( ret + Vector2 ( 0.5 , 0.5 ) ) * tile_set - > get_tile_size ( ) ;
2014-10-03 05:10:51 +02:00
}
2017-10-22 03:42:23 +02:00
2022-08-20 18:39:05 +02:00
Vector2i TileMap : : local_to_map ( const Vector2 & p_local_position ) const {
2020-06-30 08:34:15 +02:00
ERR_FAIL_COND_V ( ! tile_set . is_valid ( ) , Vector2i ( ) ) ;
2014-10-03 05:10:51 +02:00
2022-08-20 18:39:05 +02:00
Vector2 ret = p_local_position ;
2021-05-07 15:41:39 +02:00
ret / = tile_set - > get_tile_size ( ) ;
2021-05-02 23:34:51 +02:00
2021-05-07 15:41:39 +02:00
TileSet : : TileShape tile_shape = tile_set - > get_tile_shape ( ) ;
TileSet : : TileOffsetAxis tile_offset_axis = tile_set - > get_tile_offset_axis ( ) ;
TileSet : : TileLayout tile_layout = tile_set - > get_tile_layout ( ) ;
2023-06-16 14:16:37 +02:00
// Divide by the overlapping ratio.
2021-05-07 15:41:39 +02:00
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 ;
2023-06-16 14:16:37 +02:00
} else { // TILE_OFFSET_AXIS_VERTICAL.
2021-05-07 15:41:39 +02:00
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 ;
}
2022-08-20 18:39:05 +02:00
// For each half-offset shape, we check if we are in the corner of the tile, and thus should correct the local position accordingly.
2021-05-07 15:41:39 +02:00
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.
2023-06-16 14:16:37 +02:00
// square = no overlap, hexagon = 0.25 overlap, isometric = 0.5 overlap.
2021-05-07 15:41:39 +02:00
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 ( ) ;
2014-10-03 05:10:51 +02:00
}
2021-05-07 15:41:39 +02:00
2023-06-16 14:16:37 +02:00
// Compute the tile offset, and if we might the output for a neighbor top tile.
2021-05-07 15:41:39 +02:00
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 ;
2019-03-24 00:59:24 +01:00
}
2023-06-16 14:16:37 +02:00
} else { // TILE_OFFSET_AXIS_VERTICAL.
// Smart floor of the position.
2021-05-07 15:41:39 +02:00
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 ( ) ;
2014-10-03 05:10:51 +02:00
}
2021-05-07 15:41:39 +02:00
2023-06-16 14:16:37 +02:00
// Compute the tile offset, and if we might the output for a neighbor top tile.
2021-05-07 15:41:39 +02:00
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 ;
2019-03-24 00:59:24 +01:00
}
2019-04-09 17:08:36 +02:00
}
2021-05-07 15:41:39 +02:00
} else {
ret = ( ret + Vector2 ( 0.00005 , 0.00005 ) ) . floor ( ) ;
2014-10-03 05:10:51 +02:00
}
2020-06-30 08:34:15 +02:00
return Vector2i ( ret ) ;
2014-10-03 05:10:51 +02:00
}
2021-05-07 15:41:39 +02:00
bool TileMap : : is_existing_neighbor ( TileSet : : CellNeighbor p_cell_neighbor ) const {
ERR_FAIL_COND_V ( ! tile_set . is_valid ( ) , false ) ;
TileSet : : TileShape shape = tile_set - > get_tile_shape ( ) ;
if ( shape = = TileSet : : TILE_SHAPE_SQUARE ) {
return p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_SIDE | |
2021-10-28 15:19:35 +02:00
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 ;
2021-05-07 15:41:39 +02:00
} else if ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC ) {
return p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER | |
2021-10-28 15:19:35 +02:00
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 ;
2021-05-07 15:41:39 +02:00
} else {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
return p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_SIDE | |
2021-10-28 15:19:35 +02:00
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 ;
2021-05-07 15:41:39 +02:00
} else {
return p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE | |
2021-10-28 15:19:35 +02:00
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 ;
2021-05-07 15:41:39 +02:00
}
}
2015-03-09 06:34:56 +01:00
}
2021-05-07 15:41:39 +02:00
Vector2i TileMap : : get_neighbor_cell ( const Vector2i & p_coords , TileSet : : CellNeighbor p_cell_neighbor ) const {
ERR_FAIL_COND_V ( ! tile_set . is_valid ( ) , p_coords ) ;
TileSet : : TileShape shape = tile_set - > get_tile_shape ( ) ;
if ( 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 ) ;
}
2023-06-16 14:16:37 +02:00
} else { // Half-offset shapes (square and hexagon).
2021-05-07 15:41:39 +02:00
switch ( tile_set - > get_tile_layout ( ) ) {
case TileSet : : TILE_LAYOUT_STACKED : {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
bool is_offset = p_coords . y % 2 ;
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
bool is_offset = p_coords . y % 2 ;
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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_set - > get_tile_layout ( ) = = TileSet : : TILE_LAYOUT_STAIRS_RIGHT ) ^ ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ) ;
}
2015-03-09 06:34:56 +01:00
2021-05-07 15:41:39 +02:00
} else {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ) ;
}
2019-07-01 22:43:52 +02:00
2021-05-07 15:41:39 +02:00
} else {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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_set - > get_tile_layout ( ) = = TileSet : : TILE_LAYOUT_DIAMOND_RIGHT ) ^ ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_VERTICAL ) ) {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ) ;
}
2019-07-01 22:43:52 +02:00
2021-05-07 15:41:39 +02:00
} else {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_RIGHT_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ) ;
}
2019-07-01 22:43:52 +02:00
2021-05-07 15:41:39 +02:00
} else {
if ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_BOTTOM_CORNER ) | |
( 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 ( 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 ( ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_CORNER ) | |
2021-10-28 15:19:35 +02:00
( shape ! = TileSet : : TILE_SHAPE_ISOMETRIC & & p_cell_neighbor = = TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) {
2021-05-07 15:41:39 +02:00
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 ( 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 ) ;
}
}
2019-07-01 22:43:52 +02:00
}
2021-07-28 18:10:01 +02:00
TypedArray < Vector2i > TileMap : : get_used_cells ( int p_layer ) const {
2023-06-16 14:16:37 +02:00
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TypedArray < Vector2i > ( ) , get_used_cells ) ;
2015-04-18 19:00:15 +02:00
}
2014-05-14 06:22:15 +02:00
2023-01-18 13:35:58 +01:00
TypedArray < Vector2i > TileMap : : get_used_cells_by_id ( int p_layer , int p_source_id , const Vector2i p_atlas_coords , int p_alternative_tile ) const {
2023-08-17 19:55:56 +02:00
TILEMAP_CALL_FOR_LAYER_V ( p_layer , TypedArray < Vector2i > ( ) , get_used_cells_by_id , p_source_id , p_atlas_coords , p_alternative_tile ) ;
2023-01-18 13:35:58 +01:00
}
2023-06-16 14:16:37 +02:00
Rect2i TileMap : : get_used_rect ( ) const {
// Return the visible rect of the tilemap.
2023-09-07 18:16:50 +02:00
bool first = true ;
Rect2i rect = Rect2i ( ) ;
for ( const Ref < TileMapLayer > & layer : layers ) {
Rect2i layer_rect = layer - > get_used_rect ( ) ;
if ( layer_rect = = Rect2i ( ) ) {
continue ;
}
if ( first ) {
rect = layer_rect ;
first = false ;
} else {
rect = rect . merge ( layer_rect ) ;
}
2023-06-16 14:16:37 +02:00
}
return rect ;
2017-02-20 22:02:03 +01:00
}
2021-05-07 15:41:39 +02:00
// --- Override some methods of the CanvasItem class to pass the changes to the quadrants CanvasItems ---
2015-12-12 14:45:31 +01:00
2015-12-29 18:47:13 +01:00
void TileMap : : set_light_mask ( int p_light_mask ) {
2021-05-07 15:41:39 +02:00
// Occlusion: set light mask.
2015-12-29 18:47:13 +01:00
CanvasItem : : set_light_mask ( p_light_mask ) ;
2023-06-16 14:16:37 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_LIGHT_MASK ) ;
2015-12-29 18:47:13 +01:00
}
}
2015-12-12 14:45:31 +01:00
2021-05-07 15:41:39 +02:00
void TileMap : : set_material ( const Ref < Material > & p_material ) {
// Set material for the whole tilemap.
CanvasItem : : set_material ( p_material ) ;
2017-11-10 13:21:33 +01:00
2021-05-07 15:41:39 +02:00
// Update material for the whole tilemap.
2023-06-16 14:16:37 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_MATERIAL ) ;
2021-05-07 15:41:39 +02:00
}
2017-11-10 13:21:33 +01:00
}
2021-05-07 15:41:39 +02:00
void TileMap : : set_use_parent_material ( bool p_use_parent_material ) {
// Set use_parent_material for the whole tilemap.
CanvasItem : : set_use_parent_material ( p_use_parent_material ) ;
// Update use_parent_material for the whole tilemap.
2023-06-16 14:16:37 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_USE_PARENT_MATERIAL ) ;
2021-05-07 15:41:39 +02:00
}
2017-11-10 13:21:33 +01:00
}
2020-02-19 22:26:24 +01:00
void TileMap : : set_texture_filter ( TextureFilter p_texture_filter ) {
2022-10-19 13:24:23 +02:00
// Set a default texture filter for the whole tilemap.
2020-02-19 22:26:24 +01:00
CanvasItem : : set_texture_filter ( p_texture_filter ) ;
2023-06-16 14:16:37 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_TEXTURE_FILTER ) ;
2020-02-19 22:26:24 +01:00
}
}
void TileMap : : set_texture_repeat ( CanvasItem : : TextureRepeat p_texture_repeat ) {
2022-10-19 13:24:23 +02:00
// Set a default texture repeat for the whole tilemap.
2020-02-19 22:26:24 +01:00
CanvasItem : : set_texture_repeat ( p_texture_repeat ) ;
2023-06-16 14:16:37 +02:00
for ( Ref < TileMapLayer > & layer : layers ) {
2023-08-24 13:31:14 +02:00
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_TEXTURE_REPEAT ) ;
2020-02-19 22:26:24 +01:00
}
}
2022-12-12 11:33:42 +01:00
TypedArray < Vector2i > TileMap : : get_surrounding_cells ( const Vector2i & coords ) {
2021-05-07 15:41:39 +02:00
if ( ! tile_set . is_valid ( ) ) {
return TypedArray < Vector2i > ( ) ;
}
2019-02-06 00:45:40 +01:00
2021-05-07 15:41:39 +02:00
TypedArray < Vector2i > around ;
TileSet : : TileShape shape = tile_set - > get_tile_shape ( ) ;
if ( shape = = TileSet : : TILE_SHAPE_SQUARE ) {
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_RIGHT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) ;
} else if ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC ) {
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE ) ) ;
} else {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_RIGHT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE ) ) ;
} else {
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_SIDE ) ) ;
around . push_back ( get_neighbor_cell ( coords , TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE ) ) ;
}
2019-02-06 00:45:40 +01:00
}
2021-05-07 15:41:39 +02:00
return around ;
2019-02-06 00:45:40 +01:00
}
2022-12-12 11:33:42 +01:00
void TileMap : : draw_cells_outline ( Control * p_control , const RBSet < Vector2i > & p_cells , Color p_color , Transform2D p_transform ) {
2021-05-07 15:41:39 +02:00
if ( ! tile_set . is_valid ( ) ) {
return ;
}
2014-10-03 05:10:51 +02:00
2021-05-07 15:41:39 +02:00
// Create a set.
Vector2i tile_size = tile_set - > get_tile_size ( ) ;
2021-09-14 12:02:13 +02:00
Vector < Vector2 > polygon = tile_set - > get_tile_shape_polygon ( ) ;
TileSet : : TileShape shape = tile_set - > get_tile_shape ( ) ;
2014-10-03 05:10:51 +02:00
2022-05-19 01:43:40 +02:00
for ( const Vector2i & E : p_cells ) {
2022-08-20 18:39:05 +02:00
Vector2 center = map_to_local ( E ) ;
2021-09-14 12:02:13 +02:00
# define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \
2022-05-19 01:43:40 +02:00
if ( ! p_cells . has ( get_neighbor_cell ( E , side ) ) ) { \
2021-09-14 12:02:13 +02:00
Vector2 from = p_transform . xform ( center + polygon [ polygon_index_from ] * tile_size ) ; \
Vector2 to = p_transform . xform ( center + polygon [ polygon_index_to ] * tile_size ) ; \
p_control - > draw_line ( from , to , p_color ) ; \
2021-05-07 15:41:39 +02:00
}
2014-02-10 02:10:30 +01:00
2021-09-14 12:02:13 +02:00
if ( shape = = TileSet : : TILE_SHAPE_SQUARE ) {
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_RIGHT_SIDE , 1 , 2 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_SIDE , 2 , 3 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_LEFT_SIDE , 3 , 0 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_SIDE , 0 , 1 ) ;
2022-12-18 01:57:54 +01:00
} else if ( shape = = TileSet : : TILE_SHAPE_ISOMETRIC ) {
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE , 2 , 3 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE , 1 , 2 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE , 0 , 1 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE , 3 , 0 ) ;
2021-09-14 12:02:13 +02:00
} else {
if ( tile_set - > get_tile_offset_axis ( ) = = TileSet : : TILE_OFFSET_AXIS_HORIZONTAL ) {
2022-12-18 01:57:54 +01:00
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE , 3 , 4 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE , 2 , 3 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_LEFT_SIDE , 1 , 2 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE , 0 , 1 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE , 5 , 0 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_RIGHT_SIDE , 4 , 5 ) ;
2021-09-14 12:02:13 +02:00
} else {
2022-12-18 01:57:54 +01:00
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE , 3 , 4 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_SIDE , 4 , 5 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_BOTTOM_LEFT_SIDE , 5 , 0 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_LEFT_SIDE , 0 , 1 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_SIDE , 1 , 2 ) ;
DRAW_SIDE_IF_NEEDED ( TileSet : : CELL_NEIGHBOR_TOP_RIGHT_SIDE , 2 , 3 ) ;
2021-05-07 15:41:39 +02:00
}
}
}
2021-09-14 12:02:13 +02:00
# undef DRAW_SIDE_IF_NEEDED
2021-05-07 15:41:39 +02:00
}
2014-02-10 02:10:30 +01:00
2022-09-19 17:43:15 +02:00
PackedStringArray TileMap : : get_configuration_warnings ( ) const {
PackedStringArray warnings = Node : : get_configuration_warnings ( ) ;
2021-07-28 18:10:01 +02:00
// Retrieve the set of Z index values with a Y-sorted layer.
2022-05-13 15:04:37 +02:00
RBSet < int > y_sorted_z_index ;
2023-06-16 14:16:37 +02:00
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( layer - > is_y_sort_enabled ( ) ) {
y_sorted_z_index . insert ( layer - > get_z_index ( ) ) ;
2021-07-28 18:10:01 +02:00
}
}
// Check if we have a non-sorted layer in a Z-index with a Y-sorted layer.
2023-06-16 14:16:37 +02:00
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( ! layer - > is_y_sort_enabled ( ) & & y_sorted_z_index . has ( layer - > get_z_index ( ) ) ) {
2022-03-28 15:24:14 +02:00
warnings . push_back ( RTR ( " A Y-sorted layer has the same Z-index value as a not Y-sorted layer. \n This may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole with tiles from Y-sorted layers. " ) ) ;
2021-07-28 18:10:01 +02:00
break ;
}
}
2023-01-30 10:34:35 +01:00
if ( ! is_y_sort_enabled ( ) ) {
2023-10-11 13:34:18 +02:00
// Check if Y-sort is enabled on a layer but not on the node.
2023-06-16 14:16:37 +02:00
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( layer - > is_y_sort_enabled ( ) ) {
2023-01-30 10:34:35 +01:00
warnings . push_back ( RTR ( " A TileMap layer is set as Y-sorted, but Y-sort is not enabled on the TileMap node itself. " ) ) ;
break ;
}
}
2023-10-11 13:34:18 +02:00
} else {
// Check if Y-sort is enabled on the node, but not on any of the layers.
bool need_warning = true ;
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( layer - > is_y_sort_enabled ( ) ) {
need_warning = false ;
break ;
}
}
if ( need_warning ) {
warnings . push_back ( RTR ( " The TileMap node is set as Y-sorted, but Y-sort is not enabled on any of the TileMap's layers. \n This may lead to unwanted behaviors, as a layer that is not Y-sorted will be Y-sorted as a whole. " ) ) ;
}
2023-01-30 10:34:35 +01:00
}
// Check if we are in isometric mode without Y-sort enabled.
2022-10-07 22:27:31 +02:00
if ( tile_set . is_valid ( ) & & tile_set - > get_tile_shape ( ) = = TileSet : : TILE_SHAPE_ISOMETRIC ) {
bool warn = ! is_y_sort_enabled ( ) ;
if ( ! warn ) {
2023-06-16 14:16:37 +02:00
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( ! layer - > is_y_sort_enabled ( ) ) {
2022-10-07 22:27:31 +02:00
warn = true ;
break ;
}
}
}
if ( warn ) {
warnings . push_back ( RTR ( " Isometric TileSet will likely not look as intended without Y-sort enabled for the TileMap and all of its layers. " ) ) ;
}
}
2021-07-28 18:10:01 +02:00
return warnings ;
}
2021-05-07 15:41:39 +02:00
void TileMap : : _bind_methods ( ) {
2023-08-24 13:31:14 +02:00
# ifndef DISABLE_DEPRECATED
ClassDB : : bind_method ( D_METHOD ( " set_navigation_map " , " layer " , " map " ) , & TileMap : : set_layer_navigation_map ) ;
ClassDB : : bind_method ( D_METHOD ( " get_navigation_map " , " layer " ) , & TileMap : : get_layer_navigation_map ) ;
ClassDB : : bind_method ( D_METHOD ( " force_update " , " layer " ) , & TileMap : : force_update , DEFVAL ( - 1 ) ) ;
# endif // DISABLE_DEPRECATED
2021-05-07 15:41:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_tileset " , " tileset " ) , & TileMap : : set_tileset ) ;
ClassDB : : bind_method ( D_METHOD ( " get_tileset " ) , & TileMap : : get_tileset ) ;
2014-10-03 05:10:51 +02:00
2023-08-24 13:31:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_rendering_quadrant_size " , " size " ) , & TileMap : : set_rendering_quadrant_size ) ;
ClassDB : : bind_method ( D_METHOD ( " get_rendering_quadrant_size " ) , & TileMap : : get_rendering_quadrant_size ) ;
2014-02-10 02:10:30 +01:00
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_layers_count " ) , & TileMap : : get_layers_count ) ;
2021-09-06 11:56:31 +02:00
ClassDB : : bind_method ( D_METHOD ( " add_layer " , " to_position " ) , & TileMap : : add_layer ) ;
ClassDB : : bind_method ( D_METHOD ( " move_layer " , " layer " , " to_position " ) , & TileMap : : move_layer ) ;
ClassDB : : bind_method ( D_METHOD ( " remove_layer " , " layer " ) , & TileMap : : remove_layer ) ;
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_layer_name " , " layer " , " name " ) , & TileMap : : set_layer_name ) ;
ClassDB : : bind_method ( D_METHOD ( " get_layer_name " , " layer " ) , & TileMap : : get_layer_name ) ;
ClassDB : : bind_method ( D_METHOD ( " set_layer_enabled " , " layer " , " enabled " ) , & TileMap : : set_layer_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " is_layer_enabled " , " layer " ) , & TileMap : : is_layer_enabled ) ;
2021-11-03 12:49:13 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_layer_modulate " , " layer " , " modulate " ) , & TileMap : : set_layer_modulate ) ;
2021-10-10 17:04:25 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_layer_modulate " , " layer " ) , & TileMap : : get_layer_modulate ) ;
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_layer_y_sort_enabled " , " layer " , " y_sort_enabled " ) , & TileMap : : set_layer_y_sort_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " is_layer_y_sort_enabled " , " layer " ) , & TileMap : : is_layer_y_sort_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " set_layer_y_sort_origin " , " layer " , " y_sort_origin " ) , & TileMap : : set_layer_y_sort_origin ) ;
ClassDB : : bind_method ( D_METHOD ( " get_layer_y_sort_origin " , " layer " ) , & TileMap : : get_layer_y_sort_origin ) ;
ClassDB : : bind_method ( D_METHOD ( " set_layer_z_index " , " layer " , " z_index " ) , & TileMap : : set_layer_z_index ) ;
2021-09-06 11:56:31 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_layer_z_index " , " layer " ) , & TileMap : : get_layer_z_index ) ;
2023-10-13 17:22:51 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_layer_navigation_enabled " , " layer " , " enabled " ) , & TileMap : : set_layer_navigation_enabled ) ;
ClassDB : : bind_method ( D_METHOD ( " is_layer_navigation_enabled " , " layer " ) , & TileMap : : is_layer_navigation_enabled ) ;
2023-06-16 14:16:37 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_layer_navigation_map " , " layer " , " map " ) , & TileMap : : set_layer_navigation_map ) ;
ClassDB : : bind_method ( D_METHOD ( " get_layer_navigation_map " , " layer " ) , & TileMap : : get_layer_navigation_map ) ;
2021-09-15 15:23:58 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_animatable " , " enabled " ) , & TileMap : : set_collision_animatable ) ;
ClassDB : : bind_method ( D_METHOD ( " is_collision_animatable " ) , & TileMap : : is_collision_animatable ) ;
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_collision_visibility_mode " , " collision_visibility_mode " ) , & TileMap : : set_collision_visibility_mode ) ;
2021-05-24 12:33:22 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_collision_visibility_mode " ) , & TileMap : : get_collision_visibility_mode ) ;
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " set_navigation_visibility_mode " , " navigation_visibility_mode " ) , & TileMap : : set_navigation_visibility_mode ) ;
2021-05-24 12:33:22 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_navigation_visibility_mode " ) , & TileMap : : get_navigation_visibility_mode ) ;
2022-03-01 19:25:18 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_cell " , " layer " , " coords " , " source_id " , " atlas_coords " , " alternative_tile " ) , & TileMap : : set_cell , DEFVAL ( TileSet : : INVALID_SOURCE ) , DEFVAL ( TileSetSource : : INVALID_ATLAS_COORDS ) , DEFVAL ( 0 ) ) ;
ClassDB : : bind_method ( D_METHOD ( " erase_cell " , " layer " , " coords " ) , & TileMap : : erase_cell ) ;
2022-08-16 14:58:45 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_cell_source_id " , " layer " , " coords " , " use_proxies " ) , & TileMap : : get_cell_source_id , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_cell_atlas_coords " , " layer " , " coords " , " use_proxies " ) , & TileMap : : get_cell_atlas_coords , DEFVAL ( false ) ) ;
ClassDB : : bind_method ( D_METHOD ( " get_cell_alternative_tile " , " layer " , " coords " , " use_proxies " ) , & TileMap : : get_cell_alternative_tile , DEFVAL ( false ) ) ;
2021-11-03 14:58:12 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_cell_tile_data " , " layer " , " coords " , " use_proxies " ) , & TileMap : : get_cell_tile_data , DEFVAL ( false ) ) ;
2018-12-20 18:43:44 +01:00
2021-09-15 15:23:58 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_coords_for_body_rid " , " body " ) , & TileMap : : get_coords_for_body_rid ) ;
2023-04-19 06:22:46 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_layer_for_body_rid " , " body " ) , & TileMap : : get_layer_for_body_rid ) ;
2021-09-15 15:23:58 +02:00
2021-09-29 17:48:27 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_pattern " , " layer " , " coords_array " ) , & TileMap : : get_pattern ) ;
ClassDB : : bind_method ( D_METHOD ( " map_pattern " , " position_in_tilemap " , " coords_in_pattern " , " pattern " ) , & TileMap : : map_pattern ) ;
ClassDB : : bind_method ( D_METHOD ( " set_pattern " , " layer " , " position " , " pattern " ) , & TileMap : : set_pattern ) ;
2022-02-23 17:25:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " set_cells_terrain_connect " , " layer " , " cells " , " terrain_set " , " terrain " , " ignore_empty_terrains " ) , & TileMap : : set_cells_terrain_connect , DEFVAL ( true ) ) ;
ClassDB : : bind_method ( D_METHOD ( " set_cells_terrain_path " , " layer " , " path " , " terrain_set " , " terrain " , " ignore_empty_terrains " ) , & TileMap : : set_cells_terrain_path , DEFVAL ( true ) ) ;
2021-10-21 16:42:06 +02:00
2018-02-24 06:56:48 +01:00
ClassDB : : bind_method ( D_METHOD ( " fix_invalid_tiles " ) , & TileMap : : fix_invalid_tiles ) ;
2021-09-15 15:23:58 +02:00
ClassDB : : bind_method ( D_METHOD ( " clear_layer " , " layer " ) , & TileMap : : clear_layer ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " clear " ) , & TileMap : : clear ) ;
2014-02-10 02:10:30 +01:00
2023-08-24 13:31:14 +02:00
ClassDB : : bind_method ( D_METHOD ( " update_internals " ) , & TileMap : : update_internals ) ;
ClassDB : : bind_method ( D_METHOD ( " notify_runtime_tile_data_update " , " layer " ) , & TileMap : : notify_runtime_tile_data_update , DEFVAL ( - 1 ) ) ;
2021-10-22 16:32:06 +02:00
2022-12-07 11:09:10 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_surrounding_cells " , " coords " ) , & TileMap : : get_surrounding_cells ) ;
2021-09-15 15:23:58 +02:00
2021-07-28 18:10:01 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_used_cells " , " layer " ) , & TileMap : : get_used_cells ) ;
2023-01-18 13:35:58 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_used_cells_by_id " , " layer " , " source_id " , " atlas_coords " , " alternative_tile " ) , & TileMap : : get_used_cells_by_id , DEFVAL ( TileSet : : INVALID_SOURCE ) , DEFVAL ( TileSetSource : : INVALID_ATLAS_COORDS ) , DEFVAL ( TileSetSource : : INVALID_TILE_ALTERNATIVE ) ) ;
2017-03-05 16:44:50 +01:00
ClassDB : : bind_method ( D_METHOD ( " get_used_rect " ) , & TileMap : : get_used_rect ) ;
2015-04-18 19:00:15 +02:00
2022-08-20 18:39:05 +02:00
ClassDB : : bind_method ( D_METHOD ( " map_to_local " , " map_position " ) , & TileMap : : map_to_local ) ;
ClassDB : : bind_method ( D_METHOD ( " local_to_map " , " local_position " ) , & TileMap : : local_to_map ) ;
2014-10-03 05:10:51 +02:00
2021-05-07 15:41:39 +02:00
ClassDB : : bind_method ( D_METHOD ( " get_neighbor_cell " , " coords " , " neighbor " ) , & TileMap : : get_neighbor_cell ) ;
2014-02-10 02:10:30 +01:00
2021-10-22 16:32:06 +02:00
GDVIRTUAL_BIND ( _use_tile_data_runtime_update , " layer " , " coords " ) ;
GDVIRTUAL_BIND ( _tile_data_runtime_update , " layer " , " coords " , " tile_data " ) ;
2017-03-05 16:44:50 +01:00
ADD_PROPERTY ( PropertyInfo ( Variant : : OBJECT , " tile_set " , PROPERTY_HINT_RESOURCE_TYPE , " TileSet " ) , " set_tileset " , " get_tileset " ) ;
2023-08-24 13:31:14 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " rendering_quadrant_size " , PROPERTY_HINT_RANGE , " 1,128,1 " ) , " set_rendering_quadrant_size " , " get_rendering_quadrant_size " ) ;
2021-09-15 15:23:58 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : BOOL , " collision_animatable " ) , " set_collision_animatable " , " is_collision_animatable " ) ;
2021-07-28 18:10:01 +02:00
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " collision_visibility_mode " , PROPERTY_HINT_ENUM , " Default,Force Show,Force Hide " ) , " set_collision_visibility_mode " , " get_collision_visibility_mode " ) ;
ADD_PROPERTY ( PropertyInfo ( Variant : : INT , " navigation_visibility_mode " , PROPERTY_HINT_ENUM , " Default,Force Show,Force Hide " ) , " set_navigation_visibility_mode " , " get_navigation_visibility_mode " ) ;
2021-08-31 10:48:45 +02:00
ADD_ARRAY ( " layers " , " layer_ " ) ;
2021-03-08 09:47:18 +01:00
2024-01-05 11:58:21 +01:00
ADD_PROPERTY_DEFAULT ( " format " , TileMapDataFormat : : FORMAT_1 ) ;
2019-08-08 08:30:55 +02:00
2023-06-16 14:16:37 +02:00
ADD_SIGNAL ( MethodInfo ( CoreStringNames : : get_singleton ( ) - > changed ) ) ;
2021-05-24 12:33:22 +02:00
BIND_ENUM_CONSTANT ( VISIBILITY_MODE_DEFAULT ) ;
BIND_ENUM_CONSTANT ( VISIBILITY_MODE_FORCE_HIDE ) ;
BIND_ENUM_CONSTANT ( VISIBILITY_MODE_FORCE_SHOW ) ;
2021-05-07 15:41:39 +02:00
}
2017-08-20 17:45:01 +02:00
2021-05-07 15:41:39 +02:00
void TileMap : : _tile_set_changed ( ) {
2023-06-16 14:16:37 +02:00
emit_signal ( CoreStringNames : : get_singleton ( ) - > changed ) ;
2023-08-24 13:31:14 +02:00
for ( Ref < TileMapLayer > layer : layers ) {
layer - > notify_tile_map_change ( TileMapLayer : : DIRTY_FLAGS_TILE_MAP_TILE_SET ) ;
2023-06-16 14:16:37 +02:00
}
2022-10-07 22:27:31 +02:00
update_configuration_warnings ( ) ;
2021-10-13 14:49:28 +02:00
}
2023-09-18 16:30:06 +02:00
void TileMap : : _update_notify_local_transform ( ) {
bool notify = collision_animatable | | is_y_sort_enabled ( ) ;
if ( ! notify ) {
for ( const Ref < TileMapLayer > & layer : layers ) {
if ( layer - > is_y_sort_enabled ( ) ) {
notify = true ;
break ;
}
}
}
set_notify_local_transform ( notify ) ;
}
2014-02-10 02:10:30 +01:00
TileMap : : TileMap ( ) {
2017-01-13 00:35:46 +01:00
set_notify_transform ( true ) ;
2023-09-18 16:30:06 +02:00
_update_notify_local_transform ( ) ;
2021-07-28 18:10:01 +02:00
2023-06-16 14:16:37 +02:00
Ref < TileMapLayer > new_layer ;
new_layer . instantiate ( ) ;
new_layer - > set_tile_map ( this ) ;
new_layer - > set_layer_index_in_tile_map_node ( 0 ) ;
layers . push_back ( new_layer ) ;
2023-10-24 13:38:29 +02:00
default_layer . instantiate ( ) ;
2014-02-10 02:10:30 +01:00
}
TileMap : : ~ TileMap ( ) {
2022-12-11 19:21:10 +01:00
if ( tile_set . is_valid ( ) ) {
2023-07-03 21:29:37 +02:00
tile_set - > disconnect_changed ( callable_mp ( this , & TileMap : : _tile_set_changed ) ) ;
2022-12-11 19:21:10 +01:00
}
2014-02-10 02:10:30 +01:00
}
2023-06-16 14:16:37 +02:00
# undef TILEMAP_CALL_FOR_LAYER
# undef TILEMAP_CALL_FOR_LAYER_V