Gesperrte Skills im Skillbuch ausgegraut mit Level-Anforderung

- player.gd: alle Krieger-Skills immer in available_skills, locked-Flag
  und level_required Feld; execute_skill bricht bei locked=true ab
- skill_panel.gd: gesperrte Skills ausgegraut, Icon transparent,
  Level-Anforderung angezeigt, kein Drag & Drop moeglich

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Andre 2026-03-19 23:16:09 +01:00
parent c170d98f3c
commit f007e559b9
2 changed files with 93 additions and 65 deletions

102
player.gd
View file

@ -308,53 +308,9 @@ func _init_class_skills():
"icon": "res://assets/Icons/Heavy_Strike.png", "icon": "res://assets/Icons/Heavy_Strike.png",
"cooldown": HEAVY_STRIKE_COOLDOWN, "cooldown": HEAVY_STRIKE_COOLDOWN,
"cast_time": 0.0, "cast_time": 0.0,
"locked": false,
"level_required": 1,
}) })
if level >= 5:
available_skills.append({
"id": "tektonischer_schlag",
"name": "Tektonischer Schlag",
"description": "Erschüttert den Boden um dich herum. Schlägt alle Gegner in der Nähe und verlangsamt sie.",
"icon": "res://assets/Icons/Tektonischer_Schlag.png",
"cooldown": TEKTONISCHER_SCHLAG_COOLDOWN,
"cast_time": 0.0,
})
if level >= 35:
available_skills.append({
"id": "berserker",
"name": "Berserker",
"description": "Entfesselt die gesamte Wut. 10s: schneller, stärker, unaufhaltsamer. Danach 2.5s Erschöpfung.",
"icon": "res://assets/Icons/Berserker.png",
"cooldown": BERSERKER_COOLDOWN,
"cast_time": 0.0,
})
if level >= 28:
available_skills.append({
"id": "zornfesseln",
"name": "Zornfesseln",
"description": "Reißt einen Gegner heran und schlägt ihn mit voller Wucht.",
"icon": "res://assets/Icons/Zornfesseln.png",
"cooldown": ZORNFESSELN_COOLDOWN,
"cast_time": 0.0,
})
if level >= 20:
available_skills.append({
"id": "wirbelwind",
"name": "Wirbelwind",
"description": "Drehangriff mit voller Wucht. Trifft alle Gegner in der Nähe für hohen Schaden.",
"icon": "res://assets/Icons/Wirbelwind.png",
"cooldown": WIRBELWIND_COOLDOWN,
"cast_time": 0.0,
})
if level >= 15:
available_skills.append({
"id": "blutrausch",
"name": "Blutrausch",
"description": "Reißt eine tiefe Wunde. Sofortschaden + Blutung über 8 Sekunden.",
"icon": "res://assets/Icons/Blutrausch.png",
"cooldown": BLUTRAUSCH_COOLDOWN,
"cast_time": 0.0,
})
if level >= 10:
var has_offhand = _has_shield() var has_offhand = _has_shield()
available_skills.append({ available_skills.append({
"id": "durchbeissen", "id": "durchbeissen",
@ -363,6 +319,58 @@ func _init_class_skills():
"icon": "res://assets/Icons/Durchbeißen.png", "icon": "res://assets/Icons/Durchbeißen.png",
"cooldown": DURCHBEISSEN_COOLDOWN, "cooldown": DURCHBEISSEN_COOLDOWN,
"cast_time": 0.0, "cast_time": 0.0,
"locked": level < 10,
"level_required": 10,
})
available_skills.append({
"id": "tektonischer_schlag",
"name": "Tektonischer Schlag",
"description": "Erschüttert den Boden um dich herum. Schlägt alle Gegner in der Nähe und verlangsamt sie.",
"icon": "res://assets/Icons/Tektonischer_Schlag.png",
"cooldown": TEKTONISCHER_SCHLAG_COOLDOWN,
"cast_time": 0.0,
"locked": level < 5,
"level_required": 5,
})
available_skills.append({
"id": "blutrausch",
"name": "Blutrausch",
"description": "Reißt eine tiefe Wunde. Sofortschaden + Blutung über 8 Sekunden.",
"icon": "res://assets/Icons/Blutrausch.png",
"cooldown": BLUTRAUSCH_COOLDOWN,
"cast_time": 0.0,
"locked": level < 15,
"level_required": 15,
})
available_skills.append({
"id": "wirbelwind",
"name": "Wirbelwind",
"description": "Drehangriff mit voller Wucht. Trifft alle Gegner in der Nähe für hohen Schaden.",
"icon": "res://assets/Icons/Wirbelwind.png",
"cooldown": WIRBELWIND_COOLDOWN,
"cast_time": 0.0,
"locked": level < 20,
"level_required": 20,
})
available_skills.append({
"id": "zornfesseln",
"name": "Zornfesseln",
"description": "Reißt einen Gegner heran und schlägt ihn mit voller Wucht.",
"icon": "res://assets/Icons/Zornfesseln.png",
"cooldown": ZORNFESSELN_COOLDOWN,
"cast_time": 0.0,
"locked": level < 28,
"level_required": 28,
})
available_skills.append({
"id": "berserker",
"name": "Berserker",
"description": "Entfesselt die gesamte Wut. 10s: schneller, stärker, unaufhaltsamer. Danach 2.5s Erschöpfung.",
"icon": "res://assets/Icons/Berserker.png",
"cooldown": BERSERKER_COOLDOWN,
"cast_time": 0.0,
"locked": level < 35,
"level_required": 35,
}) })
CharacterClass.MainStat.INTELLIGENCE: # Magier CharacterClass.MainStat.INTELLIGENCE: # Magier
@ -696,7 +704,7 @@ func execute_skill(skill_id: String):
if is_dead or is_casting or is_drinking or is_berserker_crash: if is_dead or is_casting or is_drinking or is_berserker_crash:
return return
var skill = _find_skill(skill_id) var skill = _find_skill(skill_id)
if skill.is_empty(): if skill.is_empty() or skill.get("locked", false):
return return
# GCD Check # GCD Check

