This commit is contained in:
team3
2026-09-16 13:21:45 +02:00
parent 8a188c5d5c
commit 49e8f2d95e
27 changed files with 1772 additions and 265 deletions

View File

@@ -43,6 +43,42 @@ const PROFILE_HINT := {
Element.BLITZ: "kritisch", Element.ERDE: "zäh und langsam", Element.EIS: "robust",
}
# Das Hauptelement gibt der Fähigkeit ihre Form. Gilt für jede Rolle:
# ein Feuer-Heiler brennt, ein Erde-Tank erschüttert, ein Eis-Schütze friert.
const ELEMENT_FORM := {
Element.FEUER: {"name": "Flächenbrand", "desc": "trifft auch Nachbarn des Ziels (60%) und entzündet sie"},
Element.WASSER: {"name": "Welle", "desc": "gibt Verbündeten im Umkreis 2 je 20 Mana"},
Element.WIND: {"name": "Sturmschritt", "desc": "Verbündete im Umkreis 2 werden 3 s um 25% schneller"},
Element.BLITZ: {"name": "Kette", "desc": "springt auf 2 weitere Gegner (60%)"},
Element.ERDE: {"name": "Erschütterung","desc": "betäubt Gegner neben dem Ziel 0,6 s"},
Element.EIS: {"name": "Frostfeld", "desc": "verlangsamt Gegner um das Ziel 3 s um 30%"},
}
# Bots: wie gierig sie horten und wie gezielt sie jagen.
enum Difficulty { LEICHT, NORMAL, SCHWER }
const DIFFICULTY_NAMES := ["Leicht", "Normal", "Schwer"]
const BOT_GREED := {
Difficulty.LEICHT: [0.6, 0.9], Difficulty.NORMAL: [0.3, 0.8], Difficulty.SCHWER: [0.15, 0.4],
}
# Schere-Stein-Papier. Elemente im Ring: jedes schlägt genau eines und verliert
# gegen genau eines. Rollen als Dreieck. Nur das Hauptelement zählt.
const ELEMENT_BEATS := {
Element.WASSER: Element.FEUER, # Wasser löscht Feuer
Element.FEUER: Element.EIS, # Feuer schmilzt Eis
Element.EIS: Element.WIND, # Eis lähmt Wind
Element.WIND: Element.ERDE, # Wind trägt Erde ab
Element.ERDE: Element.BLITZ, # Erde erdet Blitz
Element.BLITZ: Element.WASSER, # Blitz leitet durch Wasser
}
const ROLE_BEATS := {
Role.TANK: Role.DPS, # Tank hält Schützen aus
Role.DPS: Role.HEILER, # Schütze bricht Heiler
Role.HEILER: Role.TANK, # Heiler überdauert Tank
}
const ELEMENT_COUNTER := 0.20
const ROLE_COUNTER := 0.15
# Multiplikator pro Sternstufe (Index = star - 1).
const STAR_MULT := [1.0, 1.8, 3.24]
const MAX_STAR := 3
@@ -89,6 +125,9 @@ const XP_TABLE := {3: 4, 4: 8, 5: 12, 6: 20, 7: 32, 8: 48}
# --- Planung ---------------------------------------------------------------
const PLAN_SECONDS := 30.0
## Die ersten Runden gehen gegen die Wildnis, damit jeder in Ruhe aufbaut.
const PVE_ROUNDS := 2
const SAVE_PATH := "user://spielstand.json"
# --- Kampf -----------------------------------------------------------------
## Heiler heilen nur Verbündete in dieser Hex-Reichweite.
@@ -164,6 +203,65 @@ static func trait_tier(element: int, count: int) -> int:
return tier
static func beats_element(attacker: int, defender: int) -> bool:
return attacker >= 0 and defender >= 0 and ELEMENT_BEATS.get(attacker, -1) == defender
static func beats_role(attacker: int, defender: int) -> bool:
return ROLE_BEATS.get(attacker, -1) == defender
## Schadensfaktor eines Angreifers gegen einen Verteidiger (Hauptelement und Rolle).
static func counter_multiplier(att_el: int, att_role: int, def_el: int, def_role: int) -> float:
var m := 1.0
if beats_element(att_el, def_el):
m += ELEMENT_COUNTER
elif beats_element(def_el, att_el):
m -= ELEMENT_COUNTER
if beats_role(att_role, def_role):
m += ROLE_COUNTER
elif beats_role(def_role, att_role):
m -= ROLE_COUNTER
return m
## Element, das dieses Element schlägt (das Gegenstück zu ELEMENT_BEATS).
static func beaten_by(element: int) -> int:
for e in ELEMENT_BEATS:
if ELEMENT_BEATS[e] == element:
return e
return -1
static func role_beaten_by(role: int) -> int:
for r in ROLE_BEATS:
if ROLE_BEATS[r] == role:
return r
return -1
## Was die Fähigkeit einer Rolle auf einer Sternstufe tut.
static func star_effect(role: int, star: int) -> String:
match role:
Role.TANK:
return "Schild und spottet 3 Gegner" if star == 2 else "Schild, Spott und 25% Reflexion"
Role.DPS:
return "Ziel plus Splash auf Nachbarn" if star == 2 else "Ziel plus Fläche im Radius 2"
_:
return "heilt 3 Verbündete" if star == 2 else "heilt alle und schildet sie"
## Zusatzwirkung eines Nebenelements.
static func element_effect(element: int) -> String:
match element:
Element.FEUER: return "Brand"
Element.WASSER: return "Mana und stärkere Heilung"
Element.WIND: return "Tempo-Schub"
Element.BLITZ: return "Kettenblitz"
Element.ERDE: return "Betäubung"
_: return "Verlangsamung"
## XP bis zum nächsten Level, 0 auf Maximalstufe.
static func xp_needed(level: int) -> int:
return XP_TABLE.get(level, 0)