Ver código fonte

Merge pull request #19914 from guilhermefelipecgs/add_z_index_autotile

Add Z-Index for Autotile
Rémi Verschelde 6 anos atrás
pai
commit
49ac23e29f

+ 36 - 4
editor/plugins/tile_set_editor_plugin.cpp

@@ -185,6 +185,7 @@ void TileSetEditor::_bind_methods() {
 	ClassDB::bind_method("_on_workspace_input", &TileSetEditor::_on_workspace_input);
 	ClassDB::bind_method("_on_tool_clicked", &TileSetEditor::_on_tool_clicked);
 	ClassDB::bind_method("_on_priority_changed", &TileSetEditor::_on_priority_changed);
+	ClassDB::bind_method("_on_z_index_changed", &TileSetEditor::_on_z_index_changed);
 	ClassDB::bind_method("_on_grid_snap_toggled", &TileSetEditor::_on_grid_snap_toggled);
 	ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step);
 	ClassDB::bind_method("_set_snap_off", &TileSetEditor::_set_snap_off);
@@ -233,6 +234,7 @@ void TileSetEditor::_notification(int p_what) {
 			tool_editmode[EDITMODE_BITMASK]->set_icon(get_icon("PackedDataContainer", "EditorIcons"));
 			tool_editmode[EDITMODE_PRIORITY]->set_icon(get_icon("MaterialPreviewLight1", "EditorIcons"));
 			tool_editmode[EDITMODE_ICON]->set_icon(get_icon("LargeTexture", "EditorIcons"));
+			tool_editmode[EDITMODE_Z_INDEX]->set_icon(get_icon("Sort", "EditorIcons"));
 
 			scroll->add_style_override("bg", get_stylebox("bg", "Tree"));
 		} break;
@@ -320,7 +322,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
 	tool_hb = memnew(HBoxContainer);
 
 	g = Ref<ButtonGroup>(memnew(ButtonGroup));
-	String label[EDITMODE_MAX] = { "Region", "Collision", "Occlusion", "Navigation", "Bitmask", "Priority", "Icon" };
+	String label[EDITMODE_MAX] = { "Region", "Collision", "Occlusion", "Navigation", "Bitmask", "Priority", "Icon", "Z Index" };
 	for (int i = 0; i < (int)EDITMODE_MAX; i++) {
 		tool_editmode[i] = memnew(Button);
 		tool_editmode[i]->set_text(label[i]);
@@ -395,6 +397,15 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
 	spin_priority->hide();
 	toolbar->add_child(spin_priority);
 
+	spin_z_index = memnew(SpinBox);
+	spin_z_index->set_min(VS::CANVAS_ITEM_Z_MIN);
+	spin_z_index->set_max(VS::CANVAS_ITEM_Z_MAX);
+	spin_z_index->set_step(1);
+	spin_z_index->set_custom_minimum_size(Size2(100, 0));
+	spin_z_index->connect("value_changed", this, "_on_z_index_changed");
+	spin_z_index->hide();
+	toolbar->add_child(spin_z_index);
+
 	Control *separator = memnew(Control);
 	separator->set_h_size_flags(SIZE_EXPAND_FILL);
 	toolbar->add_child(separator);
@@ -617,6 +628,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
 			tools[TOOL_SELECT]->set_tooltip(TTR("Drag handles to edit Rect.\nClick on another Tile to edit it."));
 			tools[SHAPE_DELETE]->set_tooltip(TTR("Delete selected Rect."));
 			spin_priority->hide();
+			spin_z_index->hide();
 		} break;
 		case EDITMODE_COLLISION:
 		case EDITMODE_NAVIGATION:
@@ -639,6 +651,8 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
 			tools[TOOL_SELECT]->set_tooltip(TTR("Select current edited sub-tile.\nClick on another Tile to edit it."));
 			tools[SHAPE_DELETE]->set_tooltip(TTR("Delete polygon."));
 			spin_priority->hide();
+			spin_z_index->hide();
+
 			select_coord(edited_shape_coord);
 		} break;
 		case EDITMODE_BITMASK: {
@@ -661,6 +675,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
 			tools[TOOL_SELECT]->set_tooltip(TTR("LMB: Set bit on.\nRMB: Set bit off.\nClick on another Tile to edit it."));
 			spin_priority->hide();
 		} break;
