Files
aetherbound-guild/runtime/entry/entry_chrome.gd
T

300 lines
13 KiB
GDScript

class_name ABGEntryChrome
extends Control
const INK := Color("#111921")
const NAVY := Color("#182838")
const NAVY_LIFT := Color("#263e53")
const NAVY_DISABLED := Color("#323b43")
const GOLD := Color("#b99a5d")
const GOLD_LIGHT := Color("#ead49b")
const IVORY := Color("#e8d9b7")
const IVORY_LIGHT := Color("#f5ead0")
const SKY := Color("#73b9e7")
const STEEL := Color("#73808a")
const SHADOW := Color(0.02, 0.035, 0.045, 0.82)
var variant := "panel"
var icon_kind := ""
func configure(next_variant: String, next_icon := "") -> ABGEntryChrome:
variant = next_variant
icon_kind = next_icon
return self
func _ready() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
set_process(variant in ["action_primary", "action_secondary", "utility", "choice", "tool", "toggle"])
queue_redraw()
func _process(_delta: float) -> void:
queue_redraw()
func _draw() -> void:
match variant:
"title_header":
_draw_enamel_frame(Rect2(Vector2.ZERO, size), 13.0, GOLD, false, false)
_draw_header_details()
"command_dock":
_draw_dock()
"crest_banner":
_draw_banner()
"boot_plate":
_draw_boot_plate()
"setup_split":
_draw_setup_split()
"settings_frame":
_draw_settings_frame()
"action_primary":
_draw_button(true, false)
"action_secondary":
_draw_button(false, false)
"utility":
_draw_button(false, true)
"choice":
_draw_setting_button("choice")
"tool":
_draw_setting_button("tool")
"toggle":
_draw_setting_button("toggle")
_:
_draw_enamel_frame(Rect2(Vector2.ZERO, size), 10.0, GOLD, false, false)
func _draw_enamel_frame(rect: Rect2, cut: float, trim: Color, disabled: bool, hot: bool) -> void:
if rect.size.x <= 2.0 or rect.size.y <= 2.0:
return
var shadow_rect := Rect2(rect.position + Vector2(3.0, 4.0), rect.size)
draw_colored_polygon(_cut_polygon(shadow_rect, cut), SHADOW)
var fill := NAVY_DISABLED if disabled else (NAVY_LIFT if hot else NAVY)
var outer := _cut_polygon(rect, cut)
draw_colored_polygon(outer, fill)
_draw_closed_line(outer, trim, 2.0)
var inner_rect := rect.grow(-4.0)
if inner_rect.size.x > 8.0 and inner_rect.size.y > 8.0:
_draw_closed_line(_cut_polygon(inner_rect, maxf(3.0, cut - 4.0)), Color(trim, 0.58), 1.0)
var highlight := SKY if hot and not disabled else Color(GOLD_LIGHT, 0.34)
draw_line(Vector2(rect.position.x + cut + 8.0, rect.position.y + 6.0), Vector2(rect.end.x - cut - 8.0, rect.position.y + 6.0), highlight, 1.0, true)
func _draw_header_details() -> void:
var w := size.x
var h := size.y
draw_line(Vector2(24.0, h - 12.0), Vector2(w - 32.0, h - 12.0), Color(GOLD, 0.55), 1.0, true)
for x in [w - 45.0, w - 32.0, w - 19.0]:
_draw_diamond(Vector2(x, h - 12.0), 3.5, SKY if x == w - 32.0 else GOLD)
_draw_corner_brackets(Rect2(Vector2.ZERO, size), GOLD_LIGHT)
func _draw_dock() -> void:
if size.x <= 2.0 or size.y <= 2.0:
return
var w := size.x
var h := size.y
var cut := 14.0
var points := PackedVector2Array([
Vector2(0.0, cut), Vector2(cut, 0.0), Vector2(w - cut, 0.0),
Vector2(w, cut), Vector2(w, h), Vector2(0.0, h)
])
draw_colored_polygon(PackedVector2Array([
Vector2(3.0, cut + 4.0), Vector2(cut + 3.0, 4.0), Vector2(w - cut + 3.0, 4.0),
Vector2(w + 3.0, cut + 4.0), Vector2(w + 3.0, h + 4.0), Vector2(3.0, h + 4.0)
]), SHADOW)
draw_colored_polygon(points, Color("#142331"))
_draw_closed_line(points, GOLD, 2.0)
draw_line(Vector2(cut + 8.0, 6.0), Vector2(w - cut - 8.0, 6.0), Color(GOLD_LIGHT, 0.72), 1.0, true)
draw_line(Vector2(cut + 14.0, 11.0), Vector2(w - cut - 14.0, 11.0), Color(SKY, 0.22), 1.0, true)
var divider_x := minf(w * 0.46, w - 365.0)
if divider_x > 180.0:
draw_line(Vector2(divider_x, 23.0), Vector2(divider_x, h - 18.0), Color(GOLD, 0.45), 1.0, true)
_draw_diamond(Vector2(divider_x, 17.0), 4.0, GOLD_LIGHT)
func _draw_boot_plate() -> void:
var plate_height := minf(188.0, size.y)
var plate_width := minf(690.0, size.x + 12.0)
var rect := Rect2(Vector2(-12.0, size.y - plate_height), Vector2(plate_width, plate_height + 12.0))
_draw_enamel_frame(rect, 13.0, GOLD, false, false)
var crest_center := Vector2(rect.end.x - 48.0, rect.position.y + 45.0)
_draw_crest(crest_center, 18.0, IVORY_LIGHT)
draw_arc(crest_center, 28.0, 0.0, TAU, 32, Color(GOLD, 0.6), 1.0, true)
draw_line(Vector2(rect.position.x + 22.0, rect.position.y + 18.0), Vector2(rect.end.x - 92.0, rect.position.y + 18.0), Color(SKY, 0.4), 1.0, true)
for offset in [0.0, 12.0, 24.0]:
_draw_diamond(Vector2(rect.end.x - 36.0 - offset, rect.end.y - 22.0), 3.0, SKY if offset == 12.0 else GOLD)
func _draw_setup_split() -> void:
var panel_x := size.x * 0.46
var panel_height := minf(size.y, 310.0)
var rect := Rect2(Vector2(panel_x, -10.0), Vector2(size.x - panel_x + 12.0, panel_height + 20.0))
_draw_enamel_frame(rect, 13.0, GOLD, false, false)
draw_line(Vector2(panel_x + 18.0, 13.0), Vector2(size.x - 24.0, 13.0), Color(SKY, 0.42), 1.0, true)
_draw_diamond(Vector2(panel_x, panel_height * 0.5), 5.0, GOLD_LIGHT)
draw_line(Vector2(-8.0, size.y - 18.0), Vector2(panel_x - 20.0, size.y - 18.0), Color(GOLD, 0.72), 2.0, true)
draw_line(Vector2(-8.0, size.y - 13.0), Vector2(panel_x - 40.0, size.y - 13.0), Color(SKY, 0.32), 1.0, true)
func _draw_settings_frame() -> void:
var rect := Rect2(Vector2(-12.0, -10.0), size + Vector2(24.0, 20.0))
_draw_enamel_frame(rect, 14.0, GOLD, false, false)
draw_line(Vector2(22.0, 54.0), Vector2(size.x - 22.0, 54.0), Color(GOLD, 0.52), 1.0, true)
_draw_diamond(Vector2(size.x - 34.0, 27.0), 5.0, SKY)
_draw_diamond(Vector2(size.x - 50.0, 27.0), 3.0, GOLD_LIGHT)
draw_line(Vector2(22.0, size.y - 57.0), Vector2(size.x - 22.0, size.y - 57.0), Color(GOLD, 0.42), 1.0, true)
_draw_crest(Vector2(size.x - 92.0, size.y - 125.0), 44.0, Color(GOLD_LIGHT, 0.08))
draw_arc(Vector2(size.x - 92.0, size.y - 125.0), 61.0, 0.0, TAU, 40, Color(SKY, 0.06), 1.0, true)
func _draw_banner() -> void:
if size.x <= 2.0 or size.y <= 2.0:
return
var w := size.x
var h := size.y
var points := PackedVector2Array([
Vector2(4.0, 0.0), Vector2(w - 4.0, 0.0), Vector2(w - 4.0, h - 18.0),
Vector2(w * 0.5, h), Vector2(4.0, h - 18.0)
])
draw_colored_polygon(points, Color("#294f7a"))
_draw_closed_line(points, GOLD, 2.0)
var inner := PackedVector2Array([
Vector2(9.0, 5.0), Vector2(w - 9.0, 5.0), Vector2(w - 9.0, h - 21.0),
Vector2(w * 0.5, h - 6.0), Vector2(9.0, h - 21.0)
])
_draw_closed_line(inner, Color(GOLD_LIGHT, 0.62), 1.0)
_draw_crest(Vector2(w * 0.5, h * 0.42), minf(w, h) * 0.23, IVORY_LIGHT)
_draw_diamond(Vector2(w * 0.5, h - 13.0), 3.0, GOLD_LIGHT)
func _draw_button(primary: bool, utility: bool) -> void:
var button := get_parent() as BaseButton
var disabled := button != null and button.disabled
var hot := button != null and not disabled and (button.is_hovered() or button.has_focus())
var trim := GOLD_LIGHT if primary or hot else GOLD
if utility:
_draw_ivory_button(disabled, hot)
else:
_draw_enamel_frame(Rect2(Vector2.ZERO, size), 9.0, trim, disabled, hot)
if primary and not disabled:
draw_colored_polygon(_cut_polygon(Rect2(Vector2(6.0, 6.0), Vector2(7.0, maxf(0.0, size.y - 12.0))), 2.0), SKY if hot else GOLD_LIGHT)
_draw_icon(Vector2(25.0, size.y * 0.5), 11.0, disabled, utility, hot)
func _draw_setting_button(kind: String) -> void:
var button := get_parent() as BaseButton
var disabled := button != null and button.disabled
var selected := button != null and bool(button.get_meta("selected_entry_tab", false))
var hot := button != null and not disabled and (button.is_hovered() or button.has_focus())
if kind == "tool" and selected:
_draw_ivory_button(false, true)
_draw_diamond(Vector2(13.0, size.y * 0.5), 4.0, Color("#294f7a"))
else:
_draw_enamel_frame(Rect2(Vector2.ZERO, size), 6.0, GOLD_LIGHT if hot else GOLD, disabled, hot)
if kind == "tool":
draw_colored_polygon(PackedVector2Array([
Vector2(6.0, 7.0), Vector2(10.0, 7.0), Vector2(10.0, size.y - 7.0), Vector2(6.0, size.y - 7.0)
]), SKY if hot else Color(GOLD, 0.55))
if kind == "choice":
var split := size.x * 0.58
var value_rect := Rect2(Vector2(split, 4.0), Vector2(maxf(0.0, size.x - split - 4.0), maxf(0.0, size.y - 8.0)))
if value_rect.size.x > 10.0:
var fill := Color("#a8a69f") if disabled else IVORY
draw_colored_polygon(_cut_polygon(value_rect, 4.0), fill)
draw_line(Vector2(split, 9.0), Vector2(split, size.y - 9.0), GOLD, 1.0, true)
if kind == "toggle":
var on := button != null and button.button_pressed
var center := Vector2(size.x - 27.0, size.y * 0.5)
draw_colored_polygon(_cut_polygon(Rect2(center - Vector2(17.0, 9.0), Vector2(34.0, 18.0)), 5.0), Color("#233846") if not disabled else NAVY_DISABLED)
_draw_closed_line(_cut_polygon(Rect2(center - Vector2(17.0, 9.0), Vector2(34.0, 18.0)), 5.0), GOLD if not disabled else STEEL, 1.0)
_draw_diamond(center + Vector2(8.0 if on else -8.0, 0.0), 6.0, SKY if on and not disabled else IVORY if not disabled else STEEL)
func _draw_ivory_button(disabled: bool, hot: bool) -> void:
var rect := Rect2(Vector2.ZERO, size)
var points := _cut_polygon(rect, 8.0)
draw_colored_polygon(_cut_polygon(Rect2(Vector2(2.0, 3.0), size), 8.0), SHADOW)
var fill := Color("#b9b5aa") if disabled else (IVORY_LIGHT if hot else IVORY)
draw_colored_polygon(points, fill)
_draw_closed_line(points, GOLD if not hot else Color("#8c6b2e"), 2.0)
var inner := rect.grow(-4.0)
_draw_closed_line(_cut_polygon(inner, 4.0), Color(INK, 0.38), 1.0)
draw_line(Vector2(15.0, 5.0), Vector2(size.x - 15.0, 5.0), Color.WHITE if hot else Color(IVORY_LIGHT, 0.75), 1.0, true)
func _draw_icon(center: Vector2, radius: float, disabled: bool, utility: bool, hot: bool) -> void:
var color := STEEL if disabled else (INK if utility else (SKY if hot else IVORY_LIGHT))
draw_circle(center, radius + 5.0, Color(INK, 0.28) if utility else Color("#233c52"))
draw_arc(center, radius + 5.0, 0.0, TAU, 24, GOLD if not disabled else STEEL, 1.0, true)
match icon_kind:
"new_game":
_draw_crest(center, radius * 0.8, color)
"continue":
draw_line(center + Vector2(-6.0, 0.0), center + Vector2(4.0, 0.0), color, 2.0, true)
draw_polyline(PackedVector2Array([center + Vector2(0.0, -5.0), center + Vector2(6.0, 0.0), center + Vector2(0.0, 5.0)]), color, 2.0, true)
"settings":
draw_arc(center, 5.0, 0.0, TAU, 20, color, 2.0, true)
draw_circle(center, 1.8, color)
for angle in range(0, 360, 60):
var direction := Vector2.RIGHT.rotated(deg_to_rad(float(angle)))
draw_line(center + direction * 6.0, center + direction * 9.0, color, 2.0, true)
"credits":
draw_polyline(PackedVector2Array([center + Vector2(-8.0, -6.0), center + Vector2(-1.0, -4.0), center + Vector2(-1.0, 7.0), center + Vector2(-8.0, 5.0), center + Vector2(-8.0, -6.0)]), color, 1.6, true)
draw_polyline(PackedVector2Array([center + Vector2(8.0, -6.0), center + Vector2(1.0, -4.0), center + Vector2(1.0, 7.0), center + Vector2(8.0, 5.0), center + Vector2(8.0, -6.0)]), color, 1.6, true)
_:
_draw_diamond(center, radius * 0.55, color)
func _draw_crest(center: Vector2, radius: float, color: Color) -> void:
var points := PackedVector2Array([
center + Vector2(0.0, -radius), center + Vector2(radius * 0.32, -radius * 0.3),
center + Vector2(radius, 0.0), center + Vector2(radius * 0.32, radius * 0.3),
center + Vector2(0.0, radius), center + Vector2(-radius * 0.32, radius * 0.3),
center + Vector2(-radius, 0.0), center + Vector2(-radius * 0.32, -radius * 0.3),
center + Vector2(0.0, -radius)
])
draw_polyline(points, color, 2.0, true)
draw_line(center + Vector2(-radius * 0.48, 0.0), center + Vector2(radius * 0.48, 0.0), color, 1.0, true)
draw_line(center + Vector2(0.0, -radius * 0.48), center + Vector2(0.0, radius * 0.48), color, 1.0, true)
draw_circle(center, maxf(1.5, radius * 0.13), SKY)
func _draw_corner_brackets(rect: Rect2, color: Color) -> void:
var length := 12.0
var inset := 9.0
for x_sign in [-1.0, 1.0]:
for y_sign in [-1.0, 1.0]:
var corner := Vector2(inset if x_sign < 0.0 else rect.size.x - inset, inset if y_sign < 0.0 else rect.size.y - inset)
draw_line(corner, corner + Vector2(length * -x_sign, 0.0), Color(color, 0.58), 1.0, true)
draw_line(corner, corner + Vector2(0.0, length * -y_sign), Color(color, 0.58), 1.0, true)
func _draw_diamond(center: Vector2, radius: float, color: Color) -> void:
var points := PackedVector2Array([
center + Vector2(0.0, -radius), center + Vector2(radius, 0.0),
center + Vector2(0.0, radius), center + Vector2(-radius, 0.0)
])
draw_colored_polygon(points, color)
func _cut_polygon(rect: Rect2, cut: float) -> PackedVector2Array:
var left := rect.position.x
var top := rect.position.y
var right := rect.end.x
var bottom := rect.end.y
var safe_cut := minf(cut, minf(rect.size.x, rect.size.y) * 0.45)
return PackedVector2Array([
Vector2(left + safe_cut, top), Vector2(right - safe_cut, top),
Vector2(right, top + safe_cut), Vector2(right, bottom - safe_cut),
Vector2(right - safe_cut, bottom), Vector2(left + safe_cut, bottom),
Vector2(left, bottom - safe_cut), Vector2(left, top + safe_cut)
])
func _draw_closed_line(points: PackedVector2Array, color: Color, width: float) -> void:
var closed := PackedVector2Array(points)
if not points.is_empty():
closed.append(points[0])
draw_polyline(closed, color, width, true)