class_name Avatar extends RefCounted ## Eine Einheit. Elemente sind leer, solange der Avatar elementlos ist. static var _next_id := 1 var id: int var role: int = Data.Role.DPS var elements: Array[int] = [] var star: int = 1 var invested: int = 0 ## bezahltes Gold (für Verkaufswert) func _init(p_role: int = Data.Role.DPS, p_elements: Array[int] = [], p_star: int = 1) -> void: id = _next_id _next_id += 1 role = p_role elements = p_elements.duplicate() star = p_star func is_elementless() -> bool: return elements.is_empty() func primary_element() -> int: return elements[0] if not elements.is_empty() else -1 func has_element(e: int) -> bool: return elements.has(e) func display_name() -> String: if elements.is_empty(): return "Neutral-" + Data.ROLE_NAMES[role] var parts := [] for e in elements: parts.append(Data.ELEMENT_NAMES[e]) return "/".join(parts) + "-" + Data.ROLE_NAMES[role] func color() -> Color: if elements.is_empty(): return Data.NONE_COLOR return Data.ELEMENT_COLORS[elements[0]] func price() -> int: return Data.PRICE_NONE if elements.is_empty() else Data.PRICE_ELEMENT ## Was zum nächsten Stern fehlt: {element: anzahl}. Leer = maximal. func upgrade_cost() -> Dictionary: if star >= Data.MAX_STAR or elements.is_empty(): return {} var cost := {} if star == 1: # 3 Avatare gesamt: der Basis-Avatar zählt mit, also 2 weitere. cost[elements[0]] = 2 else: # 2-Star -> 3-Star: je 3 Avatare pro vorhandenem Element. for e in elements: cost[e] = 3 return cost func base_stats() -> Dictionary: var b: Dictionary = Data.ROLE_STATS[role] var mult: float = Data.STAR_MULT[star - 1] var ebonus := 1.0 + Data.ELEMENT_STAT_BONUS * float(maxi(0, elements.size() - 1)) var prof: Dictionary = Data.ELEMENT_PROFILE.get(primary_element(), {"hp": 1.0, "atk": 1.0, "armor": 0.0, "aspd": 1.0, "mana": 1.0, "crit": 0.0}) return { "hp": b["hp"] * mult * ebonus * prof["hp"], "atk": b["atk"] * mult * ebonus * prof["atk"], "armor": minf(0.75, b["armor"] + prof["armor"]), "aspd": b["aspd"] * prof["aspd"], "range": b["range"], "mana": b["mana"] * prof["mana"], "crit": prof["crit"], } func duplicate_avatar() -> Avatar: var a := Avatar.new(role, elements, star) a.invested = invested return a ## Beschreibung der Fähigkeit, abhängig von Rolle, Stern und Elementen. func ability_text() -> String: var s := "" match role: Data.Role.TANK: s = "Schild %d für 4s" % int(base_stats()["atk"] * (3.0 + 0.5 * float(star - 1))) if star >= 2: s += ", spottet 3 Gegner" if star >= 3: s += ", 25% Reflexion" Data.Role.DPS: s = "%d Schaden aufs Ziel" % int(base_stats()["atk"] * (3.0 + 0.3 * float(star - 1))) if star == 2: s += " + Splash auf Nachbarn" elif star >= 3: s += " + Fläche (Radius 2)" Data.Role.HEILER: var amount := int(base_stats()["atk"] * (3.0 - 0.25 * float(star - 1))) if star == 1: s = "heilt schwächsten Verbündeten um %d" % amount elif star == 2: s = "heilt 3 Verbündete um %d" % amount else: s = "heilt alle um %d und schildet" % amount if not elements.is_empty(): var f: Dictionary = Data.ELEMENT_FORM[elements[0]] s += "\nForm %s: %s" % [f["name"], f["desc"]] var extra := [] for i in range(1, elements.size()): extra.append(Data.element_effect(elements[i]) + " (halb)") if not extra.is_empty(): s += "\nDazu: " + ", ".join(extra) return s ## „Stark gegen … · Schwach gegen …" aus Hauptelement und Rolle. func counter_text() -> String: var e := primary_element() var strong := [] var weak := [] if e >= 0: strong.append(Data.ELEMENT_NAMES[Data.ELEMENT_BEATS[e]]) weak.append(Data.ELEMENT_NAMES[Data.beaten_by(e)]) strong.append(Data.ROLE_NAMES[Data.ROLE_BEATS[role]]) weak.append(Data.ROLE_NAMES[Data.role_beaten_by(role)]) return "Stark gegen %s · Schwach gegen %s" % [", ".join(strong), ", ".join(weak)]