diff --git a/Scenes/Editor/TileTab.gd b/Scenes/Editor/TileTab.gd new file mode 100644 index 0000000..134c73d --- /dev/null +++ b/Scenes/Editor/TileTab.gd @@ -0,0 +1,16 @@ +extends ScrollContainer + +class_name TileTab + +signal tile_selected(id) + +func add_entry(id: int, group: ButtonGroup, icon: Texture): + var node := Button.new() + node.toggle_mode = true + node.icon = icon + node.group = group + node.connect("pressed", self, "_pressed", [id]) + $list.add_child(node) + +func _pressed(id: int): + emit_signal("tile_selected", id) diff --git a/Scenes/Editor/TileTab.tscn b/Scenes/Editor/TileTab.tscn new file mode 100644 index 0000000..8e8834a --- /dev/null +++ b/Scenes/Editor/TileTab.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=2 format=2] + +[ext_resource path="res://Scenes/Editor/TileTab.gd" type="Script" id=1] + +[node name="TileTab" type="ScrollContainer"] +anchor_right = 1.0 +anchor_bottom = 1.0 +size_flags_horizontal = 3 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="list" type="HBoxContainer" parent="."] +margin_right = 1280.0 +margin_bottom = 800.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 diff --git a/Scenes/MapEditor.gd b/Scenes/MapEditor.gd index 6c6a675..dea318a 100644 --- a/Scenes/MapEditor.gd +++ b/Scenes/MapEditor.gd @@ -1,58 +1,175 @@ extends Control -onready var map_menu = $menu/menubar/MapMenu.get_popup() -onready var map_node = $map +onready var map_menu := ($menu/menubar/MapMenu as MenuButton).get_popup() +onready var map_node := $map +onready var cursor := $map/cursor +onready var cursor_sprite := $map/cursor/preview -const MAP_SCALE_MAX = 8 -const MAP_SCALE_MIN = 0.25 +const MAP_SCALE_MAX := 8.0 +const MAP_SCALE_MIN := 0.25 + +const TileTabScene := preload("res://Scenes/Editor/TileTab.tscn") func _ready(): - pass + add_tile_tab("Base", $map/tiles/base) + add_tile_tab("Floors", $map/tiles/floor) + add_tile_tab("Walls", $map/tiles/walls) + +enum PlacingMode { + NONE, + TILEMAP, + OBJECT +} # Prevent input handler from running when other dialogs/actions are focused -var input_lock = false +var input_lock := false # Drag variables -var dragging = false -var view_origin = Vector2.ZERO -var mouse_origin = Vector2.ZERO +var dragging := false +var view_origin := Vector2.ZERO +var mouse_origin := Vector2.ZERO + +# Placing variables +var placing := false +var deleting := false +var placing_mode = PlacingMode.NONE +var placing_layer = null +var placing_tile_id := 0 + +# Cursor variables +var cursor_pos := Vector2.ZERO + +const TILE_SIZE := 32 func _input(ev: InputEvent): if input_lock: return - + if ev is InputEventMouseMotion: if dragging: - map_node.position = view_origin - (mouse_origin - ev.global_position) + map_node.global_position = view_origin - (mouse_origin - ev.global_position) else: # Map cursor location to grid - var mouse_offset = ev.global_position - map_node.global_position - - + var tile_snap: Vector2 = map_node.scale * TILE_SIZE + var mouse_offset: Vector2 = (ev.global_position - map_node.global_position) / tile_snap + var new_cursor_pos := Vector2(floor(mouse_offset.x), floor(mouse_offset.y)) + if new_cursor_pos != cursor_pos: + cursor_pos = new_cursor_pos + if placing: + place_tile() + elif deleting: + delete_tile() + cursor.position = cursor_pos * TILE_SIZE + if ev is InputEventMouseButton: - var mouse = ev as InputEventMouseButton + var mouse := ev as InputEventMouseButton if mouse.pressed: match ev.button_index: + BUTTON_LEFT: + # Place tile + place_tile() + placing = true + BUTTON_RIGHT: + # Place tile + delete_tile() + deleting = true BUTTON_WHEEL_UP: # Zoom in + var old_scale = map_node.scale if map_node.scale.x < MAP_SCALE_MAX: if map_node.scale.x < 1: map_node.scale *= 2 else: map_node.scale += Vector2.ONE + map_node.position -= (map_node.position + mouse.position * map_node.scale)- (map_node.position + mouse.position * old_scale) BUTTON_WHEEL_DOWN: # Zoom out + var old_scale = map_node.scale if map_node.scale.x > MAP_SCALE_MIN: if map_node.scale.x <= 1: map_node.scale /= 2 else: map_node.scale -= Vector2.ONE + map_node.position -= (map_node.position + mouse.position * map_node.scale)- (map_node.position + mouse.position * old_scale) BUTTON_MIDDLE: - view_origin = map_node.position + view_origin = map_node.global_position mouse_origin = ev.global_position dragging = true else: match ev.button_index: + BUTTON_LEFT: + placing = false + BUTTON_RIGHT: + deleting = false BUTTON_MIDDLE: dragging = false - map_node.position = view_origin - (mouse_origin - ev.global_position) + map_node.global_position = view_origin - (mouse_origin - ev.global_position) + +func place_tile(): + match placing_mode: + PlacingMode.NONE: + # Do nothing + pass + PlacingMode.OBJECT: + # TODO + pass + PlacingMode.TILEMAP: + var layer := placing_layer as TileMap + layer.set_cellv(cursor_pos, placing_tile_id) + layer.update_bitmask_area(cursor_pos) + +func delete_tile(): + match placing_mode: + PlacingMode.NONE: + # Do nothing + pass + PlacingMode.OBJECT: + # TODO + pass + PlacingMode.TILEMAP: + var layer := placing_layer as TileMap + layer.set_cellv(cursor_pos, -1) + layer.update_bitmask_area(cursor_pos) + +var group := ButtonGroup.new() + +func add_tile_tab(name: String, tilemap: TileMap): + var tab := add_tab(name) + tab.connect("tile_selected", self, "_tile_selected", [name, tilemap]) + var tileset := tilemap.tile_set + var ids := tileset.get_tiles_ids() + for id in ids: + var tile_name := tileset.tile_get_name(id) + var tile_icon := make_tile_texture(tileset, id) + tab.add_entry(id, group, tile_icon) + +func add_tab(name: String) -> TileTab: + var tab := TileTabScene.instance() as TileTab + tab.name = name + $layers/tabs.add_child(tab) + return tab + +func _toggle_tile_input(enable: bool): + input_lock = not enable + +func _tile_selected(id: int, name: String, tilemap: TileMap): + cursor_sprite.texture = make_tile_texture(tilemap.tile_set, id) + placing_mode = PlacingMode.TILEMAP + placing_layer = tilemap + placing_tile_id = id + +func make_tile_texture(tileset: TileSet, id: int) -> AtlasTexture: + var tile_mode := tileset.tile_get_tile_mode(id) + var tile_icon := AtlasTexture.new() + tile_icon.atlas = tileset.tile_get_texture(id) + match tile_mode: + TileSet.AUTO_TILE: + var tile_size := tileset.autotile_get_size(id) + tile_icon.region = Rect2( + tileset.autotile_get_icon_coordinate(id) * tile_size, + tile_size + ) + print(tile_icon.region) + TileSet.SINGLE_TILE: + tile_icon.region = tileset.tile_get_region(id) + return tile_icon diff --git a/Scenes/MapEditor.tscn b/Scenes/MapEditor.tscn index 09384b2..43421a5 100644 --- a/Scenes/MapEditor.tscn +++ b/Scenes/MapEditor.tscn @@ -1,9 +1,8 @@ -[gd_scene load_steps=23 format=2] +[gd_scene load_steps=16 format=2] [ext_resource path="res://Graphics/deepspace_mat.tres" type="Material" id=1] [ext_resource path="res://Scenes/InEditorMap.gd" type="Script" id=2] [ext_resource path="res://Graphics/tgstation/walls.tres" type="TileSet" id=3] -[ext_resource path="res://Graphics/tgstation/1x1.tres" type="TileSet" id=4] [ext_resource path="res://Graphics/tgstation/base.tres" type="TileSet" id=5] [ext_resource path="res://Graphics/tgstation/floor.tres" type="TileSet" id=6] [ext_resource path="res://Graphics/tgstation/cables.tres" type="TileSet" id=7] @@ -11,9 +10,7 @@ [ext_resource path="res://Graphics/UI/uifont.tres" type="DynamicFont" id=9] [ext_resource path="res://Scenes/MapEditor.gd" type="Script" id=10] [ext_resource path="res://Graphics/UI/grid.png" type="Texture" id=11] -[ext_resource path="res://Graphics/tgstation/floors.png" type="Texture" id=12] -[ext_resource path="res://Graphics/tgstation/wires-l2.png" type="Texture" id=13] -[ext_resource path="res://Graphics/tgstation/wall.png" type="Texture" id=14] +[ext_resource path="res://Graphics/UI/ui_theme.tres" type="Theme" id=12] [sub_resource type="StyleBoxFlat" id=1] content_margin_left = 15.0 @@ -48,20 +45,6 @@ corner_radius_bottom_left = 3 content_margin_left = 10.0 content_margin_right = 10.0 -[sub_resource type="ButtonGroup" id=6] - -[sub_resource type="AtlasTexture" id=5] -atlas = ExtResource( 12 ) -region = Rect2( 32, 192, 32, 32 ) - -[sub_resource type="AtlasTexture" id=7] -atlas = ExtResource( 13 ) -region = Rect2( 64, 224, 32, 32 ) - -[sub_resource type="AtlasTexture" id=8] -atlas = ExtResource( 12 ) -region = Rect2( 96, 160, 32, 32 ) - [node name="Control" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 @@ -72,26 +55,32 @@ __meta__ = { } [node name="background" type="ColorRect" parent="."] -material = ExtResource( 1 ) anchor_right = 1.0 anchor_bottom = 1.0 -color = Color( 0, 0, 0, 1 ) +color = Color( 0, 0, 0, 0 ) __meta__ = { "_edit_lock_": true, "_edit_use_anchors_": false } [node name="map" type="Node2D" parent="."] +z_index = -5 +z_as_relative = false script = ExtResource( 2 ) -[node name="cursor" type="Node2D" parent="map"] - -[node name="Sprite" type="Sprite" parent="map/cursor"] -texture = ExtResource( 14 ) +[node name="background" type="Sprite" parent="map"] +material = ExtResource( 1 ) +position = Vector2( -2560, -2784 ) +texture = ExtResource( 11 ) centered = false +region_enabled = true +region_rect = Rect2( 0, 0, 6400, 6400 ) +__meta__ = { +"_edit_lock_": true +} [node name="grid" type="Sprite" parent="map"] -position = Vector2( -2560, -2800 ) +position = Vector2( -2560, -2784 ) texture = ExtResource( 11 ) centered = false region_enabled = true @@ -104,7 +93,6 @@ __meta__ = { [node name="base" type="TileMap" parent="map/tiles"] z_index = 1 -z_as_relative = false tile_set = ExtResource( 5 ) cell_size = Vector2( 32, 32 ) cell_quadrant_size = 32 @@ -113,7 +101,6 @@ format = 1 [node name="cables" type="TileMap" parent="map/tiles"] z_index = 2 -z_as_relative = false tile_set = ExtResource( 7 ) cell_size = Vector2( 32, 32 ) cell_quadrant_size = 32 @@ -122,7 +109,6 @@ format = 1 [node name="floor" type="TileMap" parent="map/tiles"] z_index = 3 -z_as_relative = false tile_set = ExtResource( 6 ) cell_size = Vector2( 32, 32 ) cell_quadrant_size = 32 @@ -131,21 +117,12 @@ format = 1 [node name="walls" type="TileMap" parent="map/tiles"] z_index = 4 -z_as_relative = false tile_set = ExtResource( 3 ) cell_size = Vector2( 32, 32 ) cell_quadrant_size = 32 occluder_light_mask = -2147483647 format = 1 script = ExtResource( 8 ) -extended_tilemap_node = NodePath("../../../VBoxContainer/map/tiles/1x1") - -[node name="1x1" type="TileMap" parent="map/tiles"] -z_index = 5 -z_as_relative = false -tile_set = ExtResource( 4 ) -cell_size = Vector2( 16, 16 ) -format = 1 [node name="engines" type="Node2D" parent="map"] modulate = Color( 0.980392, 0.980392, 0.980392, 1 ) @@ -177,6 +154,13 @@ z_index = 999 [node name="areas" type="Node2D" parent="map"] +[node name="cursor" type="Node2D" parent="map"] + +[node name="preview" type="Sprite" parent="map/cursor"] +modulate = Color( 1, 1, 1, 0.666667 ) +z_index = 5 +centered = false + [node name="menu" type="PanelContainer" parent="."] margin_left = 5.0 margin_top = 5.0 @@ -230,64 +214,24 @@ custom_fonts/font = ExtResource( 9 ) text = "Play" flat = false -[node name="layers" type="PanelContainer" parent="."] +[node name="layers" type="MarginContainer" parent="."] anchor_top = 1.0 +anchor_right = 1.0 anchor_bottom = 1.0 margin_left = 5.0 -margin_top = -177.0 -margin_right = 57.0 -margin_bottom = -5.0 +margin_top = -90.0 +margin_right = -5.0 +margin_bottom = -5.44409 size_flags_vertical = 13 - -[node name="buttons" type="VBoxContainer" parent="layers"] -margin_left = 4.0 -margin_top = 4.0 -margin_right = 48.0 -margin_bottom = 168.0 -alignment = 2 __meta__ = { "_edit_use_anchors_": false } -[node name="walls" type="Button" parent="layers/buttons"] -margin_right = 44.0 -margin_bottom = 38.0 -rect_min_size = Vector2( 32, 32 ) -size_flags_horizontal = 13 -size_flags_vertical = 13 -toggle_mode = true -group = SubResource( 6 ) -icon = ExtResource( 14 ) - -[node name="floor" type="Button" parent="layers/buttons"] -margin_top = 42.0 -margin_right = 44.0 -margin_bottom = 80.0 -rect_min_size = Vector2( 32, 32 ) -size_flags_horizontal = 13 -size_flags_vertical = 13 -toggle_mode = true -group = SubResource( 6 ) -icon = SubResource( 5 ) - -[node name="cables" type="Button" parent="layers/buttons"] -margin_top = 84.0 -margin_right = 44.0 -margin_bottom = 122.0 -rect_min_size = Vector2( 32, 32 ) -size_flags_horizontal = 13 -size_flags_vertical = 13 -toggle_mode = true -group = SubResource( 6 ) -icon = SubResource( 7 ) - -[node name="base" type="Button" parent="layers/buttons"] -margin_top = 126.0 -margin_right = 44.0 -margin_bottom = 164.0 -rect_min_size = Vector2( 32, 32 ) -size_flags_horizontal = 13 -size_flags_vertical = 13 -toggle_mode = true -group = SubResource( 6 ) -icon = SubResource( 8 ) +[node name="tabs" type="TabContainer" parent="layers"] +margin_right = 1270.0 +margin_bottom = 84.0 +rect_min_size = Vector2( 0, 80 ) +theme = ExtResource( 12 ) +tab_align = 0 +[connection signal="mouse_entered" from="background" to="." method="_toggle_tile_input" binds= [ true ]] +[connection signal="mouse_exited" from="background" to="." method="_toggle_tile_input" binds= [ false ]]