update
This commit is contained in:
345
scripts/hud.gd
345
scripts/hud.gd
@@ -9,16 +9,31 @@ signal pause_changed(paused: bool)
|
||||
|
||||
const ACCENT := Color(1.0, 0.82, 0.32)
|
||||
const DIM := Color(0.62, 0.64, 0.70)
|
||||
const PLAYERS_W := 300.0 ## feste Breite der Übersicht oben rechts
|
||||
## Freie Fläche in der Tischmitte zwischen den Plätzen. Die Würfel der letzten
|
||||
## Wette werden so gross gewählt, dass sie dort hineinpassen.
|
||||
const BID_BOX := Vector2(200.0, 150.0)
|
||||
const TIMER_W := 52.0 ## Breite der Zeitanzeige in der Ansage-Leiste
|
||||
const GRUEN := Color(0.55, 0.84, 0.55) ## vorhandener Würfel beim Aufdecken
|
||||
const ROT := Color(0.94, 0.55, 0.52) ## fehlender Würfel beim Aufdecken
|
||||
|
||||
var root: Control
|
||||
var players_box: VBoxContainer
|
||||
var bid_row: HBoxContainer
|
||||
var hint_label: Label
|
||||
var bid_box: VBoxContainer
|
||||
var bid_name: Label
|
||||
var bid_row: HFlowContainer
|
||||
var boosts_box: VBoxContainer
|
||||
var banner_label: Label
|
||||
var log_label: Label
|
||||
|
||||
var count_spin: SpinBox
|
||||
var count_label: Label
|
||||
var minus_btn: Button
|
||||
var plus_btn: Button
|
||||
var _count := 1
|
||||
var _count_min := 1
|
||||
var _count_max := 30
|
||||
var _bid_count := 0 ## aktuelles Gebot, 0 = noch keins
|
||||
var _bid_face := 0
|
||||
var _min_raise := 1
|
||||
var _actual := 0 ## beim Aufdecken: tatsächlich gefundene Würfel
|
||||
var face_buttons: Array[Button] = []
|
||||
var bid_btn: Button
|
||||
var challenge_btn: Button
|
||||
@@ -53,14 +68,17 @@ class DieIcon extends Control:
|
||||
var value := 0
|
||||
var _box := StyleBoxFlat.new()
|
||||
|
||||
func _init(v: int, px: float = 0.0) -> void:
|
||||
func _init(v: int, px: float = 0.0, bg := Color.TRANSPARENT) -> void:
|
||||
value = v
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
if px > 0.0:
|
||||
custom_minimum_size = Vector2(px, px)
|
||||
# sonst zieht der Container das Symbol in die Höhe und es wird unrund
|
||||
size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
_box.bg_color = Color(0.93, 0.92, 0.88) if v > 0 else Color(0.26, 0.28, 0.34)
|
||||
if bg.a > 0.0:
|
||||
_box.bg_color = bg
|
||||
else:
|
||||
_box.bg_color = Color(0.93, 0.92, 0.88) if v > 0 else Color(0.26, 0.28, 0.34)
|
||||
_box.set_corner_radius_all(4)
|
||||
_box.border_color = Color(0, 0, 0, 0.35)
|
||||
_box.set_border_width_all(1)
|
||||
@@ -141,81 +159,95 @@ func _slot(al: float, at: float, ar: float, ab: float,
|
||||
func _build() -> void:
|
||||
# --- Spielerliste oben rechts
|
||||
var pl := _panel()
|
||||
_place(pl, 1, 0, 1, 0, -16 - PLAYERS_W, 16, -16, 16)
|
||||
_place(pl, 1, 0, 1, 0, -16, 16, -16, 16)
|
||||
pl.grow_horizontal = Control.GROW_DIRECTION_BEGIN
|
||||
pl.custom_minimum_size = Vector2(PLAYERS_W, 0)
|
||||
root.add_child(pl)
|
||||
players_box = VBoxContainer.new()
|
||||
players_box.add_theme_constant_override("separation", 4)
|
||||
players_box.add_theme_constant_override("separation", 6)
|
||||
pl.add_child(players_box)
|
||||
|
||||
# --- Aktuelles Gebot oben mittig
|
||||
var bp := _panel()
|
||||
_slot(0, 0, 1, 0, 300, 12, -300, 120).add_child(bp)
|
||||
var bv := VBoxContainer.new()
|
||||
bp.add_child(bv)
|
||||
bid_row = HBoxContainer.new()
|
||||
bid_row.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
bid_row.add_theme_constant_override("separation", 8)
|
||||
bv.add_child(bid_row)
|
||||
hint_label = _label("", 14, DIM)
|
||||
hint_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
bv.add_child(hint_label)
|
||||
# --- Aktive Booster oben links, Breite richtet sich nach dem Inhalt
|
||||
var bo := _panel()
|
||||
_place(bo, 0, 0, 0, 0, 16, 16, 16, 16)
|
||||
root.add_child(bo)
|
||||
boosts_box = VBoxContainer.new()
|
||||
boosts_box.add_theme_constant_override("separation", 3)
|
||||
bo.add_child(boosts_box)
|
||||
|
||||
# --- Banner in der Bildmitte
|
||||
var banner_slot := _slot(0, 0, 1, 0, 140, 126, -140, 210)
|
||||
# --- Letzte Wette in der Tischmitte, als so viele Würfel wie angesagt
|
||||
var bid_slot := _slot(0, 0, 1, 1, 0, 0, 0, 0)
|
||||
bid_box = VBoxContainer.new()
|
||||
bid_box.add_theme_constant_override("separation", 8)
|
||||
bid_slot.add_child(bid_box)
|
||||
bid_name = _label("", 30, ACCENT)
|
||||
bid_name.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
# Auf die freie Mitte begrenzen, sonst läuft der Text über die Nachbarplätze.
|
||||
bid_name.custom_minimum_size = Vector2(BID_BOX.x, 0)
|
||||
bid_name.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
bid_box.add_child(bid_name)
|
||||
bid_row = HFlowContainer.new()
|
||||
bid_row.alignment = FlowContainer.ALIGNMENT_CENTER
|
||||
bid_row.custom_minimum_size = Vector2(BID_BOX.x, 0)
|
||||
bid_row.add_theme_constant_override("h_separation", 5)
|
||||
bid_row.add_theme_constant_override("v_separation", 5)
|
||||
bid_box.add_child(bid_row)
|
||||
|
||||
# --- Banner oben, im freien Band zwischen den beiden Seitenpanels
|
||||
banner_label = _label("", 28, ACCENT)
|
||||
banner_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
banner_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
banner_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
banner_label.custom_minimum_size = Vector2(1000, 0)
|
||||
banner_slot.add_child(banner_label)
|
||||
banner_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
var edge := 240.0
|
||||
_place(banner_label, 0, 0, 1, 0, edge, 20, -edge, 150)
|
||||
root.add_child(banner_label)
|
||||
|
||||
# --- Verlauf unten links
|
||||
var lp := _panel()
|
||||
_place(lp, 0, 1, 0, 1, 16, -252, 376, -16)
|
||||
root.add_child(lp)
|
||||
log_label = _label("", 13, Color(0.82, 0.84, 0.9))
|
||||
log_label.vertical_alignment = VERTICAL_ALIGNMENT_BOTTOM
|
||||
log_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
|
||||
lp.add_child(log_label)
|
||||
|
||||
# --- Aktionen unten rechts
|
||||
# --- Ansage: kompakte Leiste unten in der Mitte
|
||||
action_panel = _panel()
|
||||
_place(action_panel, 1, 1, 1, 1, -296, -282, -16, -16)
|
||||
action_panel.grow_vertical = Control.GROW_DIRECTION_BEGIN
|
||||
root.add_child(action_panel)
|
||||
var av := VBoxContainer.new()
|
||||
av.add_theme_constant_override("separation", 6)
|
||||
_slot(0, 1, 1, 1, 16, -110, -16, -16).add_child(action_panel)
|
||||
var av := HBoxContainer.new()
|
||||
av.add_theme_constant_override("separation", 16)
|
||||
action_panel.add_child(av)
|
||||
|
||||
var head := HBoxContainer.new()
|
||||
av.add_child(head)
|
||||
var head_title := _label("Deine Ansage", 18, ACCENT)
|
||||
head_title.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
head.add_child(head_title)
|
||||
timer_bid = _label("", 18, DIM)
|
||||
head.add_child(timer_bid)
|
||||
# Gegenstück zur Zeitanzeige am rechten Ende, damit die Leiste symmetrisch
|
||||
# bleibt, auch wenn dort gerade keine Zeit läuft.
|
||||
var spacer := Control.new()
|
||||
spacer.custom_minimum_size = Vector2(TIMER_W, 0)
|
||||
spacer.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
av.add_child(spacer)
|
||||
|
||||
var row := HBoxContainer.new()
|
||||
av.add_child(row)
|
||||
var cl := _label("Anzahl", 15)
|
||||
cl.custom_minimum_size = Vector2(80, 0)
|
||||
row.add_child(cl)
|
||||
count_spin = SpinBox.new()
|
||||
count_spin.min_value = 1
|
||||
count_spin.max_value = 30
|
||||
count_spin.value = 1
|
||||
count_spin.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
row.add_child(count_spin)
|
||||
av.add_child(_label("Anzahl", 15))
|
||||
minus_btn = Button.new()
|
||||
minus_btn.text = "−"
|
||||
minus_btn.custom_minimum_size = Vector2(42, 42)
|
||||
minus_btn.pressed.connect(_step_count.bind(-1))
|
||||
av.add_child(minus_btn)
|
||||
count_label = _label("1", 22)
|
||||
count_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
count_label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
count_label.custom_minimum_size = Vector2(38, 0)
|
||||
av.add_child(count_label)
|
||||
plus_btn = Button.new()
|
||||
plus_btn.text = "+"
|
||||
plus_btn.custom_minimum_size = Vector2(42, 42)
|
||||
plus_btn.pressed.connect(_step_count.bind(1))
|
||||
av.add_child(plus_btn)
|
||||
|
||||
av.add_child(_label("Augenzahl", 15))
|
||||
var frow := HBoxContainer.new()
|
||||
frow.add_theme_constant_override("separation", 4)
|
||||
av.add_child(frow)
|
||||
# Die Auswahl hebt sich sonst kaum vom unbenutzten Knopf ab.
|
||||
var gewaehlt := StyleBoxFlat.new()
|
||||
gewaehlt.bg_color = Color(0.32, 0.26, 0.08)
|
||||
gewaehlt.set_corner_radius_all(6)
|
||||
gewaehlt.border_color = ACCENT
|
||||
gewaehlt.set_border_width_all(2)
|
||||
for f in range(1, 7):
|
||||
var b := Button.new()
|
||||
b.toggle_mode = true
|
||||
b.custom_minimum_size = Vector2(40, 40)
|
||||
b.custom_minimum_size = Vector2(42, 42)
|
||||
b.add_theme_stylebox_override("pressed", gewaehlt)
|
||||
b.add_theme_stylebox_override("hover_pressed", gewaehlt)
|
||||
b.pressed.connect(_on_face.bind(f))
|
||||
var ic := DieIcon.new(f)
|
||||
ic.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
@@ -230,16 +262,22 @@ func _build() -> void:
|
||||
|
||||
bid_btn = Button.new()
|
||||
bid_btn.text = "Ansagen"
|
||||
bid_btn.custom_minimum_size = Vector2(0, 36)
|
||||
bid_btn.custom_minimum_size = Vector2(120, 42)
|
||||
bid_btn.pressed.connect(_on_bid)
|
||||
av.add_child(bid_btn)
|
||||
|
||||
challenge_btn = Button.new()
|
||||
challenge_btn.text = "Anfechten"
|
||||
challenge_btn.custom_minimum_size = Vector2(0, 36)
|
||||
challenge_btn.custom_minimum_size = Vector2(120, 42)
|
||||
challenge_btn.pressed.connect(_on_challenge)
|
||||
av.add_child(challenge_btn)
|
||||
|
||||
timer_bid = _label("", 18, DIM)
|
||||
timer_bid.custom_minimum_size = Vector2(TIMER_W, 0)
|
||||
timer_bid.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
||||
timer_bid.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
||||
av.add_child(timer_bid)
|
||||
|
||||
# --- Booster-Overlay
|
||||
boost_slot = _slot(0, 0, 1, 1, 0, 0, 0, 0)
|
||||
boost_slot.visible = false
|
||||
@@ -303,8 +341,58 @@ func _on_quit() -> void:
|
||||
quit_pressed.emit()
|
||||
|
||||
|
||||
## Ein Gebot muss höher sein als das vorige. Bei gleicher Anzahl geht das nur
|
||||
## über eine höhere Augenzahl - die kleineren werden deshalb ausgeblendet.
|
||||
func _face_allowed(f: int) -> bool:
|
||||
if _bid_count <= 0 or _count >= _bid_count + _min_raise:
|
||||
return true
|
||||
if _min_raise > 1:
|
||||
return false
|
||||
return _count == _bid_count and f > _bid_face
|
||||
|
||||
|
||||
func _refresh_faces() -> void:
|
||||
var first_ok := 0
|
||||
for i in face_buttons.size():
|
||||
var ok := _my_turn and _face_allowed(i + 1)
|
||||
face_buttons[i].disabled = not ok
|
||||
face_buttons[i].modulate = Color(1, 1, 1, 1.0 if ok else 0.3)
|
||||
if ok and first_ok == 0:
|
||||
first_ok = i + 1
|
||||
# Steht die gewählte Augenzahl nicht mehr zur Wahl, auf die kleinste mögliche
|
||||
if _my_turn and first_ok > 0 and not _face_allowed(_face):
|
||||
_on_face(first_ok)
|
||||
|
||||
|
||||
## Beim Drankommen auf das kleinstmögliche Gebot stellen - von dort aus ist es
|
||||
## am wenigsten Klickarbeit bis zur gewünschten Ansage.
|
||||
func _lowest_bid() -> void:
|
||||
if _bid_count <= 0:
|
||||
_set_count(1)
|
||||
_on_face(1)
|
||||
elif _min_raise == 1 and _bid_face < 6:
|
||||
# Gleiche Anzahl reicht, wenn die Augenzahl steigt.
|
||||
_set_count(_bid_count)
|
||||
_on_face(_bid_face + 1)
|
||||
else:
|
||||
_set_count(_bid_count + _min_raise)
|
||||
_on_face(1)
|
||||
|
||||
|
||||
func _step_count(delta: int) -> void:
|
||||
_set_count(_count + delta)
|
||||
|
||||
|
||||
func _set_count(v: int) -> void:
|
||||
_count = clampi(v, _count_min, _count_max)
|
||||
count_label.text = str(_count)
|
||||
minus_btn.disabled = not _my_turn or _count <= _count_min
|
||||
plus_btn.disabled = not _my_turn or _count >= _count_max
|
||||
_refresh_faces()
|
||||
|
||||
|
||||
func _on_bid() -> void:
|
||||
bid_pressed.emit(int(count_spin.value), _face)
|
||||
bid_pressed.emit(_count, _face)
|
||||
|
||||
|
||||
func _on_challenge() -> void:
|
||||
@@ -326,6 +414,14 @@ func _set_paused(on: bool) -> void:
|
||||
pause_changed.emit(on)
|
||||
|
||||
|
||||
## queue_free() nimmt den Knoten erst am Frameende aus dem Baum - bis dahin
|
||||
## lägen alte und neue Einträge nebeneinander im Container.
|
||||
func _clear(box: Node) -> void:
|
||||
for c in box.get_children():
|
||||
box.remove_child(c)
|
||||
c.queue_free()
|
||||
|
||||
|
||||
func _on_face(f: int) -> void:
|
||||
_face = f
|
||||
for i in face_buttons.size():
|
||||
@@ -338,64 +434,96 @@ func update_state(st: Dictionary, my_seat: int) -> void:
|
||||
_my_seat = my_seat
|
||||
_my_values = st.values
|
||||
_phase = st.phase
|
||||
_actual = int(st.get("actual", 0))
|
||||
var left := float(st.get("time_left", 0.0))
|
||||
_deadline = 0.0 if left <= 0.0 else Time.get_ticks_msec() / 1000.0 + left
|
||||
|
||||
for c in players_box.get_children():
|
||||
c.queue_free()
|
||||
_clear(players_box)
|
||||
for i in st.seats.size():
|
||||
var s: Dictionary = st.seats[i]
|
||||
var turn: bool = st.phase == "bid" and i == st.turn
|
||||
var col := ACCENT if turn else (Color.WHITE if s.alive else DIM)
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 4)
|
||||
players_box.add_child(row)
|
||||
var nm := _label(("▸ " if turn else " ") + s.name + (" (KI)" if s.ai else ""), 15, col)
|
||||
# Der Name teilt sich den Rest der festen Panelbreite und wird
|
||||
# notfalls mit Auslassungspunkten gekürzt.
|
||||
nm.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
var entry := VBoxContainer.new()
|
||||
entry.add_theme_constant_override("separation", 2)
|
||||
players_box.add_child(entry)
|
||||
var nm := _label(("▸ " if turn else "") + _short(String(s.name)) + (" (KI)" if s.ai else ""), 14, col)
|
||||
nm.clip_text = true
|
||||
nm.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
||||
row.add_child(nm)
|
||||
entry.add_child(nm)
|
||||
if not s.alive:
|
||||
row.add_child(_label("ausgeschieden", 14, DIM))
|
||||
entry.add_child(_label(" ausgeschieden", 13, DIM))
|
||||
continue
|
||||
var row := HBoxContainer.new()
|
||||
row.add_theme_constant_override("separation", 4)
|
||||
entry.add_child(row)
|
||||
for v: int in _seat_dice(st, i, my_seat):
|
||||
row.add_child(DieIcon.new(v, 22.0))
|
||||
row.add_child(DieIcon.new(v, 21.0))
|
||||
|
||||
for c in bid_row.get_children():
|
||||
c.queue_free()
|
||||
_clear(bid_row)
|
||||
if st.bid.is_empty():
|
||||
bid_row.add_child(_label("Noch kein Gebot", 26, ACCENT))
|
||||
bid_name.text = "Kein Gebot"
|
||||
bid_name.add_theme_color_override("font_color", Color(1, 1, 1, 0.5))
|
||||
else:
|
||||
bid_row.add_child(_label("%s: %d ×" % [st.seats[st.bid.seat].name, st.bid.count], 26, ACCENT))
|
||||
bid_row.add_child(DieIcon.new(int(st.bid.face), 30.0))
|
||||
bid_name.text = String(st.seats[st.bid.seat].name)
|
||||
bid_name.add_theme_color_override("font_color", ACCENT)
|
||||
var px := _fit_dice(int(st.bid.count))
|
||||
# Beim Aufdecken zeigen die Farben, wie viele der angesagten Würfel es
|
||||
# wirklich gab: grün die vorhandenen, rot die fehlenden.
|
||||
var faerben: bool = st.phase == "reveal"
|
||||
for i in int(st.bid.count):
|
||||
var bg := Color.TRANSPARENT
|
||||
if faerben:
|
||||
bg = GRUEN if i < _actual else ROT
|
||||
bid_row.add_child(DieIcon.new(int(st.bid.face), px, bg))
|
||||
|
||||
var hints: Array = []
|
||||
hints.append("Würfel im Spiel: %d" % st.total)
|
||||
if st.boost != "":
|
||||
hints.append("Dein Booster: %s" % BoosterDB.get_booster(st.boost).get("name", ""))
|
||||
_clear(boosts_box)
|
||||
var boosts: Array = st.get("boosts", [])
|
||||
var any := false
|
||||
for i in mini(boosts.size(), st.seats.size()):
|
||||
if String(boosts[i]) == "":
|
||||
continue
|
||||
any = true
|
||||
var b: Dictionary = BoosterDB.get_booster(String(boosts[i]))
|
||||
var line := HBoxContainer.new()
|
||||
line.add_theme_constant_override("separation", 5)
|
||||
boosts_box.add_child(line)
|
||||
line.add_child(_label(_short(String(st.seats[i].name)) + ":", 14,
|
||||
ACCENT if i == my_seat else Color(0.78, 0.80, 0.86)))
|
||||
var kind := Color(0.5, 0.9, 0.6) if b.kind == BoosterDB.Kind.BUFF else Color(0.95, 0.5, 0.5)
|
||||
line.add_child(_label(String(b.get("name", "")), 14, kind))
|
||||
if int(st.min_raise) > 1:
|
||||
hints.append("Störfeuer: du musst um mind. %d erhöhen" % st.min_raise)
|
||||
boosts_box.add_child(_label("Störfeuer: mind. %d erhöhen" % st.min_raise, 14, ACCENT))
|
||||
any = true
|
||||
if st.must_bid:
|
||||
hints.append("Maulkorb: du musst bieten")
|
||||
hint_label.text = " | ".join(hints)
|
||||
boosts_box.add_child(_label("Maulkorb: du musst bieten", 14, ACCENT))
|
||||
any = true
|
||||
if not any:
|
||||
boosts_box.add_child(_label("Keine Booster aktiv", 14, DIM))
|
||||
|
||||
log_label.text = "\n".join(st.log)
|
||||
banner_label.text = st.banner
|
||||
|
||||
var my_turn: bool = st.phase == "bid" and st.turn == my_seat and st.seats[my_seat].alive
|
||||
var kam_dran := my_turn and not _my_turn
|
||||
_my_turn = my_turn
|
||||
action_panel.modulate = Color(1, 1, 1, 1.0 if my_turn else 0.45)
|
||||
bid_btn.disabled = not my_turn
|
||||
challenge_btn.disabled = not my_turn or st.bid.is_empty() or st.must_bid
|
||||
count_spin.max_value = maxi(1, int(st.total))
|
||||
_count_max = maxi(1, int(st.total))
|
||||
_min_raise = maxi(1, int(st.min_raise))
|
||||
_bid_count = 0 if st.bid.is_empty() else int(st.bid.count)
|
||||
_bid_face = 0 if st.bid.is_empty() else int(st.bid.face)
|
||||
# Ein Maulkorb sperrt das Anfechten - ausser es gäbe gar kein gültiges
|
||||
# Gebot mehr, dann bliebe sonst kein einziger Knopf übrig.
|
||||
var gebot_moeglich: bool = _bid_count + _min_raise <= _count_max \
|
||||
or (_min_raise == 1 and _bid_face < 6)
|
||||
challenge_btn.disabled = not my_turn or st.bid.is_empty() \
|
||||
or (st.must_bid and gebot_moeglich)
|
||||
var low := 1
|
||||
if not st.bid.is_empty():
|
||||
low = int(st.bid.count) + (int(st.min_raise) if int(st.min_raise) > 1 else 0)
|
||||
count_spin.min_value = clampi(low, 1, int(count_spin.max_value))
|
||||
if count_spin.value < count_spin.min_value:
|
||||
count_spin.value = count_spin.min_value
|
||||
if _bid_count > 0:
|
||||
low = _bid_count + (_min_raise if _min_raise > 1 else 0)
|
||||
_count_min = clampi(low, 1, _count_max)
|
||||
_set_count(_count)
|
||||
if kam_dran:
|
||||
_lowest_bid()
|
||||
|
||||
if st.phase != "boost":
|
||||
boost_slot.visible = false
|
||||
@@ -423,6 +551,22 @@ func _process(_delta: float) -> void:
|
||||
|
||||
## Eigene Würfel sind bekannt, gegnerische nicht - ausser sie wurden gespäht
|
||||
## oder es wird gerade aufgedeckt.
|
||||
## Lange Namen kürzen, damit die Panels nicht in die Breite laufen.
|
||||
func _short(name: String) -> String:
|
||||
return name if name.length() <= 12 else name.substr(0, 11) + "…"
|
||||
|
||||
|
||||
## Grösste Würfelgrösse, bei der `n` Würfel noch in die freie Mitte passen.
|
||||
func _fit_dice(n: int) -> float:
|
||||
const GAP := 4.0
|
||||
for px: float in [34.0, 30.0, 26.0, 22.0, 18.0, 15.0, 12.0]:
|
||||
var per_row := maxi(1, int((BID_BOX.x + GAP) / (px + GAP)))
|
||||
var rows := ceili(float(n) / per_row)
|
||||
if rows * (px + GAP) - GAP <= BID_BOX.y:
|
||||
return px
|
||||
return 12.0
|
||||
|
||||
|
||||
func _seat_dice(st: Dictionary, seat: int, my_seat: int) -> Array:
|
||||
if seat == my_seat:
|
||||
return st.values
|
||||
@@ -451,8 +595,7 @@ func show_booster_offer(ids: Array, values: Array) -> void:
|
||||
_pending_boost = ""
|
||||
target_row.visible = false
|
||||
boost_title.text = "Wähle einen Booster"
|
||||
for c in boost_cards.get_children():
|
||||
c.queue_free()
|
||||
_clear(boost_cards)
|
||||
for id: String in ids:
|
||||
var b: Dictionary = BoosterDB.get_booster(id)
|
||||
var card := _panel(Color(0.10, 0.12, 0.17, 0.98))
|
||||
@@ -482,10 +625,8 @@ func _pick(id: String) -> void:
|
||||
return
|
||||
_pending_boost = id
|
||||
boost_title.text = "%s - welchen Würfel?" % BoosterDB.get_booster(id).name
|
||||
for c in boost_cards.get_children():
|
||||
c.queue_free()
|
||||
for c in target_row.get_children():
|
||||
c.queue_free()
|
||||
_clear(boost_cards)
|
||||
_clear(target_row)
|
||||
for i in _my_values.size():
|
||||
var b := Button.new()
|
||||
b.custom_minimum_size = Vector2(56, 56)
|
||||
|
||||
Reference in New Issue
Block a user