summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/FileDialog.xml2
-rw-r--r--doc/classes/TileSet.xml183
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp2
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp1
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h1
-rw-r--r--drivers/gles2/shaders/scene.glsl2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp582
-rw-r--r--editor/plugins/tile_set_editor_plugin.h9
-rw-r--r--scene/resources/tile_set.cpp26
-rw-r--r--scene/resources/tile_set.h1
-rw-r--r--servers/visual/shader_language.cpp7
14 files changed, 611 insertions, 212 deletions
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index 29aa26b67f..0af645975a 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -76,7 +76,7 @@
Set dialog to open or save mode, changes selection behavior. See enum [code]Mode[/code] constants.
</member>
<member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title">
- If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e. g. setting mode to [code]MODE_OPEN_FILE[/code] will change the window title to "Open a File").
+ If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [code]MODE_OPEN_FILE[/code] will change the window title to "Open a File").
</member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files">
If [code]true[/code], the dialog will show hidden files.
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index ffd15e8d8b..fadc6fbcb9 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -36,12 +36,66 @@
<description>
</description>
</method>
+ <method name="autotile_clear_bitmask_map">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Clears all bitmask info of the autotile.
+ </description>
+ </method>
+ <method name="autotile_get_bitmask">
+ <return type="int" enum="TileSet.AutotileBindings">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the bitmask of the subtile from an autotile given its coordinates.
+ The value is the sum of the values in [enum TileSet.AutotileBindings] present in the subtile (e.g. a value of 5 means the bitmask has bindings in both the top left and top right).
+ </description>
+ </method>
<method name="autotile_get_bitmask_mode" qualifiers="const">
<return type="int" enum="TileSet.BitmaskMode">
</return>
<argument index="0" name="id" type="int">
</argument>
<description>
+ Returns the [enum TileSet.BitmaskMode] of the autotile.
+ </description>
+ </method>
+ <method name="autotile_get_icon_coordinate" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Returns the subtile that's being used as an icon in an atlas/autotile given its coordinates.
+ The subtile defined as the icon will be used as a fallback when the atlas/autotile's bitmask info is incomplete. It will also be used to represent it in the TileSet editor.
+ </description>
+ </method>
+ <method name="autotile_get_light_occluder" qualifiers="const">
+ <return type="OccluderPolygon2D">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the light occluder of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_get_navigation_polygon" qualifiers="const">
+ <return type="NavigationPolygon">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the navigation polygon of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="autotile_get_size" qualifiers="const">
@@ -50,6 +104,53 @@
<argument index="0" name="id" type="int">
</argument>
<description>
+ Returns the size of the subtiles in an atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_get_spacing" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Returns the spacing between subtiles of the atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_get_subtile_priority">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the priority of the subtile from an autotile given its coordinates.
+ When more than one subtile has the same bitmask value, one of them will be picked randomly for drawing. Its priority will define how often it will be picked.
+ </description>
+ </method>
+ <method name="autotile_get_z_index">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the drawing index of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_set_bitmask">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="bitmask" type="Vector2">
+ </argument>
+ <argument index="2" name="flag" type="int" enum="TileSet.AutotileBindings">
+ </argument>
+ <description>
+ Sets the bitmask of the subtile from an autotile given its coordinates.
+ The value is the sum of the values in [enum TileSet.AutotileBindings] present in the subtile (e.g. a value of 5 means the bitmask has bindings in both the top left and top right).
</description>
</method>
<method name="autotile_set_bitmask_mode">
@@ -60,6 +161,45 @@
<argument index="1" name="mode" type="int" enum="TileSet.BitmaskMode">
</argument>
<description>
+ Sets the [enum TileSet.BitmaskMode] of the autotile.
+ </description>
+ </method>
+ <method name="autotile_set_icon_coordinate">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the subtile that will be used as an icon in an atlas/autotile given its coordinates.
+ The subtile defined as the icon will be used as a fallback when the atlas/autotile's bitmask info is incomplete. It will also be used to represent it in the TileSet editor.
+ </description>
+ </method>
+ <method name="autotile_set_light_occluder">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="light_occluder" type="OccluderPolygon2D">
+ </argument>
+ <argument index="2" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the light occluder of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_set_navigation_polygon">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="navigation_polygon" type="NavigationPolygon">
+ </argument>
+ <argument index="2" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the navigation polygon of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="autotile_set_size">
@@ -70,6 +210,45 @@
<argument index="1" name="size" type="Vector2">
</argument>
<description>
+ Sets the size of the subtiles in an atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_set_spacing">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="spacing" type="int">
+ </argument>
+ <description>
+ Sets the spacing between subtiles of the atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_set_subtile_priority">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <argument index="2" name="priority" type="int">
+ </argument>
+ <description>
+ Sets the priority of the subtile from an autotile given its coordinates.
+ When more than one subtile has the same bitmask value, one of them will be picked randomly for drawing. Its priority will define how often it will be picked.
+ </description>
+ </method>
+ <method name="autotile_set_z_index">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <argument index="2" name="z_index" type="int">
+ </argument>
+ <description>
+ Sets the drawing index of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="clear">
@@ -304,7 +483,7 @@
<argument index="0" name="id" type="int">
</argument>
<description>
- Returns the tile's [enum TileMode].
+ Returns the tile's [enum TileSet.TileMode].
</description>
</method>
<method name="tile_get_z_index" qualifiers="const">
@@ -508,7 +687,7 @@
<argument index="1" name="tilemode" type="int" enum="TileSet.TileMode">
</argument>
<description>
- Sets the tile's [enum TileMode].
+ Sets the tile's [enum TileSet.TileMode].
</description>
</method>
<method name="tile_set_z_index">
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 6aac35a332..f3fc356879 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -1288,7 +1288,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
int blend_mode = shader_cache ? shader_cache->canvas_item.blend_mode : RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX;
- bool unshaded = (shader_cache && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX);
+ bool unshaded = shader_cache && (shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
bool reclip = false;
if (last_blend_mode != blend_mode) {
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index b61a6ee27b..30d515cec5 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -4104,6 +4104,7 @@ RID RasterizerStorageGLES2::render_target_create() {
Texture *t = memnew(Texture);
+ t->type = VS::TEXTURE_TYPE_2D;
t->flags = 0;
t->width = 0;
t->height = 0;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index 0981308b15..b7c175e186 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -264,6 +264,7 @@ public:
alloc_width(0),
alloc_height(0),
format(Image::FORMAT_L8),
+ type(VS::TEXTURE_TYPE_2D),
target(0),
data_size(0),
total_data_size(0),
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index 4f334d2be2..5cdf4ff04d 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -1254,7 +1254,7 @@ LIGHT_SHADER_CODE
float YdotH = dot(B, H);
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH);
//float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
- float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL))
+ float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL);
#else
float alpha = roughness * roughness;
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 2b038fcc0e..84d3d80e0e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1995,7 +1995,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
actions = &shaders.actions_particles;
actions->uniforms = &p_shader->uniforms;
} break;
- case VS::SHADER_MAX: break; // Can't happen, but silences warning
+ case VS::SHADER_MAX:
+ break; // Can't happen, but silences warning
}
Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
@@ -7019,6 +7020,7 @@ RID RasterizerStorageGLES3::render_target_create() {
Texture *t = memnew(Texture);
+ t->type = VS::TEXTURE_TYPE_2D;
t->flags = 0;
t->width = 0;
t->height = 0;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 958086f6c7..bd234d7fbe 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -291,6 +291,7 @@ public:
width(0),
height(0),
format(Image::FORMAT_L8),
+ type(VS::TEXTURE_TYPE_2D),
target(GL_TEXTURE_2D),
data_size(0),
compressed(false),
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index c9367edec6..b56c0bbc1b 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -517,7 +517,7 @@ void TileMapEditor::_update_palette() {
manual_palette->show();
}
- if (tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) {
+ if (sel_tile != TileMap::INVALID_CELL && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) {
manual_button->show();
} else {
manual_button->hide();
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index 2f174cb4b6..297cf6754c 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -165,6 +165,11 @@ void TileSetEditor::_import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_
_import_node(p_scene, p_library);
}
+void TileSetEditor::_undo_redo_import_scene(Node *p_scene, bool p_merge) {
+
+ _import_scene(p_scene, tileset, p_merge);
+}
+
Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bool p_merge) {
_import_scene(p_base_scene, ml, p_merge);
@@ -173,6 +178,7 @@ Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bo
void TileSetEditor::_bind_methods() {
+ ClassDB::bind_method("_undo_redo_import_scene", &TileSetEditor::_undo_redo_import_scene);
ClassDB::bind_method("_on_tileset_toolbar_button_pressed", &TileSetEditor::_on_tileset_toolbar_button_pressed);
ClassDB::bind_method("_on_textures_added", &TileSetEditor::_on_textures_added);
ClassDB::bind_method("_on_tileset_toolbar_confirm", &TileSetEditor::_on_tileset_toolbar_confirm);
@@ -190,9 +196,16 @@ void TileSetEditor::_bind_methods() {
ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step);
ClassDB::bind_method("_set_snap_off", &TileSetEditor::_set_snap_off);
ClassDB::bind_method("_set_snap_sep", &TileSetEditor::_set_snap_sep);
+ ClassDB::bind_method("_validate_current_tile_id", &TileSetEditor::_validate_current_tile_id);
ClassDB::bind_method("_zoom_in", &TileSetEditor::_zoom_in);
ClassDB::bind_method("_zoom_out", &TileSetEditor::_zoom_out);
ClassDB::bind_method("_zoom_reset", &TileSetEditor::_zoom_reset);
+ ClassDB::bind_method("_select_edited_shape_coord", &TileSetEditor::_select_edited_shape_coord);
+
+ ClassDB::bind_method("edit", &TileSetEditor::edit);
+ ClassDB::bind_method("add_texture", &TileSetEditor::add_texture);
+ ClassDB::bind_method("remove_texture", &TileSetEditor::remove_texture);
+ ClassDB::bind_method("update_texture_list_icon", &TileSetEditor::update_texture_list_icon);
}
void TileSetEditor::_notification(int p_what) {
@@ -244,6 +257,7 @@ void TileSetEditor::_notification(int p_what) {
TileSetEditor::TileSetEditor(EditorNode *p_editor) {
editor = p_editor;
+ undo_redo = editor->get_undo_redo();
current_tile = -1;
VBoxContainer *left_container = memnew(VBoxContainer);
@@ -502,7 +516,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
} break;
case TOOL_TILESET_REMOVE_TEXTURE: {
if (get_current_texture().is_valid()) {
- cd->set_text(TTR("Remove selected texture and ALL TILES which use it?"));
+ cd->set_text(TTR("Remove selected texture? This will remove all tiles which use it."));
cd->popup_centered(Size2(300, 60));
} else {
err_dialog->set_text(TTR("You haven't selected a texture to remove."));
@@ -511,7 +525,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
} break;
case TOOL_TILESET_CREATE_SCENE: {
- cd->set_text(TTR("Create from scene?"));
+ cd->set_text(TTR("Create from scene? This will overwrite all current tiles."));
cd->popup_centered(Size2(300, 60));
} break;
case TOOL_TILESET_MERGE_SCENE: {
@@ -528,14 +542,18 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
RID current_rid = get_current_texture()->get_rid();
List<int> ids;
tileset->get_tile_list(&ids);
+
+ undo_redo->create_action(TTR("Remove Texture"));
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
if (tileset->tile_get_texture(E->get())->get_rid() == current_rid) {
- tileset->remove_tile(E->get());
+ undo_redo->add_do_method(tileset.ptr(), "remove_tile", E->get());
+ _undo_tile_removal(E->get());
}
}
- texture_list->remove_item(texture_list->find_metadata(current_rid));
- texture_map.erase(current_rid);
- _on_texture_list_selected(-1);
+ undo_redo->add_do_method(this, "remove_texture", get_current_texture());
+ undo_redo->add_undo_method(this, "add_texture", get_current_texture());
+ undo_redo->add_undo_method(this, "update_texture_list_icon");
+ undo_redo->commit_action();
} break;
case TOOL_TILESET_MERGE_SCENE:
case TOOL_TILESET_CREATE_SCENE: {
@@ -544,9 +562,19 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
Node *scene = en->get_edited_scene();
if (!scene)
break;
- _import_scene(scene, tileset, option == TOOL_TILESET_MERGE_SCENE);
- edit(tileset);
+ List<int> ids;
+ tileset->get_tile_list(&ids);
+
+ undo_redo->create_action(TTR(option == TOOL_TILESET_MERGE_SCENE ? "Merge Tileset from Scene" : "Create Tileset from Scene"));
+ undo_redo->add_do_method(this, "_undo_redo_import_scene", scene, option == TOOL_TILESET_MERGE_SCENE);
+ undo_redo->add_undo_method(tileset.ptr(), "clear");
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ _undo_tile_removal(E->get());
+ }
+ undo_redo->add_do_method(this, "edit", tileset);
+ undo_redo->add_undo_method(this, "edit", tileset);
+ undo_redo->commit_action();
} break;
}
}
@@ -580,9 +608,7 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
if (texture_map.has(t->get_rid())) {
invalid_count++;
} else {
- texture_list->add_item(t->get_path().get_file());
- texture_map.insert(t->get_rid(), t);
- texture_list->set_item_metadata(texture_list->get_item_count() - 1, t->get_rid());
+ add_texture(t);
}
}
@@ -653,7 +679,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
spin_priority->hide();
spin_z_index->hide();
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
} break;
case EDITMODE_BITMASK: {
tools[TOOL_SELECT]->show();
@@ -964,7 +990,6 @@ void TileSetEditor::_on_workspace_overlay_draw() {
}
}
-#define MIN_DISTANCE_SQUARED 6
void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if (tileset.is_null() || !get_current_texture().is_valid())
@@ -1043,29 +1068,49 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
edited_region.position -= WORKSPACE_MARGIN;
if (!edited_region.has_no_area()) {
if (get_current_tile() >= 0 && workspace_mode == WORKSPACE_EDIT) {
- tileset->tile_set_region(get_current_tile(), edited_region);
+ undo_redo->create_action(TTR("Set Tile Region"));
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_region", get_current_tile(), edited_region);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_region", get_current_tile(), tileset->tile_get_region(get_current_tile()));
+ edited_region = Rect2();
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
} else {
int t_id = tileset->get_last_unused_tile_id();
- tileset->create_tile(t_id);
- tileset->tile_set_texture(t_id, get_current_texture());
- tileset->tile_set_region(t_id, edited_region);
- tileset->tile_set_name(t_id, get_current_texture()->get_path().get_file() + " " + String::num(t_id, 0));
+ undo_redo->create_action(TTR("Create Tile"));
+ undo_redo->add_do_method(tileset.ptr(), "create_tile", t_id);
+ undo_redo->add_undo_method(tileset.ptr(), "remove_tile", t_id);
+ undo_redo->add_undo_method(this, "_validate_current_tile_id");
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_texture", t_id, get_current_texture());
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_region", t_id, edited_region);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_name", t_id, get_current_texture()->get_path().get_file() + " " + String::num(t_id, 0));
if (workspace_mode != WORKSPACE_CREATE_SINGLE) {
- tileset->autotile_set_size(t_id, snap_step);
- tileset->autotile_set_spacing(t_id, snap_separation.x);
- tileset->tile_set_tile_mode(t_id, workspace_mode == WORKSPACE_CREATE_AUTOTILE ? TileSet::AUTO_TILE : TileSet::ATLAS_TILE);
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_size", t_id, snap_step);
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_spacing", t_id, snap_separation.x);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_tile_mode", t_id, workspace_mode == WORKSPACE_CREATE_AUTOTILE ? TileSet::AUTO_TILE : TileSet::ATLAS_TILE);
}
- set_current_tile(t_id);
tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
edit_mode = EDITMODE_COLLISION;
+ edited_region = Rect2();
+
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
+
+ set_current_tile(t_id);
_on_workspace_mode_changed(WORKSPACE_EDIT);
}
+ } else {
+ edited_region = Rect2();
+ workspace->update();
+ workspace_overlay->update();
}
- edited_region = Rect2();
- workspace->update();
- workspace_overlay->update();
return;
}
} else if (mm.is_valid()) {
@@ -1078,8 +1123,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- if (workspace_mode == WORKSPACE_EDIT) {
+ if (workspace_mode == WORKSPACE_EDIT) {
if (get_current_tile() >= 0) {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
@@ -1088,13 +1133,12 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && current_tile_region.has_point(mb->get_position())) {
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
- tileset->autotile_set_icon_coordinate(get_current_tile(), coord);
- Rect2 region = tileset->tile_get_region(get_current_tile());
- region.size = size;
- coord.x *= (spacing + size.x);
- coord.y *= (spacing + size.y);
- region.position += coord;
- workspace->update();
+ undo_redo->create_action(TTR("Set Tile Icon"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_icon_coordinate", get_current_tile(), coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_icon_coordinate", get_current_tile(), tileset->autotile_get_icon_coordinate(get_current_tile()));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
}
} break;
@@ -1152,14 +1196,22 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+
+ uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+ uint16_t new_mask = old_mask;
if (erasing) {
- mask &= ~bit;
+ new_mask &= ~bit;
} else {
- mask |= bit;
+ new_mask |= bit;
+ }
+ if (old_mask != new_mask) {
+ undo_redo->create_action(TTR("Edit Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, old_mask);
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
- tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
- workspace->update();
}
} else {
if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) {
@@ -1215,14 +1267,22 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+
+ uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+ uint16_t new_mask = old_mask;
if (erasing) {
- mask &= ~bit;
+ new_mask &= ~bit;
} else {
- mask |= bit;
+ new_mask |= bit;
+ }
+ if (old_mask != new_mask) {
+ undo_redo->create_action(TTR("Edit Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, old_mask);
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
- tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
- workspace->update();
}
}
} break;
@@ -1237,13 +1297,14 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
shape_anchor.x *= (size.x + spacing);
shape_anchor.y *= (size.y + spacing);
}
+ const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
shape_anchor += current_tile_region.position;
if (tools[TOOL_SELECT]->is_pressed()) {
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) {
for (int i = 0; i < current_shape.size(); i++) {
- if ((current_shape[i] - mb->get_position()).length_squared() <= MIN_DISTANCE_SQUARED) {
+ if ((current_shape[i] - mb->get_position()).length_squared() <= grab_threshold) {
dragging_point = i;
workspace->update();
return;
@@ -1254,20 +1315,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
if (edited_shape_coord != coord) {
edited_shape_coord = coord;
- edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord);
- edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord);
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
- bool found_collision_shape = false;
- for (int i = 0; i < sd.size(); i++) {
- if (sd[i].autotile_coord == coord) {
- edited_collision_shape = sd[i].shape;
- found_collision_shape = true;
- break;
- }
- }
- if (!found_collision_shape)
- edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
}
}
workspace->update();
@@ -1286,9 +1334,12 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
points.push_back(p - shape_anchor);
}
- edited_collision_shape->set_points(points);
-
- workspace->update();
+ undo_redo->create_action(TTR("Edit Collision Polygon"));
+ undo_redo->add_do_method(edited_collision_shape.ptr(), "set_points", points);
+ undo_redo->add_undo_method(edited_collision_shape.ptr(), "set_points", edited_collision_shape->get_points());
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} else if (edit_mode == EDITMODE_OCCLUSION) {
if (dragging_point >= 0) {
@@ -1303,9 +1354,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
w = PoolVector<Vector2>::Write();
- edited_occlusion_shape->set_polygon(polygon);
- workspace->update();
+ undo_redo->create_action(TTR("Edit Occlusion Polygon"));
+ undo_redo->add_do_method(edited_occlusion_shape.ptr(), "set_polygon", polygon);
+ undo_redo->add_undo_method(edited_occlusion_shape.ptr(), "set_polygon", edited_occlusion_shape->get_polygon());
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} else if (edit_mode == EDITMODE_NAVIGATION) {
if (dragging_point >= 0) {
@@ -1322,10 +1377,15 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
w = PoolVector<Vector2>::Write();
- edited_navigation_shape->set_vertices(polygon);
- edited_navigation_shape->add_polygon(indices);
- workspace->update();
+ undo_redo->create_action(TTR("Edit Navigation Polygon"));
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon);
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "set_vertices", edited_navigation_shape->get_vertices());
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "add_polygon", indices);
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "add_polygon", edited_navigation_shape->get_polygon(0));
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
}
}
@@ -1336,14 +1396,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
} else if (tools[SHAPE_NEW_POLYGON]->is_pressed()) {
-
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
Vector2 pos = mb->get_position();
pos = snap_point(pos);
if (creating_shape) {
if (current_shape.size() > 0) {
- if ((pos - current_shape[0]).length_squared() <= MIN_DISTANCE_SQUARED) {
+ if ((pos - current_shape[0]).length_squared() <= grab_threshold) {
if (current_shape.size() > 2) {
close_shape(shape_anchor);
workspace->update();
@@ -1354,60 +1413,16 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
current_shape.push_back(pos);
workspace->update();
} else {
- int t_id = get_current_tile();
- if (t_id >= 0) {
- if (edit_mode == EDITMODE_COLLISION) {
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(t_id);
- for (int i = 0; i < sd.size(); i++) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || sd[i].autotile_coord == edited_shape_coord) {
- Ref<ConvexPolygonShape2D> shape = sd[i].shape;
-
- if (!shape.is_null()) {
- sd.remove(i);
- tileset->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- workspace->update();
- }
- break;
- }
- }
- } else if (edit_mode == EDITMODE_OCCLUSION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Map<Vector2, Ref<OccluderPolygon2D> > map = tileset->autotile_get_light_oclusion_map(t_id);
- for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
- break;
- }
- }
- } else
- tileset->tile_set_light_occluder(t_id, Ref<OccluderPolygon2D>());
-
- edited_occlusion_shape = Ref<OccluderPolygon2D>();
- workspace->update();
- } else if (edit_mode == EDITMODE_NAVIGATION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id);
- for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_navigation_polygon(t_id, Ref<NavigationPolygon>(), edited_shape_coord);
- break;
- }
- }
- } else
- tileset->tile_set_navigation_polygon(t_id, Ref<NavigationPolygon>());
- edited_navigation_shape = Ref<NavigationPolygon>();
- workspace->update();
- }
- }
-
creating_shape = true;
current_shape.resize(0);
current_shape.push_back(snap_point(pos));
+ workspace->update();
}
- } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT && current_shape.size() > 2) {
+ } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
if (creating_shape) {
- close_shape(shape_anchor);
+ creating_shape = false;
+ _select_edited_shape_coord();
+ workspace->update();
}
}
} else if (mm.is_valid()) {
@@ -1427,14 +1442,27 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
if (p_tool == BITMASK_COPY) {
bitmask_map_copy = tileset->autotile_get_bitmask_map(get_current_tile());
} else if (p_tool == BITMASK_PASTE) {
- tileset->autotile_clear_bitmask_map(get_current_tile());
+ undo_redo->create_action(TTR("Paste Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
for (Map<Vector2, uint16_t>::Element *E = bitmask_map_copy.front(); E; E = E->next()) {
- tileset->autotile_set_bitmask(get_current_tile(), E->key(), E->value());
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
}
- workspace->update();
+ for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
+ }
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
} else if (p_tool == BITMASK_CLEAR) {
- tileset->autotile_clear_bitmask_map(get_current_tile());
- workspace->update();
+ undo_redo->create_action(TTR("Clear Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
+ for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
+ }
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
} else if (p_tool == SHAPE_DELETE) {
if (creating_shape) {
creating_shape = false;
@@ -1443,11 +1471,17 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
} else {
switch (edit_mode) {
case EDITMODE_REGION: {
- if (workspace_mode == WORKSPACE_EDIT && get_current_tile() >= 0) {
- tileset->remove_tile(get_current_tile());
- set_current_tile(-1);
- workspace->update();
- workspace_overlay->update();
+ int t_id = get_current_tile();
+ if (workspace_mode == WORKSPACE_EDIT && t_id >= 0) {
+ undo_redo->create_action(TTR("Remove Tile"));
+ undo_redo->add_do_method(tileset.ptr(), "remove_tile", t_id);
+ _undo_tile_removal(t_id);
+ undo_redo->add_do_method(this, "_validate_current_tile_id");
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
}
tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
workspace_mode = WORKSPACE_EDIT;
@@ -1455,37 +1489,50 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
} break;
case EDITMODE_COLLISION: {
if (!edited_collision_shape.is_null()) {
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
- int index = -1;
+ // Necessary to get the version that returns a Array instead of a Vector.
+ Array sd = tileset->call("tile_get_shapes", get_current_tile());
for (int i = 0; i < sd.size(); i++) {
- if (sd[i].shape == edited_collision_shape) {
- index = i;
+ if (sd[i].get("shape") == edited_collision_shape) {
+ undo_redo->create_action(TTR("Remove Collision Polygon"));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate());
+ sd.remove(i);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
break;
}
}
- if (index >= 0) {
- sd.remove(index);
- tileset->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- current_shape.resize(0);
- workspace->update();
+ }
+ } break;
+ case EDITMODE_OCCLUSION: {
+ if (!edited_occlusion_shape.is_null()) {
+ undo_redo->create_action(TTR("Remove Occlusion Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), Ref<OccluderPolygon2D>());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), tileset->tile_get_light_occluder(get_current_tile()));
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord), edited_shape_coord);
}
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} break;
case EDITMODE_NAVIGATION: {
if (!edited_navigation_shape.is_null()) {
- tileset->autotile_set_navigation_polygon(get_current_tile(), Ref<NavigationPolygon>(), edited_shape_coord);
- edited_navigation_shape = Ref<NavigationPolygon>();
- current_shape.resize(0);
- workspace->update();
- }
- } break;
- case EDITMODE_OCCLUSION: {
- if (!edited_occlusion_shape.is_null()) {
- tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
- edited_occlusion_shape = Ref<OccluderPolygon2D>();
- current_shape.resize(0);
- workspace->update();
+ undo_redo->create_action(TTR("Remove Navigation Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), Ref<NavigationPolygon>());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), tileset->tile_get_navigation_polygon(get_current_tile()));
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), Ref<NavigationPolygon>(), edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ }
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} break;
default: {}
@@ -1502,13 +1549,27 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
}
void TileSetEditor::_on_priority_changed(float val) {
- tileset->autotile_set_subtile_priority(get_current_tile(), edited_shape_coord, (int)val);
- workspace->update();
+ if ((int)val == tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord))
+ return;
+
+ undo_redo->create_action(TTR("Edit Tile Priority"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_subtile_priority", get_current_tile(), edited_shape_coord, (int)val);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_subtile_priority", get_current_tile(), edited_shape_coord, tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
void TileSetEditor::_on_z_index_changed(float val) {
- tileset->autotile_set_z_index(get_current_tile(), edited_shape_coord, (int)val);
- workspace->update();
+ if ((int)val == tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord))
+ return;
+
+ undo_redo->create_action(TTR("Edit Tile Z Index"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_z_index", get_current_tile(), edited_shape_coord, (int)val);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_z_index", get_current_tile(), edited_shape_coord, tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
void TileSetEditor::_on_grid_snap_toggled(bool p_val) {
@@ -1534,6 +1595,63 @@ void TileSetEditor::_set_snap_sep(Vector2 p_val) {
workspace->update();
}
+void TileSetEditor::_validate_current_tile_id() {
+ if (get_current_tile() >= 0 && !tileset->has_tile(get_current_tile()))
+ set_current_tile(-1);
+}
+
+void TileSetEditor::_select_edited_shape_coord() {
+ select_coord(edited_shape_coord);
+}
+
+void TileSetEditor::_undo_tile_removal(int p_id) {
+ undo_redo->add_undo_method(tileset.ptr(), "create_tile", p_id);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_name", p_id, tileset->tile_get_name(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_normal_map", p_id, tileset->tile_get_normal_map(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_texture_offset", p_id, tileset->tile_get_texture_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_material", p_id, tileset->tile_get_material(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_modulate", p_id, tileset->tile_get_modulate(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_occluder_offset", p_id, tileset->tile_get_occluder_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon_offset", p_id, tileset->tile_get_navigation_polygon_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shape_offset", p_id, 0, tileset->tile_get_shape_offset(p_id, 0));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shape_transform", p_id, 0, tileset->tile_get_shape_transform(p_id, 0));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_z_index", p_id, tileset->tile_get_z_index(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_texture", p_id, tileset->tile_get_texture(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_region", p_id, tileset->tile_get_region(p_id));
+ // Necessary to get the version that returns a Array instead of a Vector.
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", p_id, tileset->call("tile_get_shapes", p_id));
+ if (tileset->tile_get_tile_mode(p_id) == TileSet::SINGLE_TILE) {
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", p_id, tileset->tile_get_light_occluder(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", p_id, tileset->tile_get_navigation_polygon(p_id));
+ } else {
+ Map<Vector2, Ref<OccluderPolygon2D> > oclusion_map = tileset->autotile_get_light_oclusion_map(p_id);
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = oclusion_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", p_id, E->value(), E->key());
+ }
+ Map<Vector2, Ref<NavigationPolygon> > navigation_map = tileset->autotile_get_navigation_map(p_id);
+ for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = navigation_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", p_id, E->value(), E->key());
+ }
+ Map<Vector2, uint16_t> bitmask_map = tileset->autotile_get_bitmask_map(p_id);
+ for (Map<Vector2, uint16_t>::Element *E = bitmask_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", p_id, E->key(), E->value());
+ }
+ Map<Vector2, int> priority_map = tileset->autotile_get_priority_map(p_id);
+ for (Map<Vector2, int>::Element *E = priority_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_subtile_priority", p_id, E->key(), E->value());
+ }
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_icon_coordinate", p_id, tileset->autotile_get_icon_coordinate(p_id));
+ Map<Vector2, int> z_map = tileset->autotile_get_z_index_map(p_id);
+ for (Map<Vector2, int>::Element *E = z_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_z_index", p_id, E->key(), E->value());
+ }
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_tile_mode", p_id, tileset->tile_get_tile_mode(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_size", p_id, tileset->autotile_get_size(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_spacing", p_id, tileset->autotile_get_spacing(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask_mode", p_id, tileset->autotile_get_bitmask_mode(p_id));
+ }
+}
+
void TileSetEditor::_zoom_in() {
float scale = workspace->get_scale().x;
if (scale < max_scale) {
@@ -1544,7 +1662,6 @@ void TileSetEditor::_zoom_in() {
}
}
void TileSetEditor::_zoom_out() {
-
float scale = workspace->get_scale().x;
if (scale > min_scale) {
scale /= scale_ratio;
@@ -1769,7 +1886,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_collision_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_collision_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1785,10 +1902,12 @@ void TileSetEditor::draw_polygon_shapes() {
}
if (coord == edited_shape_coord || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
- for (int j = 0; j < polygon.size() - 1; j++) {
- workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
if (shape == edited_collision_shape) {
draw_handles = true;
}
@@ -1807,7 +1926,7 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Color> colors;
Vector2 anchor = WORKSPACE_MARGIN;
anchor += tileset->tile_get_region(get_current_tile()).position;
- if (shape == edited_occlusion_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_occlusion_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1820,10 +1939,12 @@ void TileSetEditor::draw_polygon_shapes() {
}
workspace->draw_polygon(polygon, colors);
- for (int j = 0; j < polygon.size() - 1; j++) {
- workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
if (shape == edited_occlusion_shape) {
draw_handles = true;
}
@@ -1852,7 +1973,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_occlusion_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_occlusion_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1866,10 +1987,12 @@ void TileSetEditor::draw_polygon_shapes() {
workspace->draw_polygon(polygon, colors);
if (coord == edited_shape_coord) {
- for (int j = 0; j < polygon.size() - 1; j++) {
- workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
if (shape == edited_occlusion_shape) {
draw_handles = true;
}
@@ -1890,7 +2013,7 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Color> colors;
Vector2 anchor = WORKSPACE_MARGIN;
anchor += tileset->tile_get_region(get_current_tile()).position;
- if (shape == edited_navigation_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_navigation_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1904,10 +2027,12 @@ void TileSetEditor::draw_polygon_shapes() {
}
workspace->draw_polygon(polygon, colors);
- for (int j = 0; j < polygon.size() - 1; j++) {
- workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
if (shape == edited_navigation_shape) {
draw_handles = true;
}
@@ -1936,7 +2061,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_navigation_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_navigation_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1951,10 +2076,12 @@ void TileSetEditor::draw_polygon_shapes() {
workspace->draw_polygon(polygon, colors);
if (coord == edited_shape_coord) {
- for (int j = 0; j < polygon.size() - 1; j++) {
- workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
if (shape == edited_navigation_shape) {
draw_handles = true;
}
@@ -1971,6 +2098,7 @@ void TileSetEditor::draw_polygon_shapes() {
workspace->draw_line(current_shape[j], current_shape[j + 1], Color(0, 1, 1), 1, true);
}
workspace->draw_line(current_shape[current_shape.size() - 1], snap_point(workspace->get_local_mouse_position()), Color(0, 1, 1), 1, true);
+ draw_handles = true;
}
}
@@ -1999,16 +2127,29 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_points(segments);
+ undo_redo->create_action(TTR("Create Collision Polygon"));
+ // Necessary to get the version that returns a Array instead of a Vector.
+ Array sd = tileset->call("tile_get_shapes", get_current_tile());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate());
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].get("shape") == edited_collision_shape) {
+ sd.remove(i);
+ break;
+ }
+ }
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->tile_add_shape(get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
+ undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
else
- tileset->tile_add_shape(get_current_tile(), shape, Transform2D());
-
- edited_collision_shape = shape;
+ undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D());
+ tools[TOOL_SELECT]->set_pressed(true);
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
+ } else {
+ tools[TOOL_SELECT]->set_pressed(true);
+ workspace->update();
}
-
- tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
} else if (edit_mode == EDITMODE_OCCLUSION) {
Ref<OccluderPolygon2D> shape = memnew(OccluderPolygon2D);
@@ -2023,13 +2164,18 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
w = PoolVector<Vector2>::Write();
shape->set_polygon(polygon);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->autotile_set_light_occluder(get_current_tile(), shape, edited_shape_coord);
- else
- tileset->tile_set_light_occluder(get_current_tile(), shape);
- edited_occlusion_shape = shape;
+ undo_redo->create_action(TTR("Create Occlusion Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), shape, edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), shape);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), tileset->tile_get_light_occluder(get_current_tile()));
+ }
tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
} else if (edit_mode == EDITMODE_NAVIGATION) {
Ref<NavigationPolygon> shape = memnew(NavigationPolygon);
@@ -2047,13 +2193,18 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_vertices(polygon);
shape->add_polygon(indices);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->autotile_set_navigation_polygon(get_current_tile(), shape, edited_shape_coord);
- else
- tileset->tile_set_navigation_polygon(get_current_tile(), shape);
- edited_navigation_shape = shape;
+ undo_redo->create_action(TTR("Create Navigation Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), shape, edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), shape);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), tileset->tile_get_navigation_polygon(get_current_tile()));
+ }
tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
tileset->_change_notify("");
}
@@ -2098,6 +2249,23 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
}
}
} else {
+ Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
+ bool found_collision_shape = false;
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].autotile_coord == coord) {
+ if (edited_collision_shape != sd[i].shape)
+ edited_collision_shape = sd[i].shape;
+ found_collision_shape = true;
+ break;
+ }
+ }
+ if (!found_collision_shape)
+ edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
+ if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord))
+ edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord);
+ if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord))
+ edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), coord);
+
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
Vector2 shape_anchor = coord;
@@ -2168,6 +2336,24 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
return p;
}
+void TileSetEditor::add_texture(Ref<Texture> p_texture) {
+ texture_list->add_item(p_texture->get_path().get_file());
+ texture_map.insert(p_texture->get_rid(), p_texture);
+ texture_list->set_item_metadata(texture_list->get_item_count() - 1, p_texture->get_rid());
+}
+
+void TileSetEditor::remove_texture(Ref<Texture> p_texture) {
+ texture_list->remove_item(texture_list->find_metadata(p_texture->get_rid()));
+ texture_map.erase(p_texture->get_rid());
+
+ _validate_current_tile_id();
+
+ if (!get_current_texture().is_valid()) {
+ _on_texture_list_selected(-1);
+ workspace_overlay->update();
+ }
+}
+
void TileSetEditor::update_texture_list() {
Ref<Texture> selected_texture = get_current_texture();
@@ -2184,9 +2370,7 @@ void TileSetEditor::update_texture_list() {
}
if (!texture_map.has(tileset->tile_get_texture(E->get())->get_rid())) {
- texture_list->add_item(tileset->tile_get_texture(E->get())->get_path().get_file());
- texture_map.insert(tileset->tile_get_texture(E->get())->get_rid(), tileset->tile_get_texture(E->get()));
- texture_list->set_item_metadata(texture_list->get_item_count() - 1, tileset->tile_get_texture(E->get())->get_rid());
+ add_texture(tileset->tile_get_texture(E->get()));
}
}
for (int i = 0; i < ids_to_remove.size(); i++) {
@@ -2200,7 +2384,9 @@ void TileSetEditor::update_texture_list() {
} else if (get_current_texture().is_valid()) {
_on_texture_list_selected(texture_list->find_metadata(get_current_texture()->get_rid()));
} else {
+ _validate_current_tile_id();
_on_texture_list_selected(-1);
+ workspace_overlay->update();
}
update_texture_list_icon();
helper->_change_notify("");
@@ -2276,7 +2462,7 @@ void TileSetEditor::update_workspace_tile_mode() {
if (edit_mode == EDITMODE_ICON)
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
else
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
} else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
if (tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
@@ -2285,7 +2471,7 @@ void TileSetEditor::update_workspace_tile_mode() {
if (edit_mode == EDITMODE_ICON)
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
else
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
tool_editmode[EDITMODE_BITMASK]->hide();
tool_editmode[EDITMODE_PRIORITY]->hide();
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index f2e7e977cb..e4e01750bd 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -94,6 +94,7 @@ class TileSetEditor : public HSplitContainer {
Ref<TileSet> tileset;
TilesetEditorContext *helper;
EditorNode *editor;
+ UndoRedo *undo_redo;
ConfirmationDialog *cd;
AcceptDialog *err_dialog;
@@ -151,10 +152,14 @@ class TileSetEditor : public HSplitContainer {
void update_texture_list();
void update_texture_list_icon();
+ void add_texture(Ref<Texture> p_texture);
+ void remove_texture(Ref<Texture> p_texture);
+
Ref<Texture> get_current_texture();
static void _import_node(Node *p_node, Ref<TileSet> p_library);
static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge);
+ void _undo_redo_import_scene(Node *p_scene, bool p_merge);
protected:
static void _bind_methods();
@@ -186,6 +191,10 @@ private:
void _set_snap_off(Vector2 p_val);
void _set_snap_sep(Vector2 p_val);
+ void _validate_current_tile_id();
+ void _select_edited_shape_coord();
+ void _undo_tile_removal(int p_id);
+
void _zoom_in();
void _zoom_out();
void _zoom_reset();
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 8a24d4bab1..089100bf40 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -507,6 +507,13 @@ int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
return 1;
}
+const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
+
+ static Map<Vector2, int> dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.priority_map;
+}
+
void TileSet::autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -524,11 +531,11 @@ int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
return 0;
}
-const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
+const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const {
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
- return tile_map[p_id].autotile_data.priority_map;
+ return tile_map[p_id].autotile_data.z_index_map;
}
void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) {
@@ -986,8 +993,23 @@ void TileSet::clear() {
void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile);
+ ClassDB::bind_method(D_METHOD("autotile_clear_bitmask_map", "id"), &TileSet::autotile_clear_bitmask_map);
+ ClassDB::bind_method(D_METHOD("autotile_set_icon_coordinate", "id", "coord"), &TileSet::autotile_set_icon_coordinate);
+ ClassDB::bind_method(D_METHOD("autotile_get_icon_coordinate", "id"), &TileSet::autotile_get_icon_coordinate);
+ ClassDB::bind_method(D_METHOD("autotile_set_subtile_priority", "id", "coord", "priority"), &TileSet::autotile_set_subtile_priority);
+ ClassDB::bind_method(D_METHOD("autotile_get_subtile_priority", "id", "coord"), &TileSet::autotile_get_subtile_priority);
+ ClassDB::bind_method(D_METHOD("autotile_set_z_index", "id", "coord", "z_index"), &TileSet::autotile_set_z_index);
+ ClassDB::bind_method(D_METHOD("autotile_get_z_index", "id", "coord"), &TileSet::autotile_get_z_index);
+ ClassDB::bind_method(D_METHOD("autotile_set_light_occluder", "id", "light_occluder", "coord"), &TileSet::autotile_set_light_occluder);
+ ClassDB::bind_method(D_METHOD("autotile_get_light_occluder", "id", "coord"), &TileSet::autotile_get_light_occluder);
+ ClassDB::bind_method(D_METHOD("autotile_set_navigation_polygon", "id", "navigation_polygon", "coord"), &TileSet::autotile_set_navigation_polygon);
+ ClassDB::bind_method(D_METHOD("autotile_get_navigation_polygon", "id", "coord"), &TileSet::autotile_get_navigation_polygon);
+ ClassDB::bind_method(D_METHOD("autotile_set_bitmask", "id", "bitmask", "flag"), &TileSet::autotile_set_bitmask);
+ ClassDB::bind_method(D_METHOD("autotile_get_bitmask", "id", "coord"), &TileSet::autotile_get_bitmask);
ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "id", "mode"), &TileSet::autotile_set_bitmask_mode);
ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode", "id"), &TileSet::autotile_get_bitmask_mode);
+ ClassDB::bind_method(D_METHOD("autotile_set_spacing", "id", "spacing"), &TileSet::autotile_set_spacing);
+ ClassDB::bind_method(D_METHOD("autotile_get_spacing", "id"), &TileSet::autotile_get_spacing);
ClassDB::bind_method(D_METHOD("autotile_set_size", "id", "size"), &TileSet::autotile_set_size);
ClassDB::bind_method(D_METHOD("autotile_get_size", "id"), &TileSet::autotile_get_size);
ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 2ab771b1b0..3992c675fd 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -175,6 +175,7 @@ public:
void autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index);
int autotile_get_z_index(int p_id, const Vector2 &p_coord);
+ const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const;
void autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag);
uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord);
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 1acec7ccaf..628ffb71f3 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -525,7 +525,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
bool exponent_found = false;
bool hexa_found = false;
bool sign_found = false;
- bool minus_exponent_found = false;
bool float_suffix_found = false;
String str;
@@ -557,8 +556,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (sign_found)
return _make_token(TK_ERROR, "Invalid numeric constant");
sign_found = true;
- if (GETCHAR(i) == '-')
- minus_exponent_found = true;
} else
break;
@@ -571,7 +568,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (hexa_found) {
//hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported");
- } else if (period_found || float_suffix_found) {
+ } else if (period_found || exponent_found || float_suffix_found) {
//floats
if (period_found) {
if (float_suffix_found) {
@@ -614,7 +611,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
char_idx += str.length();
Token tk;
- if (period_found || minus_exponent_found || float_suffix_found)
+ if (period_found || exponent_found || float_suffix_found)
tk.type = TK_REAL_CONSTANT;
else
tk.type = TK_INT_CONSTANT;