This repository has been archived on 2020-09-30. You can view files and clone it, but cannot push or open issues or pull requests.
odyssey-old/Scenes/MapEditor.gd

176 lines
4.7 KiB
GDScript

extends Control
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.0
const MAP_SCALE_MIN := 0.25
const TileTabScene := preload("res://Scenes/Editor/TileTab.tscn")
func _ready():
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
# Drag variables
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.global_position = view_origin - (mouse_origin - ev.global_position)
else:
# Map cursor location to grid
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
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.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.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