138 lines
3.8 KiB
GDScript
138 lines
3.8 KiB
GDScript
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)]
|