DungeonCrawler/skill_panel.gd
Andre f007e559b9 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>
2026-03-19 23:16:09 +01:00

150 lines
4.7 KiB
GDScript

# SkillPanel.gd
# Zeigt alle verfügbaren Fähigkeiten an, von hier aus auf Aktionsleiste ziehen
extends CanvasLayer
var panel_visible = false
var player = null
# Drag State
var dragging = false
var drag_skill_id: String = ""
var drag_icon: TextureRect = null
@onready var panel = $Panel
@onready var skill_list = $Panel/VBoxContainer/ScrollContainer/SkillList
func _ready():
panel.visible = false
func setup(p):
player = p
func toggle():
panel_visible = !panel_visible
panel.visible = panel_visible
if panel_visible:
_refresh_skills()
func _refresh_skills():
if player == null:
return
for child in skill_list.get_children():
child.queue_free()
for skill in player.available_skills:
var is_locked: bool = skill.get("locked", false)
# Hintergrund-Panel für Lesbarkeit
var panel = PanelContainer.new()
var style = StyleBoxFlat.new()
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)
panel.add_theme_stylebox_override("panel", style)
panel.mouse_filter = Control.MOUSE_FILTER_STOP
var hbox = HBoxContainer.new()
hbox.add_theme_constant_override("separation", 8)
hbox.mouse_filter = Control.MOUSE_FILTER_IGNORE
panel.add_child(hbox)
# Icon
var icon_rect = TextureRect.new()
var tex = load(skill["icon"])
if tex:
icon_rect.texture = tex
icon_rect.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
icon_rect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
icon_rect.custom_minimum_size = Vector2(36, 36)
icon_rect.size = Vector2(36, 36)
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)
# 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()
label.text = skill["name"]
label.add_theme_font_size_override("font_size", 14)
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
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
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 nur bei freigeschalteten Skills
if not is_locked:
var skill_id = skill["id"]
var skill_icon_path = skill["icon"]
panel.gui_input.connect(_on_skill_input.bind(skill_id, skill_icon_path))
skill_list.add_child(panel)
func _on_skill_input(event: InputEvent, skill_id: String, icon_path: String):
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
_start_drag(skill_id, icon_path)
func _start_drag(skill_id: String, icon_path: String):
dragging = true
drag_skill_id = skill_id
var tex = load(icon_path)
drag_icon = TextureRect.new()
drag_icon.texture = tex
drag_icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE
drag_icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED
drag_icon.mouse_filter = Control.MOUSE_FILTER_IGNORE
var drag_layer = CanvasLayer.new()
drag_layer.name = "DragLayer"
drag_layer.layer = 200
drag_layer.add_child(drag_icon)
get_tree().root.add_child(drag_layer)
# Größe erst nach add_child setzen, sonst überschreibt Godot sie
drag_icon.custom_minimum_size = Vector2(48, 48)
drag_icon.size = Vector2(48, 48)
drag_icon.position = get_viewport().get_mouse_position() - Vector2(24, 24)
if player and player.hud:
player.hud.set_drag_active(true)
func _process(_delta):
if dragging and drag_icon:
drag_icon.position = get_viewport().get_mouse_position() - Vector2(20, 20)
if player and player.hud:
player.hud.update_drag_hover(get_viewport().get_mouse_position())
func _input(event):
if not dragging:
return
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and not event.pressed:
_end_drag()
func _end_drag():
if not dragging:
return
if player and player.hud:
var slot_index = player.hud.get_slot_at_position(get_viewport().get_mouse_position())
if slot_index >= 0 and slot_index <= 8 and drag_skill_id != "":
player.assign_skill_to_action_bar(slot_index, drag_skill_id)
player.hud.set_drag_active(false)
if drag_icon:
var drag_layer = drag_icon.get_parent()
drag_layer.queue_free()
drag_icon = null
dragging = false
drag_skill_id = ""