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 PARCHMENT_LIGHT := Color("#fff4d6") 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", "candidate_plate", "company_primary", "company_secondary", "company_utility", "company_tool", "company_destination", "content_primary", "content_secondary", "content_destination", "anchor_icon", "guild_status_icon", "guild_nav_icon"]) 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() "boot_field_plate": _draw_boot_field_plate() "setup_split": _draw_setup_split() "settings_frame": _draw_settings_frame() "initial_company_frame": _draw_initial_company_frame() "initial_company_scene_frame": _draw_initial_company_scene_frame() "content_scene_frame": _draw_content_scene_frame() "candidate_plate": _draw_candidate_plate() "company_primary": _draw_company_button("primary") "company_secondary": _draw_company_button("secondary") "company_utility": _draw_company_button("utility") "company_tool": _draw_company_button("tool") "company_destination": _draw_company_button("destination") "content_primary": _draw_content_button("primary") "content_secondary": _draw_content_button("secondary") "content_destination": _draw_content_button("destination") "anchor_icon": _draw_anchor_icon() "guild_status_icon": _draw_guild_status_icon() "guild_nav_icon": _draw_guild_nav_icon() "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_boot_field_plate() -> void: if size.x <= 2.0 or size.y <= 2.0: return var plate_height := minf(190.0, size.y * 0.58) var plate := Rect2(Vector2(-8.0, size.y - plate_height), Vector2(size.x + 16.0, plate_height + 8.0)) draw_colored_polygon(_cut_polygon(Rect2(plate.position + Vector2(3.0, 4.0), plate.size), 12.0), Color(SHADOW, 0.44)) draw_colored_polygon(_cut_polygon(plate, 12.0), Color(INK, 0.58)) _draw_closed_line(_cut_polygon(plate, 12.0), Color(GOLD_LIGHT, 0.78), 1.4) draw_line(Vector2(20.0, plate.position.y + 18.0), Vector2(size.x - 82.0, plate.position.y + 18.0), Color(SKY, 0.48), 1.0, true) draw_line(Vector2(20.0, plate.end.y - 18.0), Vector2(size.x - 24.0, plate.end.y - 18.0), Color(GOLD, 0.64), 1.0, true) _draw_crest(Vector2(size.x - 48.0, plate.position.y + 47.0), 17.0, IVORY_LIGHT) draw_arc(Vector2(size.x - 48.0, plate.position.y + 47.0), 27.0, 0.0, TAU, 32, Color(GOLD_LIGHT, 0.58), 1.0, true) _draw_open_frame_corners() 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_initial_company_frame() -> void: _draw_initial_company_open_frame(false) func _draw_initial_company_scene_frame() -> void: _draw_initial_company_open_frame(true) func _draw_content_scene_frame() -> void: if size.x <= 2.0 or size.y <= 2.0: return var rect := Rect2(Vector2(1.0, 1.0), size - Vector2(2.0, 2.0)) var top_height := minf(58.0, size.y * 0.20) var bottom_height := minf(54.0, size.y * 0.18) draw_colored_polygon(_cut_polygon(Rect2(Vector2.ZERO, Vector2(size.x, top_height)), 10.0), Color(INK, 0.58)) draw_colored_polygon(_cut_polygon(Rect2(Vector2(0.0, size.y - bottom_height), Vector2(size.x, bottom_height)), 10.0), Color(INK, 0.50)) var lower_band := Rect2(Vector2(0.0, maxf(top_height, size.y - bottom_height - 104.0)), Vector2(size.x * 0.53, 104.0)) draw_colored_polygon(_cut_polygon(lower_band, 8.0), Color(INK, 0.28)) var context_band := Rect2(Vector2(size.x * 0.53, top_height - 1.0), Vector2(size.x * 0.47, maxf(0.0, size.y - top_height - bottom_height + 2.0))) draw_colored_polygon(_cut_polygon(context_band, 8.0), Color(INK, 0.56)) draw_line(Vector2(context_band.position.x, context_band.position.y + 12.0), Vector2(context_band.position.x, context_band.end.y - 12.0), Color(GOLD_LIGHT, 0.42), 1.0, true) _draw_closed_line(_cut_polygon(rect, 11.0), Color(GOLD_LIGHT, 0.76), 1.2) draw_line(Vector2(22.0, top_height - 5.0), Vector2(size.x - 22.0, top_height - 5.0), Color(GOLD, 0.66), 1.0, true) draw_line(Vector2(22.0, size.y - bottom_height + 3.0), Vector2(size.x - 22.0, size.y - bottom_height + 3.0), Color(GOLD, 0.54), 1.0, true) _draw_open_frame_corners() func _draw_content_button(kind: String) -> 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 rect := Rect2(Vector2(1.0, 1.0), size - Vector2(2.0, 3.0)) if rect.size.x <= 6.0 or rect.size.y <= 6.0: return var points := _company_command_polygon(rect, 9.0 if kind != "primary" else 12.0, 5.0) var fill := Color("#b9b5aa", 0.78) if disabled else Color("#f1e0bb", 0.94) if kind == "primary" or kind == "destination" else Color(NAVY, 0.46 if hot else 0.38) var trim := STEEL if disabled else Color("#806536", 0.92) if kind == "primary" or kind == "destination" else Color(GOLD_LIGHT, 0.76) draw_colored_polygon(points, fill) _draw_closed_line(points, trim, 1.2) draw_line(Vector2(rect.position.x + 14.0, rect.position.y + 5.0), Vector2(rect.end.x - 16.0, rect.position.y + 5.0), Color(PARCHMENT_LIGHT, 0.48), 1.0, true) _draw_company_icon(Vector2(rect.position.x + 18.0, rect.position.y + rect.size.y * 0.5), disabled, hot, "utility" if kind in ["primary", "destination"] else kind) func _draw_anchor_icon() -> 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 center := size * 0.5 var radius := minf(size.x, size.y) * 0.38 draw_circle(center + Vector2(2.0, 3.0), radius, Color(SHADOW, 0.55)) draw_circle(center, radius, Color("#142b3a", 0.92) if not disabled else Color("#6a6d68", 0.72)) draw_arc(center, radius, 0.0, TAU, 32, STEEL if disabled else (PARCHMENT_LIGHT if hot else Color(GOLD_LIGHT, 0.88)), 1.8, true) draw_arc(center, radius - 5.0, 0.0, TAU, 32, Color(GOLD, 0.50), 1.0, true) _draw_company_icon(center, disabled, hot, "utility") func _draw_guild_status_icon() -> 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 medallion_radius := minf(minf(size.x, size.y) * 0.40, 26.0) _draw_guild_medallion(size * 0.5, medallion_radius, disabled, hot) func _draw_guild_nav_icon() -> 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 medallion_radius := minf(minf(size.x, size.y) * 0.44, 34.0) _draw_guild_medallion(size * 0.5, medallion_radius, disabled, hot) func _draw_guild_medallion(center: Vector2, medallion_radius: float, disabled: bool, hot: bool) -> void: if medallion_radius <= 2.0: return var radius := medallion_radius * 0.62 var color := STEEL if disabled else (PARCHMENT_LIGHT if hot else GOLD_LIGHT) var line_width := maxf(1.4, radius * 0.15) draw_circle(center + Vector2(maxf(1.0, medallion_radius * 0.06), maxf(1.5, medallion_radius * 0.09)), medallion_radius, Color(SHADOW, 0.62)) draw_circle(center, medallion_radius, Color("#173044", 0.88) if not disabled else Color("#3f494d", 0.72)) draw_arc(center, medallion_radius, 0.0, TAU, 32, Color(GOLD, 0.92) if not disabled else STEEL, maxf(1.2, line_width * 0.72), true) draw_arc(center, maxf(1.0, medallion_radius - maxf(3.0, medallion_radius * 0.14)), 0.0, TAU, 32, Color(GOLD_LIGHT, 0.44) if not disabled else Color(STEEL, 0.38), 1.0, true) match icon_kind: "back": draw_polyline(PackedVector2Array([ center + Vector2(radius * 0.35, -radius * 0.62), center + Vector2(-radius * 0.35, 0.0), center + Vector2(radius * 0.35, radius * 0.62), ]), color, line_width, true) draw_line(center + Vector2(-radius * 0.25, 0.0), center + Vector2(radius * 0.72, 0.0), color, line_width, true) "roster", "company": _draw_guild_people(center, radius, color, line_width) "equipment": var shield := PackedVector2Array([ center + Vector2(-radius * 0.62, -radius * 0.58), center + Vector2(radius * 0.62, -radius * 0.58), center + Vector2(radius * 0.52, radius * 0.24), center + Vector2(0.0, radius * 0.78), center + Vector2(-radius * 0.52, radius * 0.24), ]) draw_colored_polygon(shield, Color(color, 0.18)) _draw_closed_line(shield, color, line_width) draw_line(center + Vector2(0.0, -radius * 0.48), center + Vector2(0.0, radius * 0.52), color, maxf(1.0, line_width * 0.65), true) "party": draw_line(center + Vector2(-radius * 0.48, -radius * 0.70), center + Vector2(-radius * 0.48, radius * 0.72), color, line_width, true) draw_colored_polygon(PackedVector2Array([ center + Vector2(-radius * 0.38, -radius * 0.62), center + Vector2(radius * 0.62, -radius * 0.40), center + Vector2(radius * 0.22, radius * 0.08), center + Vector2(-radius * 0.38, -radius * 0.06), ]), Color(color, 0.92)) "risk": var flame := PackedVector2Array([ center + Vector2(0.0, -radius * 0.78), center + Vector2(radius * 0.52, -radius * 0.08), center + Vector2(radius * 0.42, radius * 0.48), center + Vector2(0.0, radius * 0.74), center + Vector2(-radius * 0.48, radius * 0.42), center + Vector2(-radius * 0.38, -radius * 0.10), center + Vector2(-radius * 0.04, radius * 0.14), center + Vector2(0.0, -radius * 0.78), ]) draw_polyline(flame, color, line_width, true) "pressure": var spark := PackedVector2Array([ center + Vector2(0.0, -radius * 0.82), center + Vector2(radius * 0.20, -radius * 0.22), center + Vector2(radius * 0.76, 0.0), center + Vector2(radius * 0.20, radius * 0.22), center + Vector2(0.0, radius * 0.82), center + Vector2(-radius * 0.20, radius * 0.22), center + Vector2(-radius * 0.76, 0.0), center + Vector2(-radius * 0.20, -radius * 0.22), ]) draw_colored_polygon(spark, Color(color, 0.94)) _draw_closed_line(spark, color, maxf(1.0, line_width * 0.65)) "coin": var gem_color := STEEL if disabled else (PARCHMENT_LIGHT if hot else SKY) var gem := PackedVector2Array([ center + Vector2(0.0, -radius * 0.82), center + Vector2(radius * 0.62, -radius * 0.18), center + Vector2(radius * 0.42, radius * 0.72), center + Vector2(-radius * 0.42, radius * 0.72), center + Vector2(-radius * 0.62, -radius * 0.18), ]) draw_colored_polygon(gem, Color(gem_color, 0.34)) _draw_closed_line(gem, gem_color, line_width) draw_line(center + Vector2(0.0, -radius * 0.75), center + Vector2(0.0, radius * 0.66), gem_color, maxf(1.0, line_width * 0.65), true) "settings": draw_arc(center, radius * 0.46, 0.0, TAU, 20, color, line_width, true) draw_circle(center, radius * 0.14, color) for angle in range(0, 360, 45): var direction := Vector2.RIGHT.rotated(deg_to_rad(float(angle))) draw_line(center + direction * radius * 0.57, center + direction * radius * 0.82, color, line_width, true) _: _draw_crest(center, radius * 0.72, color) func _draw_guild_people(center: Vector2, radius: float, color: Color, line_width: float) -> void: for offset in [-0.46, 0.0, 0.46]: var head_center := center + Vector2(radius * offset, -radius * (0.28 if offset == 0.0 else 0.18)) var head_radius := radius * (0.22 if offset == 0.0 else 0.18) draw_arc(head_center, head_radius, 0.0, TAU, 14, color, line_width, true) var shoulder_y := center.y + radius * (0.24 if offset == 0.0 else 0.30) draw_arc(Vector2(head_center.x, shoulder_y), radius * (0.34 if offset == 0.0 else 0.28), PI, TAU, 12, color, line_width, true) func _draw_initial_company_open_frame(scene_forward: bool) -> void: if size.x <= 2.0 or size.y <= 2.0: return var frame_rect := Rect2(Vector2(0.75, 0.75), size - Vector2(1.5, 1.5)) var frame_points := _cut_polygon(frame_rect, 11.0) draw_colored_polygon(frame_points, Color(INK, 0.04 if scene_forward else 0.12)) _draw_closed_line(frame_points, Color(GOLD, 0.72), 1.5) var top_height := minf(60.0, size.y * 0.22) var bottom_height := minf(60.0, size.y * 0.22) var top_strip := Rect2(Vector2.ZERO, Vector2(size.x, top_height)) var bottom_strip := Rect2(Vector2(0.0, size.y - bottom_height), Vector2(size.x, bottom_height)) draw_colored_polygon(_cut_polygon(top_strip, 10.0), Color(INK, 0.80 if scene_forward else 0.86)) draw_colored_polygon(_cut_polygon(bottom_strip, 10.0), Color(INK, 0.74 if scene_forward else 0.80)) var crest_center := Vector2(size.x * 0.5, minf(29.0, top_height * 0.5)) var rail_gap := 30.0 var rail_y := maxf(8.0, top_height - 4.0) draw_line(Vector2(20.0, rail_y), Vector2(crest_center.x - rail_gap, rail_y), Color(GOLD, 0.70), 1.0, true) draw_line(Vector2(crest_center.x + rail_gap, rail_y), Vector2(size.x - 20.0, rail_y), Color(GOLD, 0.70), 1.0, true) draw_line(Vector2(28.0, rail_y - 4.0), Vector2(size.x - 28.0, rail_y - 4.0), Color(SKY, 0.20), 1.0, true) var footer_y := size.y - bottom_height + 2.0 draw_line(Vector2(20.0, footer_y), Vector2(size.x - 20.0, footer_y), Color(GOLD, 0.62), 1.0, true) _draw_crest(crest_center, 12.0, IVORY_LIGHT) _draw_open_frame_corners() func _draw_open_frame_corners() -> void: _draw_frame_corner_fitting(Vector2(1.0, 1.0), 1.0, 1.0) _draw_frame_corner_fitting(Vector2(size.x - 1.0, 1.0), -1.0, 1.0) _draw_frame_corner_fitting(Vector2(1.0, size.y - 1.0), 1.0, -1.0) _draw_frame_corner_fitting(Vector2(size.x - 1.0, size.y - 1.0), -1.0, -1.0) func _draw_frame_corner_fitting(origin: Vector2, x_direction: float, y_direction: float) -> void: var x := Vector2(x_direction, 0.0) var y := Vector2(0.0, y_direction) var points := PackedVector2Array([ origin, origin + x * 48.0, origin + x * 40.0 + y * 6.0, origin + x * 15.0 + y * 6.0, origin + x * 7.0 + y * 14.0, origin + x * 7.0 + y * 29.0, origin + y * 37.0, ]) draw_colored_polygon(points, Color("#203445")) _draw_closed_line(points, Color(GOLD, 0.94), 1.5) draw_line(origin + x * 13.0 + y * 10.0, origin + x * 35.0 + y * 10.0, Color(GOLD_LIGHT, 0.42), 1.0, true) draw_line(origin + x * 11.0 + y * 14.0, origin + x * 11.0 + y * 26.0, Color(SKY, 0.32), 1.0, true) _draw_diamond(origin + x * 7.0 + y * 7.0, 2.5, GOLD_LIGHT) func _draw_candidate_plate() -> void: var button := get_parent() as BaseButton var selected := button != null and bool(button.get_meta("candidate_selected", false)) var inspected := button != null and bool(button.get_meta("candidate_inspected", false)) var hot := button != null and (button.is_hovered() or button.has_focus()) var trim := SKY if selected else GOLD_LIGHT if inspected or hot else GOLD var ground_center := Vector2(size.x * 0.5, maxf(18.0, size.y - 49.0)) var ground := _ellipse_points(ground_center, maxf(24.0, size.x * 0.34), 9.0) draw_colored_polygon(ground, Color(SKY if selected else GOLD_LIGHT, 0.13 if selected else 0.05)) _draw_closed_line(ground, Color(trim, 0.90 if selected else 0.50), 2.0 if selected else 1.0) if inspected or hot: _draw_corner_brackets(Rect2(Vector2(4.0, 4.0), size - Vector2(8.0, 51.0)), trim) if selected: for offset in [0.0, 11.0]: _draw_diamond(Vector2(size.x - 15.0 - offset, 15.0), 3.5, SKY if offset == 0.0 else GOLD_LIGHT) func _draw_translucent_frame(rect: Rect2, cut: float, fill: Color, trim: Color, 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), Color(SHADOW, 0.55)) var outer := _cut_polygon(rect, cut) draw_colored_polygon(outer, fill) _draw_closed_line(outer, SKY if hot else 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.42), 1.0) 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), Color(SKY if hot else GOLD_LIGHT, 0.48), 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_company_button(kind: String) -> 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 rect := Rect2(Vector2(1.0, 1.0), size - Vector2(2.0, 3.0)) if rect.size.x <= 6.0 or rect.size.y <= 6.0: return var points: PackedVector2Array var fill: Color var trim: Color match kind: "utility": points = PackedVector2Array([ Vector2(rect.position.x, rect.position.y + 7.0), Vector2(rect.position.x + 9.0, rect.position.y), Vector2(rect.end.x - 14.0, rect.position.y), Vector2(rect.end.x, rect.position.y + 12.0), Vector2(rect.end.x - 8.0, rect.end.y), Vector2(rect.position.x + 9.0, rect.end.y), Vector2(rect.position.x, rect.end.y - 7.0) ]) fill = Color("#b9b5aa") if disabled else (IVORY_LIGHT if hot else IVORY) trim = STEEL if disabled else Color("#96753d") "tool": points = _company_command_polygon(rect, 5.0, 4.0) fill = Color(NAVY_DISABLED, 0.92) if disabled else Color(INK, 0.90 if hot else 0.78) trim = STEEL if disabled else (SKY if hot else Color(GOLD, 0.78)) "destination": points = PackedVector2Array([ Vector2(rect.position.x + 8.0, rect.position.y), Vector2(rect.end.x - 8.0, rect.position.y), Vector2(rect.end.x, rect.position.y + 8.0), Vector2(rect.end.x, rect.end.y - 8.0), Vector2(rect.end.x - 8.0, rect.end.y), Vector2(rect.position.x + 8.0, rect.end.y), Vector2(rect.position.x, rect.end.y - 8.0), Vector2(rect.position.x, rect.position.y + 8.0) ]) fill = Color("#394047") if disabled else Color("#253846") trim = Color(STEEL, 0.72) if disabled else Color(GOLD, 0.80) "primary": points = _company_command_polygon(rect, 12.0, 6.0) fill = Color(NAVY_DISABLED, 0.94) if disabled else Color("#203b50") if hot else Color("#172c3d") trim = STEEL if disabled else GOLD_LIGHT _: points = _company_command_polygon(rect, 9.0, 5.0) fill = Color(NAVY_DISABLED, 0.88) if disabled else Color(NAVY, 0.82 if hot else 0.68) trim = STEEL if disabled else (SKY if hot else Color(GOLD, 0.72)) var shadow_points := PackedVector2Array() for point in points: shadow_points.append(point + Vector2(2.0, 3.0)) draw_colored_polygon(shadow_points, Color(SHADOW, 0.48)) draw_colored_polygon(points, fill) _draw_closed_line(points, trim, 1.5 if kind == "primary" else 1.0) if kind == "utility": draw_line(Vector2(rect.end.x - 15.0, rect.position.y + 2.0), Vector2(rect.end.x - 7.0, rect.position.y + 12.0), Color(INK, 0.20), 1.0, true) draw_line(Vector2(rect.position.x + 12.0, rect.position.y + 5.0), Vector2(rect.end.x - 20.0, rect.position.y + 5.0), Color.WHITE, 1.0, true) elif kind == "tool": var marker := SKY if icon_kind == "mark_a" else GOLD_LIGHT if icon_kind == "mark_b" else trim draw_colored_polygon(PackedVector2Array([ Vector2(rect.position.x + 4.0, rect.position.y + 6.0), Vector2(rect.position.x + 8.0, rect.position.y + 3.0), Vector2(rect.position.x + 8.0, rect.end.y - 3.0), Vector2(rect.position.x + 4.0, rect.end.y - 6.0) ]), marker) elif kind == "destination": draw_line(Vector2(rect.position.x + 72.0, rect.position.y + 4.0), Vector2(rect.end.x - 14.0, rect.position.y + 4.0), Color(GOLD_LIGHT, 0.30), 1.0, true) draw_line(Vector2(rect.position.x + 72.0, rect.end.y - 4.0), Vector2(rect.end.x - 14.0, rect.end.y - 4.0), Color(INK, 0.55), 1.0, true) else: draw_line(Vector2(rect.position.x + 12.0, rect.position.y + 4.0), Vector2(rect.end.x - 17.0, rect.position.y + 4.0), Color(SKY if hot else GOLD_LIGHT, 0.48), 1.0, true) if kind == "primary" and not disabled: draw_colored_polygon(PackedVector2Array([ Vector2(rect.end.x - 10.0, rect.position.y + 7.0), Vector2(rect.end.x - 3.0, rect.size.y * 0.5 + 1.0), Vector2(rect.end.x - 10.0, rect.end.y - 6.0) ]), SKY if hot else GOLD_LIGHT) if kind not in ["tool", "destination"]: _draw_company_icon(Vector2(rect.position.x + 18.0, rect.position.y + rect.size.y * 0.5), disabled, hot, kind) func _company_command_polygon(rect: Rect2, tip: float, notch: float) -> PackedVector2Array: return PackedVector2Array([ Vector2(rect.position.x + 8.0, rect.position.y), Vector2(rect.end.x - tip, rect.position.y), Vector2(rect.end.x, rect.position.y + rect.size.y * 0.5), Vector2(rect.end.x - tip, rect.end.y), Vector2(rect.position.x + 8.0, rect.end.y), Vector2(rect.position.x, rect.end.y - 8.0), Vector2(rect.position.x + notch, rect.position.y + rect.size.y * 0.5), Vector2(rect.position.x, rect.position.y + 8.0) ]) func _draw_company_icon(center: Vector2, disabled: bool, hot: bool, kind: String) -> void: var color := STEEL if disabled else (INK if kind == "utility" else SKY if hot else IVORY_LIGHT) match icon_kind: "back": draw_polyline(PackedVector2Array([center + Vector2(5.0, -7.0), center + Vector2(-3.0, 0.0), center + Vector2(5.0, 7.0)]), color, 2.0, true) draw_line(center + Vector2(-2.0, 0.0), center + Vector2(8.0, 0.0), color, 2.0, true) "select": var button := get_parent() as BaseButton if button != null and bool(button.get_meta("command_selected", false)): draw_polyline(PackedVector2Array([center + Vector2(-7.0, 0.0), center + Vector2(-2.0, 5.0), center + Vector2(8.0, -6.0)]), color, 2.2, true) else: draw_line(center + Vector2(-6.0, 0.0), center + Vector2(6.0, 0.0), color, 2.0, true) draw_line(center + Vector2(0.0, -6.0), center + Vector2(0.0, 6.0), color, 2.0, true) "confirm": draw_polyline(PackedVector2Array([center + Vector2(-7.0, 0.0), center + Vector2(-2.0, 5.0), center + Vector2(8.0, -6.0)]), color, 2.2, true) "compare": draw_line(center + Vector2(-8.0, -4.0), center + Vector2(6.0, -4.0), color, 1.8, true) draw_polyline(PackedVector2Array([center + Vector2(2.0, -8.0), center + Vector2(7.0, -4.0), center + Vector2(2.0, 0.0)]), color, 1.8, true) draw_line(center + Vector2(8.0, 4.0), center + Vector2(-6.0, 4.0), color, 1.8, true) draw_polyline(PackedVector2Array([center + Vector2(-2.0, 0.0), center + Vector2(-7.0, 4.0), center + Vector2(-2.0, 8.0)]), color, 1.8, true) "retry": draw_arc(center, 7.0, -PI * 0.15, PI * 1.45, 18, color, 1.8, true) draw_polyline(PackedVector2Array([center + Vector2(-8.0, -4.0), center + Vector2(-8.0, 3.0), center + Vector2(-2.0, 2.0)]), color, 1.8, true) "settings": draw_arc(center, 5.0, 0.0, TAU, 18, color, 1.7, true) draw_circle(center, 1.5, color) for angle in range(0, 360, 90): var direction := Vector2.RIGHT.rotated(deg_to_rad(float(angle))) draw_line(center + direction * 6.0, center + direction * 8.0, color, 1.7, true) _: if kind != "tool": _draw_crest(center, 7.0, color) 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) func _ellipse_points(center: Vector2, radius_x: float, radius_y: float) -> PackedVector2Array: var points := PackedVector2Array() for index in range(32): var angle := TAU * float(index) / 32.0 points.append(center + Vector2(cos(angle) * radius_x, sin(angle) * radius_y)) return points