This commit is contained in:
Marek Lenczewski
2026-03-30 22:56:58 +02:00
parent d6715e9c3f
commit 04749104a0
49 changed files with 1406 additions and 171 deletions

252
plan.md
View File

@@ -1,8 +1,9 @@
# Projektstruktur
## Szenenbaum
- Welt
- Taverne
- Player
- Portal
- Portale (dynamisch)
- Gegner
- HUD
@@ -10,23 +11,26 @@
- Zwischen Szenen: Kommunikation über EventBus (Szenen kennen sich nicht)
- Innerhalb einer Szene: Modulare Skripte, Zugriff auf Geschwister-Nodes erlaubt
## Szenen
- world.tscn — Hauptszene
## Welt
- world.tscn — Hauptszene (200x200m)
- NavigationRegion3D (Wegfindung für Gegner)
- Boden (MeshInstance3D, 20x20m PlaneMesh, Gras-Noise-Textur)
- Boden (MeshInstance3D, 200x200m PlaneMesh, Gras-Noise-Textur)
- Kollision (StaticBody3D, WorldBoundaryShape3D)
- Licht (DirectionalLight3D, 45°, Schatten)
- Spieler (Instanz von player.tscn)
- Portal (Instanz von portal.tscn)
- Taverne (StaticBody3D, BoxMesh, Mitte der Karte, Spieler-Spawn/Respawn)
- Spieler (Instanz von player.tscn, Spawn bei Taverne)
- PortalSpawner (Node, portal_spawner.gd)
- HUD (Instanz von hud.tscn)
- portal_spawner.gd — Spawnt Portale dynamisch in der Portalzone (außerhalb Dorfradius)
- Timer-basiert, zufällige Position, max. Anzahl begrenzt
- player.tscn — Spieler
## Spieler
- player.tscn — CharacterBody3D
- Gruppe (player)
- CharacterBody3D (player.gd)
- Kollision (CapsuleShape3D, 1.8m x 0.3m)
- Mesh (CapsuleMesh)
- CameraPivot (Node3D, Kopfhöhe, camera.gd)
- Camera3D (hinter/über Spieler)
- Camera3D (hinter/über Spieler)w
- Movement (Node, movement.gd)
- Combat (Node, combat.gd)
- Role (Node, role.gd)
@@ -34,36 +38,51 @@
- Health (Node, health.gd)
- Shield (Node, shield.gd)
- Respawn (Node, respawn.gd)
- player.gd — Kern, verbindet Komponenten
- camera.gd — LMB freies Umsehen, RMB Kamera + Laufrichtung anpassen
- movement.gd — Bewegung (WASD relativ zur Kamera), Springen, Schwerkraft
- respawn.gd — Bei Tod: Spieler deaktivieren, 3s Timer, Respawn bei Taverne, Leben/Schild voll
- player_stats.tres — health=100, regen=1/s, shield=50, delay=3s, regen_time=5s
- hud.tscn — HUD (eigene Szene, kommuniziert nur über Events)
- CanvasLayer (hud.gd)
- HealthBar (ProgressBar, links oben)
- ShieldBar (ProgressBar, links oben, unter HealthBar)
- RespawnTimer (Label, mitte, Countdown bei Tod)
- AbilityBar (HBoxContainer, mitte unten)
- RoleIcon (Label, T=Tank, D=Schaden, H=Heiler)
- Abilities(Label, Fähigkeiten 1-4, Passive P)
## Kampf
- combat.gd — Führt Abilities aus, verwaltet Cooldowns (GCD 0.5s), Auto-Attack (0.5s)
- targeting.gd — Klick/TAB anvisieren (Gruppen "enemies" + "portals"), Kampfmodus bei Gegner-Angriff, Auto-Targeting (Gegner > Portal)
- role.gd — Rollenwechsel ALT+1 bis ALT+3 (Tank/Schaden/Heiler), tauscht AbilitySet
- portal.tscn — Portal (Gegner-Spawner, anvisierbar)
- Gruppe (portals)
- StaticBody3D (portal.gd)
- Kollision (CylinderShape3D)
- Mesh (CylinderMesh, blau)
- Health (Node, health.gd)
- HitArea (Area3D, Trefferbereich)
- CollisionShape3D
- Spawner (Node, spawner.gd)
- DetectionArea (Area3D, 10m Radius, Auto-Targeting bei Betreten)
- CollisionShape3D (SphereShape3D)
- Healthbar (Sprite3D + SubViewport, healthbar.gd)
- Phase 1: Angreifbar, HP-Bar, spawnt 3 Gegner bei 85%/70%/55%/40%/25%/10% Leben
- Portal = Spawnpunkt, 10m Aggro-Radius
- Phase 2 (geplant): Bei 0 HP → Portal wird Gate, teleportiert in Dungeon
- Abgesperrter Bereich mit Gegner-Gruppen und Boss
## Abilities
- ability.gd (Resource) — name, type, damage, range, cooldown, uses_gcd, execute()
- ability_set.gd (Resource) — Set von 5 Abilities pro Rolle
- ability_modifier.gd (Resource) — Verändert Ability (Element, Beruf, Prestige)
- Typen: Single, AOE, Utility, Ult, Passive
- Auto-Attack: Automatisch bei anvisiertem Gegner im Kampf
- Schadens-Klasse:
- AA: 10 Schaden, 10m
- 1 Single: 30 Schaden, 20m Range, 2s CD, GCD
- 2 AOE: 20 Schaden, 5m Range, 3s CD, GCD
- 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD
- 4 Ult: 5x Single (50 Schaden) + 2x AOE 3m (20 Schaden), 20m Range, 15s CD, GCD
- 5 Passive: 50% mehr Schaden Aura, 50m (permanent aktiv, kein CD)
- Tank-Klasse:
- AA: 5 Schaden, 3m
- 1 Single: 15 Schaden, 3m Range, 2s CD, GCD
- 2 AOE: 10 Schaden, 10m Range, 3s CD, GCD
- 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD
- 4 Ult: Schild 300%, 20s CD, GCD
- 5 Passive: 50% mehr Schild Aura, 50m (permanent aktiv, kein CD)
- Heiler-Klasse: Kein Autotarget, Anvisierter Spieler wird geheilt, ist keiner anvisiert dann Selfheal
- AA: 1 Heilung, 20m
- 1 Single: 15 Heilung, 20m Range, 2s CD, GCD
- 2 AOE: 10 Heilung, 20m Range, 3s CD, GCD
- 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD
- 4 Ult: 25 Heal Single + 10 AOE Heal 3m radius, 20m Range, 15s CD, GCD
- 5 Passive: 50% mehr Heal Aura, 50m (permanent aktiv, kein CD)
- Jede Rolle hat ein eigenes AbilitySet
- Beim Rollenwechsel wird das AbilitySet getauscht
- Elemente und Modifikatoren verändern Abilities nachträglich
- enemy.tscn — Gegner
## Gegner
- enemy.tscn — CharacterBody3D
- Gruppe (enemies)
- CharacterBody3D (enemy.gd)
- Kollision (CapsuleShape3D)
- Mesh (SphereMesh, Platzhalter)
- Health (Node, health.gd)
@@ -81,74 +100,119 @@
- Border (ColorRect, gelb, sichtbar bei Anvisierung)
- HealthBar (ProgressBar, grün)
- ShieldBar (ProgressBar, blau)
## Skripte
- player.gd — Kern, verbindet Komponenten
- camera.gd — LMB freies Umsehen, RMB Kamera + Laufrichtung anpassen
- movement.gd — Bewegung (WASD relativ zur Kamera), Springen, Schwerkraft
- combat.gd — Führt Abilities aus, verwaltet Cooldowns (GCD 0.5s), Auto-Attack (10 Schaden, 1s, 20m)
- targeting.gd — Klick/TAB anvisieren (Gruppen "enemies" + "portals"), Kampfmodus bei Gegner-Angriff, Auto-Targeting (Gegner > Portal)
- event_bus.gd — Autoload-Singleton, globale Signals
- role.gd — Rollenwechsel ALT+1 bis ALT+3 (Tank/Schaden/Heiler), tauscht AbilitySet
- respawn.gd — Bei Tod: Spieler deaktivieren, 3s Timer, Respawn am Startpunkt, Leben/Schild voll
- hud.gd — Reagiert auf Events, aktualisiert HealthBar/ShieldBar/AbilityBar/RespawnTimer
- portal.gd — Portal-Kern, Gruppe "portals", stirbt bei 0 HP, kein Kampf/Aggro/State
- enemy.gd — Gegner-Kern, State Machine (Idle, Verfolgen, Angreifen, Zurückkehren), alarmiert Gegner in 3m, Gruppe "enemies"
- enemy_movement.gd — Navigation zum Ziel/Spawnpunkt
- enemy_combat.gd — Angriff über Event (damage_requested)
- enemy_aggro.gd — Aggro-Tabelle (Spieler → Wert), wählt Ziel mit höchstem Aggro
- enemy_stats.tres — health=100, regen=0, shield=50, delay=3s, regen_time=5s
- Aggro-Regeln:
- Schaden = Aggro (1:1)
- Heilung = Aggro (0.5x)
- Tank = Aggro-Multiplikator (2x)
- Aggro verfällt -1/s
- Spieler im Portal-Radius: Aggro bleibt bei mindestens 1
- Außerhalb 10m Portal-Radius: Aggro verfällt 1% * 2 je s (1%, 2%, 4%, 8%, ...)
- Ohne Aggro: Gegner kehrt zum Portal zurück, regeneriert 10% Leben/s bis 100%, dann 1%/s
- Bei Spieler-Tod → Aggro auf 0
## Components (scripts/components/, wiederverwendbar)
## Portal
- portal.tscn — StaticBody3D
- Gruppe (portals)
- Kollision (CylinderShape3D)
- Mesh (CylinderMesh, blau)
- Health (Node, health.gd)
- HitArea (Area3D, Trefferbereich)
- CollisionShape3D
- Spawner (Node, spawner.gd)
- DetectionArea (Area3D, 10m Radius, Auto-Targeting bei Betreten)
- CollisionShape3D (SphereShape3D)
- Healthbar (Sprite3D + SubViewport, healthbar.gd)
- portal.gd — Portal-Kern, Gruppe "portals", bei 0 HP → spawnt Gate, zerstört Gegner und sich
- spawner.gd — Spawnt Entities bei Lebensschwellen, engagt Spieler im Portal-Radius sofort
- portal_stats.tres — health=500, regen=1%/s, shield=0
- Phase 1: Angreifbar, HP-Bar, spawnt 3 Gegner bei 85%/70%/55%/40%/25%/10% Leben
- Portal = Spawnpunkt, 10m Aggro-Radius
## Gate
- gate.tscn — StaticBody3D (keine Kollision)
- Mesh (CylinderMesh, grün, leuchtend)
- GateArea (Area3D, 3m Radius, Spieler-Erkennung)
- CollisionShape3D (SphereShape3D)
- gate.gd — Konfigurierbar: target_scene, is_exit
- Eingangs-Gate: Prüft nach 0.5s ob Spieler bereits in GateArea steht, speichert Portal-Position
- Exit-Gate: 1s Aktivierungsdelay (verhindert Re-Triggern bei Spawn)
- Beide Gates bestehen solange Boss lebt, verschwinden bei dungeon_cleared
## Dungeon
- dungeon.tscn — Geschlossener Raum (15x90m, Wände, dunkles Licht)
- NavigationRegion3D (Wegfindung)
- Boden (PlaneMesh, dunkle Textur)
- 4 Wände (StaticBody3D + BoxMesh, 3m hoch)
- Spieler (Instanz von player.tscn, Position 0/1/-5)
- HUD (Instanz von hud.tscn)
- Gegnergruppen bei (15x15, 15x30, 15x45, 15x60), je 4 Gegner
- Boss (Instanz von boss.tscn)
- Exit-Gate (Instanz von gate.tscn, is_exit=true, Ecke bei -6/0/-4)
- DungeonManager (Node, dungeon_manager.gd)
- dungeon_manager.gd — Stellt Spieler wieder her, erkennt Boss-Tod, 2s Delay, dungeon_cleared, zurück zur Taverne
## Boss
- boss.tscn — CharacterBody3D (boss.gd)
- Gruppe (enemies, boss)
- Kollision (CapsuleShape3D, größer als Enemy)
- Mesh (SphereMesh, lila, 1.5x Größe)
- Health (Node, health.gd, boss_stats.tres)
- Shield (Node, shield.gd, boss_stats.tres)
- HitArea, DetectionArea, NavigationAgent3D, EnemyMovement, EnemyCombat, EnemyAggro
- Healthbar (Sprite3D + SubViewport, healthbar.gd)
- boss.gd — Erbt von enemy.gd, Gruppe "boss"
- boss_stats.tres — health=500, regen=0, shield=100, delay=5s, regen_time=8s
## GameState
- game_state.gd — Autoload, speichert Spielerzustand zwischen Szenenwechseln
- save_player(player), restore_player(player), clear_player(), clear()
- returning_from_dungeon — Spieler kommt aus Dungeon, spawnt bei Gate-Position
- dungeon_cleared — Boss tot, Gates werden entfernt, Spieler spawnt bei Taverne
- portal_position (Vector3, Position des Gates für Rückkehr + Wiederherstellung)
## Gemeinsame Komponenten
- health.gd — Leben, Regeneration, Tod bei 0 (liest Base-Werte aus EntityStats)
- shield.gd — Schild, Regeneration nach Delay (liest Base-Werte aus EntityStats)
- healthbar.gd — Liest Health/Shield (optional) vom Parent, gelber Rand bei Anvisierung, blauer Lebensbalken wenn Spieler Ziel ist (nur bei Gegnern)
- spawner.gd — Spawnt Entities bei Lebensschwellen, engagt Spieler im Portal-Radius sofort
## Stats (Resources)
- entity_stats.gd (Resource) — max_health, health_regen, max_shield, shield_regen_delay, shield_regen_time
- player_stats.tres — health=100, regen=1/s, shield=50, delay=3s, regen_time=5s
- enemy_stats.tres — health=100, regen=0, shield=50, delay=3s, regen_time=5s
- portal_stats.tres — health=500, regen=0, shield=0
## Aggro
- Schaden = Aggro (1:1)
- Heilung = Aggro (0.5x)
- Tank = Aggro-Multiplikator (2x)
- Aggro verfällt -1/s
- Spieler im Portal-Radius: Aggro bleibt bei mindestens 1
- Außerhalb 10m Portal-Radius: Aggro verfällt 1% * 2 je s (1%, 2%, 4%, 8%, ...)
- Ohne Aggro: Gegner kehrt zum Portal zurück, regeneriert 10% Leben/s bis 100%, dann 1%/s
- Bei Spieler-Tod → Aggro auf 0
## Abilities (Resources)
- ability.gd (Resource) — name, type, damage, range, cooldown, uses_gcd, execute()
- ability_set.gd (Resource) — Set von 5 Abilities pro Klasse
- ability_modifier.gd (Resource) — Verändert Ability (Element, Beruf, Prestige)
- Typen: Single, AOE, Utility, Ult, Passive
- Auto-Attack: 10 Schaden, 1s, automatisch bei anvisiertem Gegner im Kampf
- Schadens-Klasse:
- 1 Single: 30 Schaden, 20m Range, 1s CD, GCD
- 2 AOE: 20 Schaden, 5m Range, 3s CD, GCD
- 3 Utility: Schild sofort auf 100%, 5s CD, kein GCD
- 4 Ult: 5x Single (50 Schaden) + 2x AOE 3m (20 Schaden), 20m Range, 15s CD, GCD
- 5 Passive: 50% mehr Schaden (permanent aktiv, kein CD)
- Jede Rolle hat ein eigenes AbilitySet
- Beim Rollenwechsel wird das AbilitySet getauscht
- Elemente und Modifikatoren verändern Abilities nachträglich
## HUD
- hud.tscn — CanvasLayer (hud.gd)
- HealthBar (ProgressBar, links oben, Label "50/100")
- ShieldBar (ProgressBar, links oben, unter HealthBar, Label "25/50")
- RespawnTimer (Label, mitte, Countdown bei Tod)
- AbilityBar (HBoxContainer, mitte unten)
- RoleIcon (Label, T=Tank, D=Schaden, H=Heiler)
- Abilities (Label, Fähigkeiten 1-4, Passive P)
- hud.gd — Reagiert auf Events, aktualisiert HealthBar/ShieldBar/AbilityBar/RespawnTimer
## Events
- attack_executed(attacker, position, direction, damage) — Angriff wurde ausgeführt
- damage_dealt(attacker, target, damage) — Schaden wurde verteilt
- damage_requested(attacker, target, amount) — Schaden zwischen Szenen anfordern
- entity_died(entity) — Entity ist gestorben
- shield_broken(entity) — Schild ist auf 0 gefallen
- shield_regenerated(entity) — Schild ist wieder voll
- target_changed(player, target) — Spieler hat neues Ziel anvisiert
- player_respawned(player) — Spieler ist respawnt
- role_changed(player, role_type) — Spieler hat Rolle gewechselt
- health_changed(entity, current, max) — Leben hat sich verändert
- shield_changed(entity, current, max) — Schild hat sich verändert
- respawn_tick(timer) — Respawn-Countdown Update
- enemy_engaged(enemy, target) — Gegner hat Spieler anvisiert
- cooldown_tick(cooldowns, max_cooldowns, gcd_timer) — Cooldown-Update für HUD
- portal_spawn(portal, enemies) — Portal hat Gegner gespawnt
- event_bus.gd — Autoload-Singleton, globale Signals
- Kampf:
- attack_executed(attacker, position, direction, damage) — Angriff wurde ausgeführt
- damage_dealt(attacker, target, damage) — Schaden wurde verteilt
- damage_requested(attacker, target, amount) — Schaden zwischen Szenen anfordern
- Entity:
- entity_died(entity) — Entity ist gestorben
- health_changed(entity, current, max) — Leben hat sich verändert
- shield_changed(entity, current, max) — Schild hat sich verändert
- shield_broken(entity) — Schild ist auf 0 gefallen
- shield_regenerated(entity) — Schild ist wieder voll
- Spieler:
- target_changed(player, target) — Spieler hat neues Ziel anvisiert
- player_respawned(player) — Spieler ist respawnt
- role_changed(player, role_type) — Spieler hat Rolle gewechselt
- respawn_tick(timer) — Respawn-Countdown Update
- cooldown_tick(cooldowns, max_cooldowns, gcd_timer) — Cooldown-Update für HUD
- Gegner:
- enemy_engaged(enemy, target) — Gegner hat Spieler anvisiert
- Portal:
- portal_spawn(portal, enemies) — Portal hat Gegner gespawnt
- portal_defeated(portal) — Portal besiegt, wird Gate
- Dungeon:
- dungeon_cleared() — Boss tot, Dungeon gesäubert