134 lines
5.7 KiB
GDScript
134 lines
5.7 KiB
GDScript
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 = {}
|
|
|
|
func _ready() -> void:
|
|
custom_minimum_size = Vector2(330, 300)
|
|
resized.connect(_build)
|
|
_build()
|
|
|
|
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 = learned or not unlocked or progress.analysis_samples < DATA.cost(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"
|
|
button.tooltip_text = DATA.title(id) + "\n" + DATA.description(id) + "\n" + status
|
|
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)
|
|
|