update
This commit is contained in:
@@ -1,10 +1,17 @@
|
||||
class_name HudOverlay
|
||||
extends Control
|
||||
|
||||
## Zeichnet Lebens- und Manabalken, Rolle und Sterne über die 3D-Einheiten.
|
||||
## Zeichnet Lebens- und Manabalken, Rolle, Sterne und Schadenszahlen
|
||||
## über die 3D-Einheiten. Spielt außerdem die Kampfgeräusche ab.
|
||||
|
||||
const FLOAT_TIME := 0.9
|
||||
const FLOAT_RISE := 42.0
|
||||
|
||||
var board: BoardView3D = null
|
||||
var sfx: Sfx = null
|
||||
var _font: Font
|
||||
var _floaters: Array = [] ## {"world": Vector3, "text": String, "col": Color, "age": float}
|
||||
var _combat_seen: Combat = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
@@ -13,10 +20,52 @@ func _ready() -> void:
|
||||
set_process(true)
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
func _process(delta: float) -> void:
|
||||
_pull_hits()
|
||||
for f in _floaters:
|
||||
f["age"] += delta
|
||||
_floaters = _floaters.filter(func(f): return f["age"] < FLOAT_TIME)
|
||||
queue_redraw()
|
||||
|
||||
|
||||
## Holt neue Treffer aus dem laufenden Spielerkampf und macht Zahlen und Töne daraus.
|
||||
func _pull_hits() -> void:
|
||||
if board == null or board.game == null:
|
||||
return
|
||||
var c: Combat = board.game.player_combat
|
||||
if c == null or not c.record_hits:
|
||||
_combat_seen = null
|
||||
return
|
||||
if c != _combat_seen:
|
||||
_combat_seen = c
|
||||
_floaters.clear()
|
||||
if c.hits.is_empty():
|
||||
return
|
||||
var my_team := board.game.human_team_in_combat()
|
||||
for h in c.hits:
|
||||
var world := board.world_pos(board.mirror_for_view(h["pos"], my_team))
|
||||
var mine: bool = h["team"] == my_team
|
||||
match h["kind"]:
|
||||
"dmg":
|
||||
_floaters.append({"world": world, "text": str(h["amount"]),
|
||||
"col": Color(1.0, 0.55, 0.45) if mine else Color(1.0, 0.95, 0.85), "age": 0.0})
|
||||
if sfx: sfx.play("treffer")
|
||||
"crit":
|
||||
_floaters.append({"world": world, "text": str(h["amount"]) + "!",
|
||||
"col": Color(1.0, 0.85, 0.3), "age": 0.0})
|
||||
if sfx: sfx.play("krit")
|
||||
"heal":
|
||||
_floaters.append({"world": world, "text": "+" + str(h["amount"]),
|
||||
"col": Color(0.55, 1.0, 0.6), "age": 0.0})
|
||||
if sfx: sfx.play("heilung")
|
||||
"cast":
|
||||
if sfx: sfx.play("zauber")
|
||||
"attack":
|
||||
var from := board.world_pos(board.mirror_for_view(h["from"], my_team))
|
||||
board.spawn_attack(from, world, h["ranged"], Data.ELEMENT_COLORS[h["element"]])
|
||||
c.hits.clear()
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
if board == null or board.camera == null:
|
||||
return
|
||||
@@ -30,7 +79,6 @@ func _draw() -> void:
|
||||
var a: Avatar = d["avatar"]
|
||||
var side: int = d["side"]
|
||||
|
||||
# Balkenbreite nach Entfernung, damit nahe Einheiten größer wirken.
|
||||
var bw: float = clampf(absf(foot.y - head.y) * 0.85, 26.0, 70.0)
|
||||
var bx := head.x - bw * 0.5
|
||||
var by := head.y - 4.0
|
||||
@@ -41,13 +89,34 @@ func _draw() -> void:
|
||||
draw_rect(Rect2(bx, by + 7.0, bw, 4.0), Color(0.05, 0.05, 0.07, 0.85))
|
||||
draw_rect(Rect2(bx, by + 7.0, bw * clampf(d["mana"], 0.0, 1.0), 4.0),
|
||||
Color(0.35, 0.62, 0.95))
|
||||
# Schild als heller Streifen über dem Lebensbalken.
|
||||
if d.get("shield", 0.0) > 0.0:
|
||||
draw_rect(Rect2(bx, by - 4.0, bw * clampf(d["shield"], 0.0, 1.0), 3.0), Color(0.85, 0.9, 1.0))
|
||||
|
||||
# Sterne
|
||||
for s in a.star:
|
||||
draw_circle(Vector2(bx + bw * 0.5 - 7.0 + 7.0 * float(s), by - 7.0), 2.6,
|
||||
draw_circle(Vector2(bx + bw * 0.5 - 7.0 + 7.0 * float(s), by - 9.0), 2.6,
|
||||
Color(1.0, 0.85, 0.25))
|
||||
# Rolle
|
||||
draw_string(_font, Vector2(bx + bw + 4.0, by + 7.0), Data.ROLE_SHORT[a.role],
|
||||
HORIZONTAL_ALIGNMENT_LEFT, -1, 13, Color(0.9, 0.9, 0.95, 0.9))
|
||||
if d["cast"]:
|
||||
draw_arc(foot, bw * 0.55, 0.0, TAU, 24, Color(1.0, 0.95, 0.5, 0.9), 2.5)
|
||||
# Zustände als kleine Marken neben dem Balken.
|
||||
var marks := []
|
||||
if d.get("burn", false): marks.append(["B", Color(1.0, 0.5, 0.2)])
|
||||
if d.get("slow", false): marks.append(["S", Color(0.6, 0.85, 1.0)])
|
||||
if d.get("stun", false): marks.append(["Z", Color(1.0, 0.9, 0.3)])
|
||||
for i in marks.size():
|
||||
draw_string(_font, Vector2(bx - 12.0 - 11.0 * float(i), by + 7.0), marks[i][0],
|
||||
HORIZONTAL_ALIGNMENT_LEFT, -1, 12, marks[i][1])
|
||||
|
||||
# Schwebende Zahlen
|
||||
for f in _floaters:
|
||||
var t: float = f["age"] / FLOAT_TIME
|
||||
var pos := cam.unproject_position(f["world"] + Vector3(0.0, 1.5, 0.0))
|
||||
pos.y -= t * FLOAT_RISE
|
||||
var col: Color = f["col"]
|
||||
col.a = 1.0 - t * t
|
||||
var size := 15 if f["text"].ends_with("!") else 13
|
||||
draw_string(_font, pos + Vector2(1, 1), f["text"], HORIZONTAL_ALIGNMENT_CENTER, -1, size,
|
||||
Color(0, 0, 0, col.a * 0.8))
|
||||
draw_string(_font, pos, f["text"], HORIZONTAL_ALIGNMENT_CENTER, -1, size, col)
|
||||
|
||||
Reference in New Issue
Block a user