saumwacht-godot/scripts/luneraria/ui/components/portrait_rect.gd
Martin Stickelbroeck 1b540f2a55 G3 (Zwischenstand): neues Ingame-HUD; Projekt wechselt nach Unity
Nicht abgenommen: Nach dem ersten Spieltest wurde entschieden, Champions of
Luneraria nach Unity 6 zu portieren. Dieser Stand ist die Referenz für das
HUD im Unity-Projekt (../luneraria-unity).

- HUD neu aus Komponenten mit eigenem Theme, Porträts aus den echten Modellen
  (einmal gerendert, zwischengespeichert), Lane-Übersicht mit deterministischer
  Bedrohung aus öffentlichem Zustand, Bossgrotte, nächste Welle, Ereignisse,
  Minimap mit zusammengefassten Armeen, Held/Items/Talente, Einheitendetails,
  Angriffschampions, Bereit-Sperre, UI-Größe, Team-Formen statt nur Farben
- Privatsphäre über LuneHudModel: fremdes Gold und fremde Entwürfe erscheinen nie
- Keine Regeländerung: Regeln 91/91, M2 73/73, Netz 43/43; verify_g3 715/715;
  verify_m1 38/38 und verify_m2 14/14 mit angepassten UI-Treibern
- Spieltest bis Welle 8 über die echte Oberfläche, Befunde in G3-HUD.md
- HELDEN-KONZEPT.md: vom Projektinhaber vorgegebene Helden (nicht umgesetzt)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:59:55 +02:00

87 lines
3 KiB
GDScript

class_name LunePortraitRect
extends Control
## A real-model portrait on the neutral card background (dark slate gradient, soft floor).
## It asks LunePortraits for the texture and fills in when the render is done.
var model_id: String = ""
var large: bool = false
var dimmed: bool = false:
set(value):
if value != dimmed:
dimmed = value
queue_redraw()
var ring: Color = Color(0, 0, 0, 0):
set(value):
if value != ring:
ring = value
queue_redraw()
## Diagonal hatching over the background (attack champions: temporary units).
var hatch: Color = Color(0, 0, 0, 0):
set(value):
if value != hatch:
hatch = value
queue_redraw()
## Fallen units: a red cross over the portrait.
var crossed: bool = false:
set(value):
if value != crossed:
crossed = value
queue_redraw()
var _texture: Texture2D
var _connected: bool = false
func _init() -> void:
mouse_filter = Control.MOUSE_FILTER_IGNORE
texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
clip_contents = true
func show_model(id: String, is_large: bool = false) -> void:
if id == model_id and is_large == large and _texture != null:
return
model_id = id
large = is_large
var cache: LunePortraits = LunePortraits.shared()
if not _connected:
cache.portrait_ready.connect(_on_ready)
_connected = true
_texture = cache.portrait(id, is_large)
queue_redraw()
func has_portrait() -> bool:
return _texture != null
func _on_ready(key: String) -> void:
if key == LunePortraits.key_for(model_id, large):
_texture = LunePortraits.textures.get(key)
queue_redraw()
func _draw() -> void:
var rect := Rect2(Vector2.ZERO, size)
var top := Color("202b37")
var bottom := Color("0d1218")
draw_polygon(PackedVector2Array([rect.position, Vector2(rect.end.x, rect.position.y), rect.end, Vector2(rect.position.x, rect.end.y)]),
PackedColorArray([top, top, bottom, bottom]))
var floor_points := PackedVector2Array()
for index: int in range(20):
var angle: float = TAU * float(index) / 20.0
floor_points.append(Vector2(size.x * .5 + cos(angle) * size.x * .36, size.y * .88 + sin(angle) * size.y * .06))
draw_colored_polygon(floor_points, Color(0, 0, 0, .35))
if hatch.a > 0.0:
var x: float = -size.y
while x < size.x:
var from := Vector2(maxf(x, 0.0), maxf(0.0, -x))
var to := Vector2(minf(x + size.y, size.x), minf(size.y, size.x - x))
draw_line(from, to, hatch, 2.0)
x += 9.0
if _texture != null:
var edge: float = minf(size.x, size.y)
var target := Rect2((size - Vector2(edge, edge)) * .5, Vector2(edge, edge))
draw_texture_rect(_texture, target, false, Color(1, 1, 1, .45) if dimmed else Color.WHITE)
else:
LuneGlyphs.draw(self, "human", rect.grow(-minf(size.x, size.y) * .22), Color(1, 1, 1, .08))
if ring.a > 0.0:
draw_rect(rect.grow(-1.0), ring, false, 2.0)
if crossed:
var inset: float = minf(size.x, size.y) * .22
draw_line(Vector2(inset, inset), size - Vector2(inset, inset), Color(1, .42, .36, .85), 2.0, true)
draw_line(Vector2(size.x - inset, inset), Vector2(inset, size.y - inset), Color(1, .42, .36, .85), 2.0, true)