@tool extends Control var depth_m := 0.0 var maximum_depth_m := 1000.0 var knee_m := 1.0 var warning_fraction := 0.8 var fault_fraction := 0.95 var available := false func _ready() -> void: resized.connect(queue_redraw) theme_changed.connect(queue_redraw) # log(1 + depth / knee) includes zero and is nearly linear close to the surface. func normalized_depth(value: float) -> float: var knee := maxf(knee_m, 0.001) var maximum := maxf(maximum_depth_m, 0.001) return log(1 + clampf(value, 0, maximum) / knee) / log(1 + maximum / knee) func severity() -> int: var ratio := depth_m / maxf(maximum_depth_m, 0.001) return 2 if ratio >= fault_fraction else (1 if ratio >= warning_fraction else 0) func _draw() -> void: var top := 9.0 var bottom := maxf(top + 1, size.y - 10) var track := get_theme_color("instrument_grid", "SurfaceSide") var ink := get_theme_color("font_color", "Label") var font := get_theme_default_font() draw_line(Vector2(17, top), Vector2(17, bottom), track, 2, true) var decade := maxf(knee_m, 0.001) while decade < maximum_depth_m: for multiplier in [1.0, 2.0, 5.0]: var tick: float = decade * multiplier if tick > 0 and tick < maximum_depth_m: var y: float = lerpf(top, bottom, normalized_depth(tick)) draw_line(Vector2(14, y), Vector2(21, y), track, 1, true) decade *= 10 var last_label_y := -100.0 var last_label_value := -1.0 var ticks: Array[float] = [0, maxf(knee_m, 0.001) * 2] decade = maxf(knee_m, 0.001) * 10 while decade < maximum_depth_m: ticks.append(decade) decade *= 10 ticks.append(maximum_depth_m) for tick in ticks: if tick < 0 or tick > maximum_depth_m or is_equal_approx(tick, last_label_value): continue var y := lerpf(top, bottom, normalized_depth(tick)) if tick != maximum_depth_m and (y - last_label_y < 20 or (bottom - y < 20 and tick != 0)): continue draw_line(Vector2(12, y), Vector2(23, y), ink, 1, true) draw_string(font, Vector2(29, y + 5), String.num(tick, 3).trim_suffix(".0"), HORIZONTAL_ALIGNMENT_LEFT, -1, 14, ink) last_label_y = y last_label_value = tick if available: var y := lerpf(top, bottom, normalized_depth(depth_m)) var role: String = ["instrument_accent", "warning", "fault"][severity()] var accent := get_theme_color(role, "SurfaceSide") draw_line(Vector2(17, top), Vector2(17, y), accent, 3, true) draw_colored_polygon(PackedVector2Array([Vector2(1, y - 5), Vector2(1, y + 5), Vector2(12, y)]), accent) draw_line(Vector2(12, y), Vector2(23, y), accent, 3, true)