extends Control const DATA := preload("res://scripts/planets/alien_research.gd") const MENU := preload("res://scripts/planets/freighter_menu.gd") const COLORS := [Color("dfb775"), Color("e68c77"), Color("79cba8"), Color("7bc9e6")] const TILE_SIZE := Vector2(36,40) const PLACEHOLDER_LEVELS := 4 const COST_COLUMN_WIDTH := 48.0 var progress: Resource var refreshed: Callable var points: Dictionary = {} var _state := "" func _ready() -> void: custom_minimum_size = Vector2(330, 300) resized.connect(_build) _build() func _process(_delta: float) -> void: var state := str(progress.alien_skills)+str(progress.alien_project)+str(progress.analysis_samples) if state != _state: _state = state _build() if not progress.alien_project.is_empty(): var active_button := get_node_or_null(NodePath(progress.alien_project)) as Button if active_button != null: active_button.tooltip_text = str(active_button.get_meta("base_tooltip",""))+"\n"+("Pozostało: %d s gry" % ceili(progress.alien_remaining)) func _build() -> void: for child in get_children(): remove_child(child) child.queue_free() points.clear() var width := maxf(330, size.x) var tree_width := width-COST_COLUMN_WIDTH _add_row_cost("general",24) _add_row_cost("weapons",80) var row_id := "weapons_a" for level in PLACEHOLDER_LEVELS: _add_row_cost(row_id,142+level*46) row_id += "_next" _add_skill("general", Vector2(COST_COLUMN_WIDTH+tree_width*0.5, 24), COLORS[0]) for i in range(3): var branch: String = DATA.BRANCHES[i] var x := COST_COLUMN_WIDTH+tree_width * (float(i) + 0.5) / 3.0 _add_skill(branch, Vector2(x, 80), COLORS[i + 1]) for path in ["a","b"]: var id: String = branch+"_"+path for level in PLACEHOLDER_LEVELS: var center := Vector2(x+(-22 if path=="a" else 22),142+level*46) if id in DATA.ACTIVE_IDS: _add_skill(id,center,DATA.path_color(id)) else: _add_placeholder(id,center) id += "_next" var caption := MENU.label(self, ["BROŃ", "KADŁUB", "TARCZE"][i], 12, MENU.MUTED) caption.mouse_filter = Control.MOUSE_FILTER_IGNORE caption.position = Vector2(x - 45, 104) caption.size = Vector2(90, 16) caption.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER queue_redraw() func _add_skill(id: String, center: Vector2, color: Color) -> void: points[id] = center var learned: bool = progress.alien_skills.get(id, false) var prerequisite := DATA.parent(id) var unlocked: bool = prerequisite.is_empty() or progress.alien_skills.get(prerequisite, false) var button := MENU.button(self, "", _purchase.bind(id), learned) button.set_script(preload("res://scripts/planets/research_skill_button.gd")) button.name = id button.position = center - TILE_SIZE*0.5 button.size = TILE_SIZE button.disabled = not DATA.can_start(progress,id) if "_" in id: _style_path(button,DATA.path_color(id)) var status := "Zbadano" if learned else "Koszt: %d próbek" % DATA.cost(id) if not unlocked: status += "\nWymaga: " + DATA.title(prerequisite) elif not learned and progress.analysis_samples < DATA.cost(id): status += "\nZa mało próbek" if not learned: status += "\n" + "Czas badania: 10 minut gry" button.tooltip_text = DATA.title(id) + "\n" + DATA.description(id) + "\n" + status button.set_meta("base_tooltip",button.tooltip_text) var icon := TextureRect.new() icon.texture = load("res://assets/freighter/research/" + id + ".png") icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_COVERED icon.texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS icon.mouse_filter = Control.MOUSE_FILTER_IGNORE icon.position = Vector2.ONE icon.size = TILE_SIZE-Vector2(2,2) icon.clip_contents = true if not unlocked: icon.modulate = Color(0.5, 0.55, 0.55, 0.65) button.add_child(icon) if learned: var check := MENU.label(button,"✓",12,color) check.mouse_filter = Control.MOUSE_FILTER_IGNORE check.position = TILE_SIZE-Vector2(13,15) check.size = Vector2(12,12) check.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER func _add_row_cost(id: String, y: float) -> void: var price := MENU.label(self,"%d pkt" % DATA.cost(id),12,MENU.MUTED) price.name = "RowCost_%d" % DATA.cost(id) price.autowrap_mode = TextServer.AUTOWRAP_OFF price.position = Vector2(0,y-10) price.size = Vector2(COST_COLUMN_WIDTH-6,20) price.vertical_alignment = VERTICAL_ALIGNMENT_CENTER price.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER price.tooltip_text = "Koszt każdej technologii w tym rzędzie: %d próbek." % DATA.cost(id) # The initially wrapped label may retain its old minimum height until text is shaped. price.set_deferred("size",Vector2(COST_COLUMN_WIDTH-6,20)) func _add_placeholder(id: String, center: Vector2) -> void: points[id] = center var slot := MENU.button(self, "", func(): pass) slot.name = id slot.disabled = true _style_path(slot,DATA.path_color(id)) slot.focus_mode = Control.FOCUS_NONE slot.mouse_default_cursor_shape = Control.CURSOR_ARROW slot.set_script(preload("res://scripts/planets/research_skill_button.gd")) slot.position = center - TILE_SIZE*0.5 slot.size = TILE_SIZE slot.tooltip_text = "Pusty slot\nMiejsce na przyszłe badanie." var mark := MENU.label(slot, "·", 24, MENU.MUTED) mark.mouse_filter = Control.MOUSE_FILTER_IGNORE mark.position = Vector2(0, 8) mark.size = Vector2(36, 28) mark.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER func _style_path(button: Button, color: Color) -> void: for state in ["normal","hover","pressed","disabled","focus"]: var style := button.get_theme_stylebox(state).duplicate() as StyleBoxFlat style.border_color = color style.set_border_width_all(1) button.add_theme_stylebox_override(state,style) func _purchase(id: String) -> void: if DATA.purchase(progress, id): refreshed.call() func _draw() -> void: for id in points: var prerequisite := DATA.parent(id) if prerequisite.is_empty(): continue var start: Vector2 = points[prerequisite] + Vector2(0,TILE_SIZE.y*0.5) var end: Vector2 = points[id] - Vector2(0,TILE_SIZE.y*0.5) var active: bool = id in DATA.ACTIVE_IDS and progress.alien_skills.get(prerequisite, false) var color := DATA.path_color(id) if "_" in id else (Color("79b9a4") if active else Color("3c5158")) var middle := (start.y + end.y) * 0.5 draw_polyline(PackedVector2Array([start, Vector2(start.x, middle), Vector2(end.x, middle), end]), color, 1.5, true)