A game where you get to play as a slime, made with Godot.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.8 KiB

@tool
class_name TerrainEditingControls
extends VBoxContainer
enum ToolMode { HEIGHT, FLATTEN, PAINT, ERASE }
enum ToolShape { CORNER, CIRCLE, SQUARE }
@onready var tool_mode_buttons : Array[Button] = [ $Height, $Flatten, $Paint, $Erase ]
@onready var tool_shape_buttons : Array[Button] = [ $Corner, $Circle, $Square ]
@onready var paint_texture_buttons : Array[Button] = [ $Grass, $Dirt, $Rock, $Sand ]
@onready var draw_size_label : Label = $SizeLabel
@onready var draw_size_slider : Slider = $SizeSlider
@onready var raise_lower_toggle : Button = $RaiseLower
@onready var connected_toggle : Button = $Connected
@onready var corner_texture_default : Texture2D = preload("icons/corner.png")
@onready var corner_texture_tile : Texture2D = preload("icons/corner_tile.png")
## Gets or sets the currently active tool mode.
var tool_mode : ToolMode:
get: return index_of_pressed(tool_mode_buttons)
set(value): set_pressed(tool_mode_buttons, value); tool_mode_changed()
## Gets or sets the currently selected tool shape.
var tool_shape : ToolShape:
get: return index_of_pressed(tool_shape_buttons)
set(value): set_pressed(tool_shape_buttons, value); tool_shape_changed()
## Gets or sets the currently selected texture to paint with.
var texture : int:
get: return index_of_pressed(paint_texture_buttons) + 1
set(value): set_pressed(paint_texture_buttons, value - 1)
## Gets or sets the current draw size for CIRCLE or SQUARE shapes.
var draw_size : int:
get: return roundi(-draw_size_slider.value)
set(value): draw_size_slider.value = -value
## Gets whether the raise/lower button is currently active.
var is_raise : bool:
get: return raise_lower_toggle.button_pressed
## Gets whether the raise/lower button is currently active.
var is_connected : bool:
get: return connected_toggle.button_pressed
func _ready() -> void:
# Update 'tool_mode', 'tool_shape' or 'texture' when any of the buttons are pressed.
for i in len(tool_mode_buttons ): tool_mode_buttons [i].pressed.connect(func(): tool_mode = i )
for i in len(tool_shape_buttons ): tool_shape_buttons [i].pressed.connect(func(): tool_shape = i )
for i in len(paint_texture_buttons): paint_texture_buttons[i].pressed.connect(func(): texture = i + 1)
# Update 'draw_size_label' whenever the slider changes.
draw_size_slider.value_changed.connect(func(_value):
draw_size_label.text = str(draw_size))
func tool_mode_changed() -> void:
var is_height := (tool_mode == ToolMode.HEIGHT)
var is_flatten := (tool_mode == ToolMode.FLATTEN)
var is_paint := (tool_mode == ToolMode.PAINT)
var is_erase := (tool_mode == ToolMode.ERASE)
# In 'PAINT' and 'ERASE' mode, 'CORNER' affects a single tile regardless of 'draw_size'.
# This changes the button's icon to a small square to communicate that.
tool_shape_buttons[0].icon = corner_texture_tile if is_paint or is_erase else corner_texture_default
# Enable texture buttons only in 'PAINT' mode.
for button in paint_texture_buttons: button.disabled = !is_paint
# Enable raise/lower toggle only in 'HEIGHT' mode.
raise_lower_toggle.disabled = !is_height
# Enable connected toggle only in 'HEIGHT' or 'FLATTEN' mode.
connected_toggle.disabled = !(is_height or is_flatten)
func tool_shape_changed() -> void:
var is_corner := (tool_shape == ToolShape.CORNER)
draw_size_slider.editable = !is_corner;
## Returns the index of the first pressed (toggled on) button.
func index_of_pressed(buttons: Array[Button]) -> int:
for i in len(buttons):
var button := buttons[i]
if button.button_pressed:
return i
return 0
## Sets the pressed state (toggled on) of the button
## with the specified index, unsetting all others.
func set_pressed(buttons: Array[Button], value: int) -> void:
for i in len(buttons):
var button := buttons[i]
var is_pressed := (value == i)
button.button_pressed = is_pressed
button.flat = !is_pressed