+		case EDITMODE_Z_INDEX:
 		case EDITMODE_PRIORITY:
 		case EDITMODE_ICON: {
 			tools[TOOL_SELECT]->show();
@@ -681,9 +696,15 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
 			if (edit_mode == EDITMODE_ICON) {
 				tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to use as icon, this will be also used on invalid autotile bindings.\nClick on another Tile to edit it."));
 				spin_priority->hide();
-			} else {
+				spin_z_index->hide();
+			} else if (edit_mode == EDITMODE_PRIORITY) {
 				tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its priority.\nClick on another Tile to edit it."));
 				spin_priority->show();
+				spin_z_index->hide();
+			} else {
+				tools[TOOL_SELECT]->set_tooltip(TTR("Select sub-tile to change its z index.\nClick on another Tile to edit it."));
+				spin_priority->hide();
+				spin_z_index->show();
 			}
 		} break;
 		default: {}
@@ -811,6 +832,10 @@ void TileSetEditor::_on_workspace_draw() {
 				spin_priority->set_suffix(" / " + String::num(total, 0));
 				draw_highlight_subtile(edited_shape_coord, queue_others);
 			} break;
+			case EDITMODE_Z_INDEX: {
+				spin_z_index->set_value(tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord));
+				draw_highlight_subtile(edited_shape_coord);
+			} break;
 			default: {}
 		}
 	}
@@ -1205,7 +1230,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
 				case EDITMODE_COLLISION:
 				case EDITMODE_OCCLUSION:
 				case EDITMODE_NAVIGATION:
-				case EDITMODE_PRIORITY: {
+				case EDITMODE_PRIORITY:
+				case EDITMODE_Z_INDEX: {
 					Vector2 shape_anchor = Vector2(0, 0);
 					if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
 						shape_anchor = edited_shape_coord;
@@ -1481,6 +1507,11 @@ void TileSetEditor::_on_priority_changed(float val) {
 	workspace->update();
 }
 
+void TileSetEditor::_on_z_index_changed(float val) {
+	tileset->autotile_set_z_index(get_current_tile(), edited_shape_coord, (int)val);
+	workspace->update();
+}
+
 void TileSetEditor::_on_grid_snap_toggled(bool p_val) {
 	helper->set_snap_options_visible(p_val);
 	workspace->update();
@@ -2219,7 +2250,7 @@ void TileSetEditor::update_workspace_tile_mode() {
 	separator_editmode->show();
 
 	if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
-		if (tool_editmode[EDITMODE_ICON]->is_pressed() || tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
+		if (tool_editmode[EDITMODE_ICON]->is_pressed() || tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed() || tool_editmode[EDITMODE_Z_INDEX]->is_pressed()) {
 			tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
 			edit_mode = EDITMODE_COLLISION;
 		}
@@ -2228,6 +2259,7 @@ void TileSetEditor::update_workspace_tile_mode() {
 		tool_editmode[EDITMODE_ICON]->hide();
 		tool_editmode[EDITMODE_BITMASK]->hide();
 		tool_editmode[EDITMODE_PRIORITY]->hide();
+		tool_editmode[EDITMODE_Z_INDEX]->hide();
 	} else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
 		if (edit_mode == EDITMODE_ICON)
 			select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));

+ 3 - 0
editor/plugins/tile_set_editor_plugin.h

@@ -71,6 +71,7 @@ class TileSetEditor : public HSplitContainer {
 		EDITMODE_BITMASK,
 		EDITMODE_PRIORITY,
 		EDITMODE_ICON,
+		EDITMODE_Z_INDEX,
 		EDITMODE_MAX
 	};
 
@@ -138,6 +139,7 @@ class TileSetEditor : public HSplitContainer {
 	VSeparator *separator_delete;
 	VSeparator *separator_grid;
 	SpinBox *spin_priority;
+	SpinBox *spin_z_index;
 	WorkspaceMode workspace_mode;
 	EditMode edit_mode;
 	int current_tile;
@@ -178,6 +180,7 @@ private:
 	void _on_workspace_input(const Ref<InputEvent> &p_ie);
 	void _on_tool_clicked(int p_tool);
 	void _on_priority_changed(float val);
+	void _on_z_index_changed(float val);
 	void _on_grid_snap_toggled(bool p_val);
 	void _set_snap_step(Vector2 p_val);
 	void _set_snap_off(Vector2 p_val);

+ 4 - 0
scene/2d/tile_map.cpp

@@ -327,6 +327,10 @@ void TileMap::update_dirty_quadrants() {
 			Ref<ShaderMaterial> mat = tile_set->tile_get_material(c.id);
 			int z_index = tile_set->tile_get_z_index(c.id);
 
+			if (tile_set->tile_get_tile_mode(c.id) == TileSet::AUTO_TILE) {
+				z_index += tile_set->autotile_get_z_index(c.id, Vector2(c.autotile_coord_x, c.autotile_coord_y));
+			}
+
 			RID canvas_item;
 			RID debug_canvas_item;
 

+ 47 - 0
scene/resources/tile_set.cpp

@@ -129,6 +129,22 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) {
 				}
 				p.pop_front();
 			}
+		} else if (what == "z_index_map") {
+			tile_map[id].autotile_data.z_index_map.clear();
+			Array p = p_value;
+			Vector3 val;
+			Vector2 v;
+			int z_index;
+			while (p.size() > 0) {
+				val = p[0];
+				if (val.z > 1) {
+					v.x = val.x;
+					v.y = val.y;
+					z_index = (int)val.z;
+					tile_map[id].autotile_data.z_index_map[v] = z_index;
+				}
+				p.pop_front();
+			}
 		}
 	} else if (what == "shape")
 		tile_set_shape(id, 0, p_value);
@@ -228,6 +244,19 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const {
 				}
 			}
 			r_ret = p;
