# Hurry Curry! - a game about cooking # Copyright (C) 2025 Hurry Curry! contributors # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, version 3 of the License only. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # extends Control @export var radius: float = 150 @export var pie_squish: float = 0.6 @export var font: Font const circle_res := 128. var current_class := "Node" var data = {} var class_lookup = {} var offset = 0. var font_size = radius / 10 var sorted := [] var total = 0 func _ready(): custom_minimum_size = get_draw_size() func _process(_dt): setup_counters() traverse(get_tree().root) sort_counters() queue_redraw() func _input(event: InputEvent): if event is InputEventKey and event.is_pressed(): if Input.is_action_pressed("toggle_debug"): visible = event.as_text_key_label() == "1" current_class = "Node" return if not visible: return var text = event.as_text() if not text.is_valid_int(): return var num = int(text) if num > sorted.size(): return if num == 0: if current_class == "Node": return current_class = ClassDB.get_parent_class(current_class) else: current_class = sorted[num - 1][0] func setup_counters(): class_lookup.clear() data.clear() for c in ClassDB.get_inheriters_from_class(current_class): class_lookup[current_class] = current_class data[current_class] = 0 if ClassDB.get_parent_class(c) == current_class: class_lookup[c] = c data[c] = 0 for c2 in ClassDB.get_inheriters_from_class(c): class_lookup[c2] = c func traverse(node: Node): var cls = node.get_class() if class_lookup.has(cls): data[class_lookup[cls]] += 1 for c in node.get_children(): traverse(c) func sort_counters(): total = 0 sorted.clear() for key in data: if data[key] == 0: continue sorted.append([key, data[key]]) total += data[key] sorted.sort_custom(func(a,b): return a[1] > b[1]) func draw_slice(start: float, end: float, color: Color): var a = PackedVector2Array() a.append(Vector2.ZERO) var res = ceil((end - start) * 128) for i in range(res + 1): var ang = lerpf(start, end, float(i) / res) a.append(Vector2(sin(ang), -cos(ang) * pie_squish) * radius) draw_colored_polygon(a, color) func get_draw_size(): return Vector2(1, 1.5) * radius * 2. func _draw(): draw_rect(Rect2(Vector2.ZERO, get_draw_size()), Color(.1,.1,.1,0.8)) offset = 0. draw_row(0, current_class, total, current_class == "Node") draw_pie() for i in range(sorted.size()): var label = sorted[i][0]; var value = sorted[i][1] draw_row(i + 1, label, value, label == current_class) func draw_pie(): draw_set_transform(Vector2(radius, offset + radius * pie_squish + 10)) var angle = 0. for i in range(sorted.size()): var label = sorted[i][0]; var value = sorted[i][1] var inc = float(value) / float(total) * PI * 2. draw_slice(angle, angle + inc, label_color(i+1, label)) angle += inc offset += radius * 2 * pie_squish + 20 draw_set_transform(Vector2.ZERO) func draw_row(index: int, label: String, value: int, nokb: bool): offset += font_size var color = label_color(index, label) var text_left = "[%d] %s" % [index, label] if nokb: text_left = "[_] %s" % label var text_right = "%3d" % value draw_string(font, Vector2(0., offset), text_left, HORIZONTAL_ALIGNMENT_LEFT, radius * 1.5, font_size, color) draw_string(font, Vector2(radius * 1.5, offset), text_right, HORIZONTAL_ALIGNMENT_LEFT, radius * 0.5, font_size, color) func label_color(i: int, _label: String) -> Color: return Color.from_hsv(fmod(float(i + current_class.hash() & 0xffff) / 3.5, 1.), 0.5, 1.)