@tool extends Control func _process(_delta): update_layer_number() update_minify_button() func _on_new_pressed(): var dialog = EditorFileDialog.new() dialog.file_mode = EditorFileDialog.FILE_MODE_SAVE_FILE dialog.filters = ["*.tscn ; Godot Human Readable Text Scene"] EditorInterface.popup_dialog_centered_ratio(dialog) var file = await dialog.file_selected EditorInterface.open_scene_from_path("res://addons/editor_helper/template.tscn") get_scene().name = file.get_file().get_basename().to_camel_case() EditorInterface.save_scene_as(file) func _on_new_layer_pressed(): var scene = get_scene() if !is_scene_expanded(scene): return await error_not_expanded() var maps = scene.get_node("TileMap") var layer = TileMapLayer.new() layer.tile_set = load("res://Assets/tileset.tres") layer.set("metadata/_edit_lock_", true) maps.add_child(layer) layer.owner = scene var index = layer.get_index() layer.name = "TileMap Layer %s" % str(index + 1) save_and_reload() #focus_node(scene.get_node("TileMap").get_child(index)) func _on_minify_pressed(): var scene = get_scene() if !is_scene_expanded(scene): return await error_not_expanded() focus_node(scene) scene.remove_child(scene.get_node("ProjectionViewport")) scene.get_node("HeightMap").mesh_library = load("res://Assets/heightmap_meshlibrary.tres") scene.remove_child(scene.get_node("NotMinified")) EditorInterface.mark_scene_as_unsaved() func _on_expand_pressed(): var scene = get_scene() if !is_scene_minified(scene): return await error_not_minified() var not_minified = Node.new() not_minified.name = "NotMinified" scene.add_child(not_minified) scene.move_child(not_minified, 0) not_minified.owner = scene var sv = SubViewport.new() sv.name = "ProjectionViewport" sv.disable_3d = true scene.add_child(sv) sv.owner = scene update_proj_map() EditorInterface.mark_scene_as_unsaved() func _on_up_pressed(): move_up_or_down(1) func _on_down_pressed(): move_up_or_down(-1) func _on_edit_2d_pressed(): var scene = get_scene() if !is_scene_expanded(scene): return await error_not_expanded() focus_node(scene.get_node("TileMap").get_child(0)) func _on_edit_3d_pressed(): var scene = get_scene() if !is_scene_expanded(scene): return await error_not_expanded() update_proj_map() focus_node(scene.get_node("HeightMap")) func _on_update_pressed(): update_proj_map() func _on_create_baseplate_pressed(): var scene = get_scene() if !is_scene_expanded(scene): return await error_not_expanded() var heightmap: GridMap = scene.get_node("HeightMap") var maps = scene.get_node("TileMap") var item_list = heightmap.mesh_library.get_item_list() var cube = item_list[0] print(cube) for map: TileMapLayer in maps.get_children(): if map is not TileMapLayer: continue for cell in map.get_used_cells(): heightmap.set_cell_item(Vector3i(cell.x, -1, cell.y), cube) func update_minify_button(): var expanded = is_scene_expanded(get_scene()) $VBoxContainer/Minify.visible = expanded $VBoxContainer/Expand.visible = !expanded func move_up_or_down(direction: int): var selection = EditorInterface.get_selection().get_selected_nodes() if len(selection) != 1: return await error_not_editing_tilemap() selection = selection[0] if selection is GridMap: var floor: Vector3 = selection.get(&"metadata/_editor_floor_") floor.y += direction selection.set(&"metadata/_editor_floor_", floor) save_and_reload() update_proj_map() elif selection is TileMapLayer: var index = selection.get_index() + direction if index == -1: return var target = selection.get_parent().get_child(index) if target != null: focus_node(target) func save_and_reload(): EditorInterface.save_scene() EditorInterface.reload_scene_from_path(get_scene().scene_file_path) func update_layer_number(): var s = "N/A ¯\\_(ツ)_/¯" var selection = EditorInterface.get_selection().get_selected_nodes() if len(selection) == 1: selection = selection[0] if selection is GridMap: var v = selection.get(&"metadata/_editor_floor_").y if v == -1: s = "-1 (Baseplate)" else: s = str(v) if selection is TileMapLayer: s = str(selection.get_index()) $"VBoxContainer/Current Layer".text = "Current layer: %s" % s func focus_node(node: Node): var selection = EditorInterface.get_selection() selection.clear() selection.add_node(node) func get_scene() -> Node: return EditorInterface.get_edited_scene_root() func is_scene_expanded(scene: Node) -> bool: if !scene: return false return scene.has_node("NotMinified") func is_scene_minified(scene: Node) -> bool: if !scene: return false return scene.has_node("TileMap") && scene.has_node("HeightMap") && !scene.has_node("NotMinified") func error(message: String): var dialog = AcceptDialog.new() dialog.dialog_text = message EditorInterface.popup_dialog_centered(dialog) await dialog.close_requested dialog.queue_free() func error_not_expanded(): error("This scene is not an expanded map!") func error_not_minified(): error("This scene is not a minified map!") func error_not_editing_tilemap(): error("Please start editing a map before using this button!") func heightmap_set_proj_map(height_map: GridMap, proj_vp: SubViewport, rect: Rect2i): var ml = load("res://Assets/heightmap_meshlibrary.tres").duplicate() var cube: BoxMesh = ml.get(&"item/0/mesh").duplicate() var sm = ShaderMaterial.new() sm.shader = load("res://Assets/Editor/Project.gdshader") sm.set(&"shader_parameter/tilemap_camera", proj_vp.get_texture()) sm.set(&"shader_parameter/offset", -rect.position as Vector2) sm.set(&"shader_parameter/scale", rect.size as Vector2) cube.material = sm ml.set(&"item/0/mesh", cube) height_map.mesh_library = ml func update_proj_map(): var scene = get_scene() if !is_scene_expanded(scene): return error_not_expanded() var maps = scene.get_node("TileMap").duplicate(0) var proj_vp = scene.get_node("ProjectionViewport") if proj_vp.has_node("TileMap"): proj_vp.get_node("TileMap").free() proj_vp.add_child(maps) var total_rect = Rect2i() for map: TileMapLayer in maps.get_children(): if map is not TileMapLayer: continue total_rect = total_rect.merge(map.get_used_rect()) maps.position = total_rect.position * -128 proj_vp.size = total_rect.size.max(Vector2i.ONE) * 128 heightmap_set_proj_map(scene.get_node("HeightMap"), proj_vp, total_rect)