View file

@ -33,10 +33,12 @@ func _refresh_skills():
child.queue_free() child.queue_free()
for skill in player.available_skills: for skill in player.available_skills:
var is_locked: bool = skill.get("locked", false)
# Hintergrund-Panel für Lesbarkeit # Hintergrund-Panel für Lesbarkeit
var panel = PanelContainer.new() var panel = PanelContainer.new()
var style = StyleBoxFlat.new() var style = StyleBoxFlat.new()
style.bg_color = Color(0.9, 0.85, 0.75, 0.18) style.bg_color = Color(0.9, 0.85, 0.75, 0.18) if not is_locked else Color(0.3, 0.3, 0.3, 0.15)
style.set_corner_radius_all(4) style.set_corner_radius_all(4)
panel.add_theme_stylebox_override("panel", style) panel.add_theme_stylebox_override("panel", style)
panel.mouse_filter = Control.MOUSE_FILTER_STOP panel.mouse_filter = Control.MOUSE_FILTER_STOP
@ -56,21 +58,39 @@ func _refresh_skills():
icon_rect.custom_minimum_size = Vector2(36, 36) icon_rect.custom_minimum_size = Vector2(36, 36)
icon_rect.size = Vector2(36, 36) icon_rect.size = Vector2(36, 36)
icon_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE icon_rect.mouse_filter = Control.MOUSE_FILTER_IGNORE
if is_locked:
icon_rect.modulate = Color(1, 1, 1, 0.35)
hbox.add_child(icon_rect) hbox.add_child(icon_rect)
# Name # Name + Level-Anforderung
var vbox = VBoxContainer.new()
vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
vbox.mouse_filter = Control.MOUSE_FILTER_IGNORE
hbox.add_child(vbox)
var label = Label.new() var label = Label.new()
label.text = skill["name"] label.text = skill["name"]
label.add_theme_font_size_override("font_size", 14) label.add_theme_font_size_override("font_size", 14)
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
label.mouse_filter = Control.MOUSE_FILTER_IGNORE label.mouse_filter = Control.MOUSE_FILTER_IGNORE
hbox.add_child(label) if is_locked:
label.modulate = Color(0.55, 0.55, 0.55, 1.0)
vbox.add_child(label)
if is_locked:
var req_label = Label.new()
req_label.text = "Benötigt Level %d" % skill.get("level_required", 0)
req_label.add_theme_font_size_override("font_size", 10)
req_label.modulate = Color(0.6, 0.45, 0.3, 1.0)
req_label.mouse_filter = Control.MOUSE_FILTER_IGNORE
vbox.add_child(req_label)
# Tooltip # Tooltip
panel.tooltip_text = skill["name"] + "\n" + skill["description"] panel.tooltip_text = skill["name"] + "\n" + skill["description"]
if is_locked:
panel.tooltip_text += "\n\n[Gesperrt bis Level %d]" % skill.get("level_required", 0)
# Drag starten bei Linksklick # Drag nur bei freigeschalteten Skills
if not is_locked:
var skill_id = skill["id"] var skill_id = skill["id"]
var skill_icon_path = skill["icon"] var skill_icon_path = skill["icon"]
panel.gui_input.connect(_on_skill_input.bind(skill_id, skill_icon_path)) panel.gui_input.connect(_on_skill_input.bind(skill_id, skill_icon_path))