# SkillPanel.gd # Zeigt alle verfügbaren Fähigkeiten an, von hier aus auf Aktionsleiste ziehen extends CanvasLayer var panel_visible = false var player = null # Pagination const SKILLS_PER_PAGE: int = 9 var current_page: int = 0 var _page_label: Label = null var _prev_btn: Button = null var _next_btn: Button = 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 _create_pagination_bar() func _create_pagination_bar(): var vbox = $Panel/VBoxContainer var nav = HBoxContainer.new() nav.alignment = BoxContainer.ALIGNMENT_CENTER nav.add_theme_constant_override("separation", 12) _prev_btn = Button.new() _prev_btn.text = "< Zurück" _prev_btn.add_theme_font_size_override("font_size", 13) _prev_btn.pressed.connect(_on_prev_page) nav.add_child(_prev_btn) _page_label = Label.new() _page_label.add_theme_font_size_override("font_size", 13) _page_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER _page_label.custom_minimum_size = Vector2(80, 0) nav.add_child(_page_label) _next_btn = Button.new() _next_btn.text = "Weiter >" _next_btn.add_theme_font_size_override("font_size", 13) _next_btn.pressed.connect(_on_next_page) nav.add_child(_next_btn) vbox.add_child(nav) func _on_prev_page(): current_page = max(0, current_page - 1) _refresh_skills() func _on_next_page(): var total_pages = _get_total_pages() current_page = min(total_pages - 1, current_page + 1) _refresh_skills() func _get_total_pages() -> int: if player == null: return 1 return max(1, ceili(float(player.available_skills.size()) / SKILLS_PER_PAGE)) func setup(p): player = p func toggle(): panel_visible = !panel_visible panel.visible = panel_visible if panel_visible: current_page = 0 _refresh_skills() func _refresh_skills(): if player == null: return for child in skill_list.get_children(): child.queue_free() # Pagination-Grenzen berechnen var total_pages = _get_total_pages() var start = current_page * SKILLS_PER_PAGE var end = min(start + SKILLS_PER_PAGE, player.available_skills.size()) var page_skills = player.available_skills.slice(start, end) # Navigations-Buttons und Label aktualisieren _page_label.text = "Seite %d / %d" % [current_page + 1, total_pages] _prev_btn.disabled = current_page == 0 _next_btn.disabled = current_page >= total_pages - 1 for skill in page_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.45) 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.7, 0.7, 0.7, 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 = ""