+		} else if (what == "z_index_map") {
+			Array p;
+			Vector3 v;
+			for (Map<Vector2, int>::Element *E = tile_map[id].autotile_data.z_index_map.front(); E; E = E->next()) {
+				if (E->value() != 0) {
+					//Don't save default value
+					v.x = E->key().x;
+					v.y = E->key().y;
+					v.z = E->value();
+					p.push_back(v);
+				}
+			}
+			r_ret = p;
 		}
 	} else if (what == "shape")
 		r_ret = tile_get_shape(id, 0);
@@ -278,6 +307,7 @@ void TileSet::_get_property_list(List<PropertyInfo> *p_list) const {
 			p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/occluder_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
 			p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/navpoly_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
 			p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/priority_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
+			p_list->push_back(PropertyInfo(Variant::ARRAY, pre + "autotile/z_index_map", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
 		} else if (tile_get_tile_mode(id) == ATLAS_TILE) {
 			p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/icon_coordinate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
 			p_list->push_back(PropertyInfo(Variant::VECTOR2, pre + "autotile/tile_size", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL));
@@ -476,6 +506,23 @@ int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
 	return 1;
 }
 
+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));
+	tile_map[p_id].autotile_data.z_index_map[p_coord] = p_z_index;
+	emit_changed();
+}
+
+int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
+
+	ERR_FAIL_COND_V(!tile_map.has(p_id), 1);
+	if (tile_map[p_id].autotile_data.z_index_map.has(p_coord)) {
+		return tile_map[p_id].autotile_data.z_index_map[p_coord];
+	}
+	//When not custom z index set return the default value
+	return 0;
+}
+
 const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
 
 	static Map<Vector2, int> dummy;

+ 4 - 0
scene/resources/tile_set.h

@@ -87,6 +87,7 @@ public:
 		Map<Vector2, Ref<OccluderPolygon2D> > occluder_map;
 		Map<Vector2, Ref<NavigationPolygon> > navpoly_map;
 		Map<Vector2, int> priority_map;
+		Map<Vector2, int> z_index_map;
 
 		// Default size to prevent invalid value
 		explicit AutotileData() :
@@ -172,6 +173,9 @@ public:
 	int autotile_get_subtile_priority(int p_id, const Vector2 &p_coord);
 	const Map<Vector2, int> &autotile_get_priority_map(int p_id) const;
 
+	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);
+
 	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);
 	const Map<Vector2, uint16_t> &autotile_get_bitmask_map(int p_id);