This commit is contained in:
team3
2026-09-16 12:09:33 +02:00
parent 9410d18ea5
commit 8a188c5d5c
29 changed files with 2016 additions and 564 deletions

View File

@@ -47,6 +47,8 @@ class CUnit extends RefCounted:
var target = null
var cast_flash: float = 0.0
var hit_flash: float = 0.0
var dealt: float = 0.0 ## ausgeteilter Schaden, für den Rückblick
var healed: float = 0.0
func effective_aspd() -> float:
return maxf(0.1, aspd * (1.0 + haste) * (1.0 - slow))
@@ -57,7 +59,12 @@ var time: float = 0.0
var finished: bool = false
var winner: int = -1 ## 0 = Team A, 1 = Team B, -1 = unentschieden
var survivors: int = 0
var survivor_stars: int = 0 ## Sternsumme der Überlebenden, bestimmt den Schaden
var events: Array = [] ## kurze Textmeldungen für das Log
## Treffer, Heilungen und Zauber für Anzeige und Sound. Nur im Spielerkampf
## aufgezeichnet, Bot-Kämpfe laufen still durch.
var record_hits: bool = false
var hits: Array = []
var _mods := [{}, {}]
var _occ := {}
@@ -116,7 +123,7 @@ func _spawn(p: PlayerState, team: int) -> void:
u.max_mana = s["mana"]
u.mana = 0.0
u.mana_mult = m["mana"]
u.crit = m["crit"]
u.crit = m["crit"] + s.get("crit", 0.0)
if _occ.has(u.pos):
u.pos = _free_near(u.pos)
_occ[u.pos] = u
@@ -266,6 +273,9 @@ func _basic_attack(u: CUnit, t: CUnit) -> void:
var dmg := u.atk
if u.crit > 0.0 and _rand.randf() < u.crit:
dmg *= CRIT_MULT
if record_hits:
hits.append({"kind": "attack", "pos": t.pos, "from": u.pos, "team": u.team,
"ranged": u.atk_range > 1, "element": u.avatar.primary_element(), "amount": 0, "t": time})
_apply_damage(u, t, dmg, false)
var ice: float = _mods[u.team]["ice"]
if ice > 0.0:
@@ -291,6 +301,10 @@ func _apply_damage(src, tgt: CUnit, amount: float, is_true: bool) -> void:
if dmg > 0.0:
tgt.hp -= dmg
tgt.hit_flash = 0.12
if src != null:
src.dealt += dmg
if record_hits and src != null:
_record("crit" if amount > src.atk * 1.4 and not is_true else "dmg", tgt, dmg)
tgt.mana += MANA_PER_HIT * tgt.mana_mult
if tgt.mana >= tgt.max_mana and tgt.alive and tgt.hp > 0.0:
_cast(tgt)
@@ -319,8 +333,17 @@ func _kill(u: CUnit) -> void:
func _heal(u: CUnit, amount: float) -> void:
if u.alive:
u.hp = minf(u.max_hp, u.hp + amount)
if not u.alive:
return
var real := minf(u.max_hp, u.hp + amount) - u.hp
u.hp += real
u.healed += real
if record_hits and real >= 1.0:
_record("heal", u, real)
func _record(kind: String, u: CUnit, amount: float) -> void:
hits.append({"kind": kind, "pos": u.pos, "team": u.team, "amount": int(round(amount)), "t": time})
# --- Fähigkeiten ----------------------------------------------------------
@@ -328,6 +351,8 @@ func _heal(u: CUnit, amount: float) -> void:
func _cast(u: CUnit) -> void:
u.mana = 0.0
u.cast_flash = 0.35
if record_hits:
_record("cast", u, 0.0)
var elems: Array = u.avatar.elements
var heal_bonus := 0.0
for i in elems.size():
@@ -373,7 +398,7 @@ func _cast(u: CUnit) -> void:
hit_enemies.append(o)
Data.Role.HEILER:
var amount := u.atk * (3.0 - 0.25 * float(u.avatar.star - 1)) * (1.0 + heal_bonus)
var allies := _allies_by_missing_hp(u.team)
var allies := _allies_by_missing_hp(u.team, u)
var count := 1
if u.avatar.star == 2:
count = 3
@@ -428,11 +453,14 @@ func _apply_element_effects(u: CUnit, main_target, hit_enemies: Array) -> void:
main_target.slow_timer = maxf(main_target.slow_timer, 3.0)
func _allies_by_missing_hp(team: int) -> Array:
## Verbündete in Heilreichweite, schwächste zuerst. Mindestens der Heiler selbst.
func _allies_by_missing_hp(team: int, healer: CUnit) -> Array:
var list := []
for o in units:
if o.alive and o.team == team:
if o.alive and o.team == team and Hex.distance(o.pos, healer.pos) <= Data.HEAL_RANGE:
list.append(o)
if list.is_empty():
list.append(healer)
list.sort_custom(func(a, b): return (a.hp / a.max_hp) < (b.hp / b.max_hp))
return list
@@ -447,6 +475,40 @@ func alive_count(team: int) -> int:
return n
## Kurzer Rückblick für ein Team: Überlebende, stärkste Einheit, Gegnerspitze.
func recap(team: int) -> Dictionary:
var total := 0
var alive := 0
var best = null
var best_enemy = null
for u in units:
if u.team == team:
total += 1
if u.alive:
alive += 1
if best == null or u.dealt + u.healed > best.dealt + best.healed:
best = u
elif best_enemy == null or u.dealt > best_enemy.dealt:
best_enemy = u
return {
"total": total, "alive": alive,
"best_name": best.avatar.display_name() if best else "-",
"best_dealt": int(best.dealt) if best else 0,
"best_healed": int(best.healed) if best else 0,
"enemy_name": best_enemy.avatar.display_name() if best_enemy else "-",
"enemy_dealt": int(best_enemy.dealt) if best_enemy else 0,
"duration": time,
}
func _star_sum(team: int) -> int:
var n := 0
for u in units:
if u.alive and u.team == team:
n += u.avatar.star
return n
func _check_end() -> void:
var a := alive_count(0)
var b := alive_count(1)
@@ -455,9 +517,11 @@ func _check_end() -> void:
if a == b:
winner = -1
survivors = 0
survivor_stars = 0
else:
winner = 0 if a > b else 1
survivors = maxi(a, b)
survivor_stars = _star_sum(winner)
return
if time >= TIME_LIMIT:
_resolve_by_hp()
@@ -472,6 +536,8 @@ func _resolve_by_hp() -> void:
if absf(frac[0] - frac[1]) < 0.25:
winner = -1
survivors = 0
survivor_stars = 0
else:
winner = 0 if frac[0] > frac[1] else 1
survivors = alive_count(winner)
survivor_stars = _star_sum(winner)