diff --git a/character_class.gd b/character_class.gd
new file mode 100644
index 0000000..5304900
--- /dev/null
+++ b/character_class.gd
@@ -0,0 +1,32 @@
+# CharacterClass.gd
+# Definiert Charakterklassen mit Grundstats und Main-Stat
+extends Resource
+class_name CharacterClass
+
+enum MainStat { STRENGTH, AGILITY, INTELLIGENCE }
+
+@export var class_name_de: String = "Krieger"
+@export var main_stat: MainStat = MainStat.STRENGTH
+
+# Grund-Stats auf Level 1
+@export var base_strength: int = 10
+@export var base_agility: int = 10
+@export var base_intelligence: int = 10
+@export var base_stamina: int = 10 # Beeinflusst HP
+
+# Stat-Zuwachs pro Level
+@export var strength_per_level: float = 2.0
+@export var agility_per_level: float = 2.0
+@export var intelligence_per_level: float = 2.0
+@export var stamina_per_level: float = 2.0
+
+# Unbewaffneter Schaden (klassenabhängig)
+@export var unarmed_min_damage: int = 1
+@export var unarmed_max_damage: int = 2
+@export var unarmed_attack_speed: float = 2.0 # Langsamer als mit Waffe
+
+# HP pro Stamina-Punkt
+const HP_PER_STAMINA = 10
+
+# Schaden-Skalierung mit Main-Stat
+const DAMAGE_PER_MAIN_STAT = 0.5
diff --git a/character_class.gd.uid b/character_class.gd.uid
new file mode 100644
index 0000000..075b0d4
--- /dev/null
+++ b/character_class.gd.uid
@@ -0,0 +1 @@
+uid://ci45xxb5vn857
diff --git a/character_panel.gd b/character_panel.gd
new file mode 100644
index 0000000..a9b55f4
--- /dev/null
+++ b/character_panel.gd
@@ -0,0 +1,104 @@
+# CharacterPanel.gd
+# Zeigt Charakterinfos: Klasse, Level, Stats und Equipment
+extends CanvasLayer
+
+var panel_visible = false
+
+@onready var panel = $Panel
+@onready var class_label = $Panel/HBoxContainer/StatsColumn/ClassLabel
+@onready var level_label = $Panel/HBoxContainer/StatsColumn/LevelLabel
+@onready var stats_container = $Panel/HBoxContainer/StatsColumn/StatsContainer
+@onready var str_label = $Panel/HBoxContainer/StatsColumn/StatsContainer/StrLabel
+@onready var agi_label = $Panel/HBoxContainer/StatsColumn/StatsContainer/AgiLabel
+@onready var int_label = $Panel/HBoxContainer/StatsColumn/StatsContainer/IntLabel
+@onready var sta_label = $Panel/HBoxContainer/StatsColumn/StatsContainer/StaLabel
+@onready var armor_label = $Panel/HBoxContainer/StatsColumn/StatsContainer/ArmorLabel
+@onready var hp_label = $Panel/HBoxContainer/StatsColumn/HPLabel
+@onready var damage_label = $Panel/HBoxContainer/EquipmentColumn/DamageLabel
+@onready var dps_label = $Panel/HBoxContainer/EquipmentColumn/DPSLabel
+
+# Equipment Slots
+@onready var head_slot = $Panel/HBoxContainer/EquipmentColumn/EquipmentContainer/HeadSlot
+@onready var chest_slot = $Panel/HBoxContainer/EquipmentColumn/EquipmentContainer/ChestSlot
+@onready var hands_slot = $Panel/HBoxContainer/EquipmentColumn/EquipmentContainer/HandsSlot
+@onready var legs_slot = $Panel/HBoxContainer/EquipmentColumn/EquipmentContainer/LegsSlot
+@onready var feet_slot = $Panel/HBoxContainer/EquipmentColumn/EquipmentContainer/FeetSlot
+@onready var weapon_slot = $Panel/HBoxContainer/EquipmentColumn/WeaponSlot
+@onready var offhand_slot = $Panel/HBoxContainer/EquipmentColumn/OffhandSlot
+
+func _ready():
+ panel.visible = false
+
+func toggle():
+ panel_visible = !panel_visible
+ panel.visible = panel_visible
+
+func update_stats(player):
+ if player.character_class:
+ var main_stat_name = ""
+ match player.character_class.main_stat:
+ CharacterClass.MainStat.STRENGTH:
+ main_stat_name = "STR"
+ CharacterClass.MainStat.AGILITY:
+ main_stat_name = "AGI"
+ CharacterClass.MainStat.INTELLIGENCE:
+ main_stat_name = "INT"
+ class_label.text = player.character_class.class_name_de + " (Haupt: " + main_stat_name + ")"
+ else:
+ class_label.text = "Keine Klasse"
+
+ level_label.text = "Level " + str(player.level) + " (" + str(player.current_xp) + "/" + str(player.xp_to_next_level) + " XP)"
+
+ str_label.text = "Stärke: " + str(player.strength)
+ agi_label.text = "Beweglichkeit: " + str(player.agility)
+ int_label.text = "Intelligenz: " + str(player.intelligence)
+ sta_label.text = "Ausdauer: " + str(player.stamina)
+ armor_label.text = "Rüstung: " + str(player.armor)
+
+ hp_label.text = "HP: " + str(player.current_hp) + " / " + str(player.max_hp)
+
+ # Waffen-Stats (jetzt in Equipment-Spalte)
+ var weapon = player.get_equipped_weapon()
+ if weapon:
+ damage_label.text = "Schaden: " + str(weapon.min_damage) + "-" + str(weapon.max_damage) + " (%.1fs)" % weapon.attack_speed
+ else:
+ # Unbewaffnet: klassenabhängiger Schaden
+ if player.character_class:
+ var min_dmg = player.character_class.unarmed_min_damage
+ var max_dmg = player.character_class.unarmed_max_damage
+ var atk_spd = player.character_class.unarmed_attack_speed
+ damage_label.text = "Unbewaffnet: " + str(min_dmg) + "-" + str(max_dmg) + " (%.1fs)" % atk_spd
+ else:
+ damage_label.text = "Unbewaffnet: 1-2 (2.0s)"
+ dps_label.text = "DPS: %.1f" % player.get_dps()
+
+ # Main-Stat hervorheben
+ str_label.modulate = Color(1, 1, 1)
+ agi_label.modulate = Color(1, 1, 1)
+ int_label.modulate = Color(1, 1, 1)
+
+ if player.character_class:
+ match player.character_class.main_stat:
+ CharacterClass.MainStat.STRENGTH:
+ str_label.modulate = Color(1, 0.8, 0.2)
+ CharacterClass.MainStat.AGILITY:
+ agi_label.modulate = Color(1, 0.8, 0.2)
+ CharacterClass.MainStat.INTELLIGENCE:
+ int_label.modulate = Color(1, 0.8, 0.2)
+
+ # Equipment aktualisieren
+ _update_equipment_slot(head_slot, "Kopf", player.equipment[Equipment.Slot.HEAD])
+ _update_equipment_slot(chest_slot, "Brust", player.equipment[Equipment.Slot.CHEST])
+ _update_equipment_slot(hands_slot, "Hände", player.equipment[Equipment.Slot.HANDS])
+ _update_equipment_slot(legs_slot, "Beine", player.equipment[Equipment.Slot.LEGS])
+ _update_equipment_slot(feet_slot, "Füße", player.equipment[Equipment.Slot.FEET])
+ _update_equipment_slot(weapon_slot, "Waffe", player.equipment[Equipment.Slot.WEAPON])
+ _update_equipment_slot(offhand_slot, "Nebenhand", player.equipment[Equipment.Slot.OFFHAND])
+
+func _update_equipment_slot(label: Label, slot_name: String, item: Equipment):
+ if item == null:
+ label.text = slot_name + ": -"
+ label.modulate = Color(0.6, 0.6, 0.6)
+ else:
+ label.text = slot_name + ": " + item.item_name
+ label.modulate = Equipment.get_rarity_color(item.rarity)
diff --git a/character_panel.gd.uid b/character_panel.gd.uid
new file mode 100644
index 0000000..dfdb2bb
--- /dev/null
+++ b/character_panel.gd.uid
@@ -0,0 +1 @@
+uid://7pdlor66gi51
diff --git a/character_panel.tscn b/character_panel.tscn
new file mode 100644
index 0000000..41f1646
--- /dev/null
+++ b/character_panel.tscn
@@ -0,0 +1,155 @@
+[gd_scene format=3 uid="uid://character_panel"]
+
+[ext_resource type="Script" path="res://character_panel.gd" id="1_panel"]
+
+[node name="CharacterPanel" type="CanvasLayer"]
+script = ExtResource("1_panel")
+
+[node name="Panel" type="Panel" parent="."]
+anchors_preset = 4
+anchor_top = 0.5
+anchor_bottom = 0.5
+offset_left = 20.0
+offset_top = -200.0
+offset_right = 520.0
+offset_bottom = 200.0
+grow_vertical = 2
+
+[node name="HBoxContainer" type="HBoxContainer" parent="Panel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = 15.0
+offset_top = 15.0
+offset_right = -15.0
+offset_bottom = -15.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/separation = 20
+
+[node name="StatsColumn" type="VBoxContainer" parent="Panel/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 6
+
+[node name="Title" type="Label" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 20
+text = "Charakter"
+horizontal_alignment = 1
+
+[node name="HSeparator" type="HSeparator" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+
+[node name="ClassLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 16
+text = "Krieger (Haupt: STR)"
+
+[node name="LevelLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "Level 1 (0/100 XP)"
+
+[node name="HSeparator2" type="HSeparator" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+
+[node name="StatsContainer" type="VBoxContainer" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+theme_override_constants/separation = 4
+
+[node name="StrLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn/StatsContainer"]
+layout_mode = 2
+text = "Stärke: 15"
+
+[node name="AgiLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn/StatsContainer"]
+layout_mode = 2
+text = "Beweglichkeit: 8"
+
+[node name="IntLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn/StatsContainer"]
+layout_mode = 2
+text = "Intelligenz: 5"
+
+[node name="StaLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn/StatsContainer"]
+layout_mode = 2
+text = "Ausdauer: 12"
+
+[node name="ArmorLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn/StatsContainer"]
+layout_mode = 2
+text = "Rüstung: 0"
+
+[node name="HSeparator3" type="HSeparator" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+
+[node name="HPLabel" type="Label" parent="Panel/HBoxContainer/StatsColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "HP: 120 / 120"
+
+[node name="VSeparator" type="VSeparator" parent="Panel/HBoxContainer"]
+layout_mode = 2
+
+[node name="EquipmentColumn" type="VBoxContainer" parent="Panel/HBoxContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_constants/separation = 6
+
+[node name="EquipTitle" type="Label" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 20
+text = "Ausrüstung"
+horizontal_alignment = 1
+
+[node name="HSeparator" type="HSeparator" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+
+[node name="EquipmentContainer" type="VBoxContainer" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_constants/separation = 4
+
+[node name="HeadSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn/EquipmentContainer"]
+layout_mode = 2
+text = "Kopf: -"
+
+[node name="ChestSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn/EquipmentContainer"]
+layout_mode = 2
+text = "Brust: -"
+
+[node name="HandsSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn/EquipmentContainer"]
+layout_mode = 2
+text = "Hände: -"
+
+[node name="LegsSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn/EquipmentContainer"]
+layout_mode = 2
+text = "Beine: -"
+
+[node name="FeetSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn/EquipmentContainer"]
+layout_mode = 2
+text = "Füße: -"
+
+[node name="HSeparator2" type="HSeparator" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+
+[node name="WeaponSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "Waffe: -"
+
+[node name="OffhandSlot" type="Label" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "Nebenhand: -"
+
+[node name="HSeparator3" type="HSeparator" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+
+[node name="DamageLabel" type="Label" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "Schaden: 3-6 (1.5s)"
+
+[node name="DPSLabel" type="Label" parent="Panel/HBoxContainer/EquipmentColumn"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = "DPS: 5.0"
diff --git a/class_selection_menu.gd b/class_selection_menu.gd
new file mode 100644
index 0000000..b9e6272
--- /dev/null
+++ b/class_selection_menu.gd
@@ -0,0 +1,81 @@
+# ClassSelectionMenu.gd
+# Menü zur Auswahl der Charakterklasse beim Spielstart
+extends CanvasLayer
+
+signal class_selected(character_class: CharacterClass)
+
+const WARRIOR_CLASS = preload("res://classes/warrior.tres")
+const ROGUE_CLASS = preload("res://classes/rogue.tres")
+const MAGE_CLASS = preload("res://classes/mage.tres")
+
+var selected_class: CharacterClass = null
+
+@onready var panel = $Panel
+@onready var warrior_btn = $Panel/VBoxContainer/ClassButtons/WarriorBtn
+@onready var rogue_btn = $Panel/VBoxContainer/ClassButtons/RogueBtn
+@onready var mage_btn = $Panel/VBoxContainer/ClassButtons/MageBtn
+@onready var start_btn = $Panel/VBoxContainer/StartBtn
+@onready var class_info = $Panel/VBoxContainer/ClassInfo
+@onready var stats_label = $Panel/VBoxContainer/StatsLabel
+
+func _ready():
+ # Spiel pausieren während Menü offen
+ get_tree().paused = true
+ process_mode = Node.PROCESS_MODE_ALWAYS
+
+ # Buttons verbinden
+ warrior_btn.pressed.connect(_on_warrior_selected)
+ rogue_btn.pressed.connect(_on_rogue_selected)
+ mage_btn.pressed.connect(_on_mage_selected)
+ start_btn.pressed.connect(_on_start_pressed)
+
+ # Start-Button deaktiviert bis Klasse gewählt
+ start_btn.disabled = true
+ class_info.text = "Wähle eine Klasse!"
+ stats_label.text = ""
+
+func _on_warrior_selected():
+ selected_class = WARRIOR_CLASS
+ _update_selection("Krieger", WARRIOR_CLASS)
+ _highlight_button(warrior_btn)
+
+func _on_rogue_selected():
+ selected_class = ROGUE_CLASS
+ _update_selection("Schurke", ROGUE_CLASS)
+ _highlight_button(rogue_btn)
+
+func _on_mage_selected():
+ selected_class = MAGE_CLASS
+ _update_selection("Magier", MAGE_CLASS)
+ _highlight_button(mage_btn)
+
+func _update_selection(cls_name: String, char_class: CharacterClass):
+ var main_stat_name = ""
+ match char_class.main_stat:
+ CharacterClass.MainStat.STRENGTH:
+ main_stat_name = "Stärke"
+ CharacterClass.MainStat.AGILITY:
+ main_stat_name = "Beweglichkeit"
+ CharacterClass.MainStat.INTELLIGENCE:
+ main_stat_name = "Intelligenz"
+
+ class_info.text = cls_name + " - Haupt-Stat: " + main_stat_name
+ stats_label.text = "STR: " + str(char_class.base_strength) + " AGI: " + str(char_class.base_agility) + " INT: " + str(char_class.base_intelligence) + " STA: " + str(char_class.base_stamina)
+ start_btn.disabled = false
+
+func _highlight_button(active_btn: Button):
+ # Alle Buttons zurücksetzen
+ warrior_btn.modulate = Color(1, 1, 1)
+ rogue_btn.modulate = Color(1, 1, 1)
+ mage_btn.modulate = Color(1, 1, 1)
+ # Aktiven Button hervorheben
+ active_btn.modulate = Color(1, 0.8, 0.2)
+
+func _on_start_pressed():
+ if selected_class == null:
+ return
+
+ # Signal senden und Menü schließen
+ class_selected.emit(selected_class)
+ get_tree().paused = false
+ queue_free()
diff --git a/class_selection_menu.gd.uid b/class_selection_menu.gd.uid
new file mode 100644
index 0000000..493bc1f
--- /dev/null
+++ b/class_selection_menu.gd.uid
@@ -0,0 +1 @@
+uid://db8m2uw42hqfc
diff --git a/class_selection_menu.tscn b/class_selection_menu.tscn
new file mode 100644
index 0000000..337d396
--- /dev/null
+++ b/class_selection_menu.tscn
@@ -0,0 +1,80 @@
+[gd_scene format=3 uid="uid://class_selection_menu"]
+
+[ext_resource type="Script" path="res://class_selection_menu.gd" id="1_menu"]
+
+[node name="ClassSelectionMenu" type="CanvasLayer"]
+script = ExtResource("1_menu")
+
+[node name="Panel" type="Panel" parent="."]
+anchors_preset = 8
+anchor_left = 0.5
+anchor_top = 0.5
+anchor_right = 0.5
+anchor_bottom = 0.5
+offset_left = -200.0
+offset_top = -180.0
+offset_right = 200.0
+offset_bottom = 180.0
+grow_horizontal = 2
+grow_vertical = 2
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Panel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = 20.0
+offset_top = 20.0
+offset_right = -20.0
+offset_bottom = -20.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/separation = 15
+
+[node name="Title" type="Label" parent="Panel/VBoxContainer"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 28
+text = "Wähle deine Klasse"
+horizontal_alignment = 1
+
+[node name="ClassButtons" type="HBoxContainer" parent="Panel/VBoxContainer"]
+layout_mode = 2
+theme_override_constants/separation = 20
+alignment = 1
+
+[node name="WarriorBtn" type="Button" parent="Panel/VBoxContainer/ClassButtons"]
+custom_minimum_size = Vector2(100, 80)
+layout_mode = 2
+theme_override_font_sizes/font_size = 16
+text = "Krieger"
+
+[node name="RogueBtn" type="Button" parent="Panel/VBoxContainer/ClassButtons"]
+custom_minimum_size = Vector2(100, 80)
+layout_mode = 2
+theme_override_font_sizes/font_size = 16
+text = "Schurke"
+
+[node name="MageBtn" type="Button" parent="Panel/VBoxContainer/ClassButtons"]
+custom_minimum_size = Vector2(100, 80)
+layout_mode = 2
+theme_override_font_sizes/font_size = 16
+text = "Magier"
+
+[node name="ClassInfo" type="Label" parent="Panel/VBoxContainer"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 18
+text = "Wähle eine Klasse!"
+horizontal_alignment = 1
+
+[node name="StatsLabel" type="Label" parent="Panel/VBoxContainer"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 14
+text = ""
+horizontal_alignment = 1
+
+[node name="StartBtn" type="Button" parent="Panel/VBoxContainer"]
+custom_minimum_size = Vector2(0, 50)
+layout_mode = 2
+theme_override_font_sizes/font_size = 20
+disabled = true
+text = "Spiel starten"
diff --git a/classes/mage.tres b/classes/mage.tres
new file mode 100644
index 0000000..943b96d
--- /dev/null
+++ b/classes/mage.tres
@@ -0,0 +1,19 @@
+[gd_resource type="Resource" script_class="CharacterClass" format=3]
+
+[ext_resource type="Script" path="res://character_class.gd" id="1"]
+
+[resource]
+script = ExtResource("1")
+class_name_de = "Magier"
+main_stat = 2
+base_strength = 5
+base_agility = 8
+base_intelligence = 15
+base_stamina = 8
+strength_per_level = 1.0
+agility_per_level = 1.5
+intelligence_per_level = 3.0
+stamina_per_level = 1.5
+unarmed_min_damage = 1
+unarmed_max_damage = 2
+unarmed_attack_speed = 2.0
diff --git a/classes/rogue.tres b/classes/rogue.tres
new file mode 100644
index 0000000..ea63f98
--- /dev/null
+++ b/classes/rogue.tres
@@ -0,0 +1,19 @@
+[gd_resource type="Resource" script_class="CharacterClass" format=3]
+
+[ext_resource type="Script" path="res://character_class.gd" id="1"]
+
+[resource]
+script = ExtResource("1")
+class_name_de = "Schurke"
+main_stat = 1
+base_strength = 8
+base_agility = 15
+base_intelligence = 7
+base_stamina = 10
+strength_per_level = 1.5
+agility_per_level = 3.0
+intelligence_per_level = 1.5
+stamina_per_level = 2.0
+unarmed_min_damage = 1
+unarmed_max_damage = 3
+unarmed_attack_speed = 1.5
diff --git a/classes/warrior.tres b/classes/warrior.tres
new file mode 100644
index 0000000..690eb51
--- /dev/null
+++ b/classes/warrior.tres
@@ -0,0 +1,19 @@
+[gd_resource type="Resource" script_class="CharacterClass" format=3]
+
+[ext_resource type="Script" path="res://character_class.gd" id="1"]
+
+[resource]
+script = ExtResource("1")
+class_name_de = "Krieger"
+main_stat = 0
+base_strength = 15
+base_agility = 8
+base_intelligence = 5
+base_stamina = 12
+strength_per_level = 3.0
+agility_per_level = 1.5
+intelligence_per_level = 1.0
+stamina_per_level = 2.5
+unarmed_min_damage = 2
+unarmed_max_damage = 4
+unarmed_attack_speed = 1.8
diff --git a/equipment.gd b/equipment.gd
new file mode 100644
index 0000000..bc40061
--- /dev/null
+++ b/equipment.gd
@@ -0,0 +1,63 @@
+# Equipment.gd
+# Resource für Ausrüstungsgegenstände
+extends Resource
+class_name Equipment
+
+enum Slot {
+ HEAD, # Helm
+ CHEST, # Brustpanzer
+ HANDS, # Handschuhe
+ LEGS, # Beinschienen
+ FEET, # Stiefel
+ WEAPON, # Waffe
+ OFFHAND # Nebenhand (Schild, etc.)
+}
+
+enum Rarity {
+ COMMON, # Weiß
+ UNCOMMON, # Grün
+ RARE, # Blau
+ EPIC # Lila
+}
+
+@export var item_name: String = "Unbekannt"
+@export var slot: Slot = Slot.WEAPON
+@export var rarity: Rarity = Rarity.COMMON
+
+# Stats die das Item gibt
+@export var armor: int = 0
+@export var strength: int = 0
+@export var agility: int = 0
+@export var intelligence: int = 0
+@export var stamina: int = 0
+@export var haste: float = 0.0 # Angriffsgeschwindigkeit (0.1 = 10% schneller)
+
+# Nur für Waffen
+@export var min_damage: int = 0
+@export var max_damage: int = 0
+@export var attack_speed: float = 1.5 # Sekunden zwischen Angriffen
+@export var weapon_range: float = 3.0
+
+# Icon für UI
+@export var icon: Texture2D
+
+# Slot-Namen für Anzeige
+static func get_slot_name(s: Slot) -> String:
+ match s:
+ Slot.HEAD: return "Kopf"
+ Slot.CHEST: return "Brust"
+ Slot.HANDS: return "Hände"
+ Slot.LEGS: return "Beine"
+ Slot.FEET: return "Füße"
+ Slot.WEAPON: return "Waffe"
+ Slot.OFFHAND: return "Nebenhand"
+ return "Unbekannt"
+
+# Seltenheitsfarbe
+static func get_rarity_color(r: Rarity) -> Color:
+ match r:
+ Rarity.COMMON: return Color(1, 1, 1) # Weiß
+ Rarity.UNCOMMON: return Color(0.2, 0.8, 0.2) # Grün
+ Rarity.RARE: return Color(0.3, 0.5, 1.0) # Blau
+ Rarity.EPIC: return Color(0.7, 0.3, 0.9) # Lila
+ return Color(1, 1, 1)
diff --git a/equipment.gd.uid b/equipment.gd.uid
new file mode 100644
index 0000000..361aeaf
--- /dev/null
+++ b/equipment.gd.uid
@@ -0,0 +1 @@
+uid://re0xiie1udfq
diff --git a/equipment/iron_helm.tres b/equipment/iron_helm.tres
new file mode 100644
index 0000000..f1c45d2
--- /dev/null
+++ b/equipment/iron_helm.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="Equipment" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://equipment.gd" id="1_equipment"]
+
+[resource]
+script = ExtResource("1_equipment")
+item_name = "Eisenhelm"
+slot = 0
+rarity = 0
+armor = 5
+strength = 1
+agility = 0
+intelligence = 0
+stamina = 1
+min_damage = 0
+max_damage = 0
+attack_speed = 1.5
+weapon_range = 3.0
diff --git a/equipment/iron_sword.tres b/equipment/iron_sword.tres
new file mode 100644
index 0000000..ee231ee
--- /dev/null
+++ b/equipment/iron_sword.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="Equipment" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://equipment.gd" id="1_equipment"]
+
+[resource]
+script = ExtResource("1_equipment")
+item_name = "Eisenschwert"
+slot = 5
+rarity = 0
+armor = 0
+strength = 2
+agility = 0
+intelligence = 0
+stamina = 0
+min_damage = 3
+max_damage = 6
+attack_speed = 1.5
+weapon_range = 3.0
diff --git a/equipment/leather_chest.tres b/equipment/leather_chest.tres
new file mode 100644
index 0000000..ef2a30f
--- /dev/null
+++ b/equipment/leather_chest.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="Equipment" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://equipment.gd" id="1_equipment"]
+
+[resource]
+script = ExtResource("1_equipment")
+item_name = "Lederrüstung"
+slot = 1
+rarity = 0
+armor = 8
+strength = 0
+agility = 1
+intelligence = 0
+stamina = 2
+min_damage = 0
+max_damage = 0
+attack_speed = 1.5
+weapon_range = 3.0
diff --git a/equipment/steel_sword.tres b/equipment/steel_sword.tres
new file mode 100644
index 0000000..b1b01e2
--- /dev/null
+++ b/equipment/steel_sword.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="Equipment" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://equipment.gd" id="1_equipment"]
+
+[resource]
+script = ExtResource("1_equipment")
+item_name = "Stahlschwert"
+slot = 5
+rarity = 1
+armor = 0
+strength = 4
+agility = 0
+intelligence = 0
+stamina = 0
+min_damage = 5
+max_damage = 9
+attack_speed = 1.4
+weapon_range = 3.0
diff --git a/equipment/wooden_shield.tres b/equipment/wooden_shield.tres
new file mode 100644
index 0000000..10e0186
--- /dev/null
+++ b/equipment/wooden_shield.tres
@@ -0,0 +1,18 @@
+[gd_resource type="Resource" script_class="Equipment" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://equipment.gd" id="1_equipment"]
+
+[resource]
+script = ExtResource("1_equipment")
+item_name = "Holzschild"
+slot = 6
+rarity = 0
+armor = 6
+strength = 0
+agility = 0
+intelligence = 0
+stamina = 2
+min_damage = 0
+max_damage = 0
+attack_speed = 1.5
+weapon_range = 3.0
diff --git a/heavy_strike.tres b/heavy_strike.tres
new file mode 100644
index 0000000..317d522
--- /dev/null
+++ b/heavy_strike.tres
@@ -0,0 +1,9 @@
+[gd_resource type="Resource" script_class="Attack" load_steps=2 format=3]
+
+[ext_resource type="Script" path="res://resources/attack.gd" id="1"]
+
+[resource]
+script = ExtResource("1")
+name = "Heavy Strike"
+damage_type = 0
+icon = null
diff --git a/icons/autoattack_icon.svg b/icons/autoattack_icon.svg
new file mode 100644
index 0000000..dc7b97d
--- /dev/null
+++ b/icons/autoattack_icon.svg
@@ -0,0 +1,25 @@
+
diff --git a/icons/autoattack_icon.svg.import b/icons/autoattack_icon.svg.import
new file mode 100644
index 0000000..0549514
--- /dev/null
+++ b/icons/autoattack_icon.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://bkujmu8r6370p"
+path="res://.godot/imported/autoattack_icon.svg-8c48165bd13a879d5f6cdbc811e19882.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icons/autoattack_icon.svg"
+dest_files=["res://.godot/imported/autoattack_icon.svg-8c48165bd13a879d5f6cdbc811e19882.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/icons/heavy_strike_icon.svg b/icons/heavy_strike_icon.svg
new file mode 100644
index 0000000..ce005ff
--- /dev/null
+++ b/icons/heavy_strike_icon.svg
@@ -0,0 +1,26 @@
+
diff --git a/icons/heavy_strike_icon.svg.import b/icons/heavy_strike_icon.svg.import
new file mode 100644
index 0000000..790abfa
--- /dev/null
+++ b/icons/heavy_strike_icon.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://dqkaowq4cvtbl"
+path="res://.godot/imported/heavy_strike_icon.svg-ae86ca74d5a61e67598cea5812ee34ac.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icons/heavy_strike_icon.svg"
+dest_files=["res://.godot/imported/heavy_strike_icon.svg-ae86ca74d5a61e67598cea5812ee34ac.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/inventory.gd b/inventory.gd
new file mode 100644
index 0000000..17a292e
--- /dev/null
+++ b/inventory.gd
@@ -0,0 +1,77 @@
+# Inventory.gd
+# Verwaltet das Spieler-Inventar mit Items und Gold
+extends Resource
+class_name Inventory
+
+signal inventory_changed
+signal gold_changed(new_amount: int)
+
+const MAX_SLOTS = 20 # Maximale Inventarplätze
+
+var items: Array[Equipment] = []
+var gold: int = 0
+
+func _init():
+ items = []
+ gold = 0
+
+# Item hinzufügen - gibt true zurück wenn erfolgreich
+func add_item(item: Equipment) -> bool:
+ if items.size() >= MAX_SLOTS:
+ print("Inventar voll!")
+ return false
+ items.append(item)
+ inventory_changed.emit()
+ print("Item erhalten: ", item.item_name)
+ return true
+
+# Item an Index entfernen
+func remove_item_at(index: int) -> Equipment:
+ if index < 0 or index >= items.size():
+ return null
+ var item = items[index]
+ items.remove_at(index)
+ inventory_changed.emit()
+ return item
+
+# Item direkt entfernen
+func remove_item(item: Equipment) -> bool:
+ var index = items.find(item)
+ if index == -1:
+ return false
+ items.remove_at(index)
+ inventory_changed.emit()
+ return true
+
+# Gold hinzufügen
+func add_gold(amount: int):
+ gold += amount
+ gold_changed.emit(gold)
+ print("+", amount, " Gold (Gesamt: ", gold, ")")
+
+# Gold ausgeben - gibt true zurück wenn genug vorhanden
+func spend_gold(amount: int) -> bool:
+ if gold < amount:
+ print("Nicht genug Gold!")
+ return false
+ gold -= amount
+ gold_changed.emit(gold)
+ return true
+
+# Prüfen ob Inventar voll ist
+func is_full() -> bool:
+ return items.size() >= MAX_SLOTS
+
+# Anzahl freier Slots
+func free_slots() -> int:
+ return MAX_SLOTS - items.size()
+
+# Item an Index holen
+func get_item(index: int) -> Equipment:
+ if index < 0 or index >= items.size():
+ return null
+ return items[index]
+
+# Anzahl Items
+func item_count() -> int:
+ return items.size()
diff --git a/inventory.gd.uid b/inventory.gd.uid
new file mode 100644
index 0000000..9e173d9
--- /dev/null
+++ b/inventory.gd.uid
@@ -0,0 +1 @@
+uid://b7x1jr36w0bfg
diff --git a/inventory_panel.gd b/inventory_panel.gd
new file mode 100644
index 0000000..8285374
--- /dev/null
+++ b/inventory_panel.gd
@@ -0,0 +1,128 @@
+# InventoryPanel.gd
+# UI für das Spieler-Inventar
+extends CanvasLayer
+
+signal item_selected(item: Equipment, index: int)
+
+var panel_visible = false
+var player = null
+
+@onready var panel = $Panel
+@onready var gold_label = $Panel/VBoxContainer/Header/GoldLabel
+@onready var item_grid = $Panel/VBoxContainer/ScrollContainer/ItemGrid
+
+const SLOT_SIZE = 50
+
+func _ready():
+ panel.visible = false
+
+func setup(p):
+ player = p
+ if player and player.inventory:
+ player.inventory.inventory_changed.connect(_on_inventory_changed)
+ player.inventory.gold_changed.connect(_on_gold_changed)
+ _refresh_inventory()
+
+func toggle():
+ panel_visible = !panel_visible
+ panel.visible = panel_visible
+ if panel_visible:
+ _refresh_inventory()
+
+func _on_inventory_changed():
+ _refresh_inventory()
+
+func _on_gold_changed(new_amount: int):
+ gold_label.text = str(new_amount) + " Gold"
+
+func _refresh_inventory():
+ if player == null or player.inventory == null:
+ return
+
+ # Gold aktualisieren
+ gold_label.text = str(player.inventory.gold) + " Gold"
+
+ # Alte Slots entfernen
+ for child in item_grid.get_children():
+ child.queue_free()
+
+ # Slots erstellen (immer MAX_SLOTS anzeigen)
+ for i in range(Inventory.MAX_SLOTS):
+ var slot = _create_slot(i)
+ item_grid.add_child(slot)
+
+func _create_slot(index: int) -> Panel:
+ var slot = Panel.new()
+ slot.custom_minimum_size = Vector2(SLOT_SIZE, SLOT_SIZE)
+
+ # Slot-Hintergrund stylen
+ var style = StyleBoxFlat.new()
+ style.bg_color = Color(0.15, 0.15, 0.15)
+ style.border_color = Color(0.3, 0.3, 0.3)
+ style.set_border_width_all(1)
+ slot.add_theme_stylebox_override("panel", style)
+
+ # Item vorhanden?
+ if player.inventory and index < player.inventory.item_count():
+ var item = player.inventory.get_item(index)
+ if item:
+ # Item-Name Label
+ var label = Label.new()
+ label.text = item.item_name.substr(0, 3) # Erste 3 Buchstaben
+ label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
+ label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
+ label.add_theme_font_size_override("font_size", 10)
+ label.modulate = Equipment.get_rarity_color(item.rarity)
+ label.anchors_preset = Control.PRESET_FULL_RECT
+ slot.add_child(label)
+
+ # Rahmen in Seltenheitsfarbe
+ style.border_color = Equipment.get_rarity_color(item.rarity)
+ style.set_border_width_all(2)
+
+ # Klick-Handler
+ slot.gui_input.connect(_on_slot_clicked.bind(index, item))
+
+ # Tooltip
+ slot.tooltip_text = _get_item_tooltip(item)
+
+ return slot
+
+func _on_slot_clicked(event: InputEvent, index: int, item: Equipment):
+ if event is InputEventMouseButton and event.pressed:
+ if event.button_index == MOUSE_BUTTON_LEFT:
+ # Linksklick: Item auswählen/anlegen
+ item_selected.emit(item, index)
+ elif event.button_index == MOUSE_BUTTON_RIGHT:
+ # Rechtsklick: Item direkt anlegen
+ if player:
+ var old_item = player.equip_item(item)
+ player.inventory.remove_item(item)
+ if old_item:
+ player.inventory.add_item(old_item)
+ _refresh_inventory()
+
+func _get_item_tooltip(item: Equipment) -> String:
+ var tooltip = item.item_name + "\n"
+ tooltip += Equipment.get_slot_name(item.slot) + "\n"
+ tooltip += "---\n"
+
+ if item.slot == Equipment.Slot.WEAPON:
+ tooltip += "Schaden: " + str(item.min_damage) + "-" + str(item.max_damage) + "\n"
+ tooltip += "Tempo: " + str(item.attack_speed) + "s\n"
+
+ if item.armor > 0:
+ tooltip += "Rüstung: +" + str(item.armor) + "\n"
+ if item.strength > 0:
+ tooltip += "Stärke: +" + str(item.strength) + "\n"
+ if item.agility > 0:
+ tooltip += "Beweglichkeit: +" + str(item.agility) + "\n"
+ if item.intelligence > 0:
+ tooltip += "Intelligenz: +" + str(item.intelligence) + "\n"
+ if item.stamina > 0:
+ tooltip += "Ausdauer: +" + str(item.stamina) + "\n"
+ if item.haste > 0:
+ tooltip += "Tempo: +" + str(int(item.haste * 100)) + "%\n"
+
+ tooltip += "\n[Rechtsklick zum Anlegen]"
+ return tooltip
diff --git a/inventory_panel.gd.uid b/inventory_panel.gd.uid
new file mode 100644
index 0000000..2be1619
--- /dev/null
+++ b/inventory_panel.gd.uid
@@ -0,0 +1 @@
+uid://bjmcu0tyxqxmd
diff --git a/inventory_panel.tscn b/inventory_panel.tscn
new file mode 100644
index 0000000..b31478d
--- /dev/null
+++ b/inventory_panel.tscn
@@ -0,0 +1,63 @@
+[gd_scene format=3 uid="uid://inventory_panel"]
+
+[ext_resource type="Script" path="res://inventory_panel.gd" id="1_panel"]
+
+[node name="InventoryPanel" type="CanvasLayer"]
+script = ExtResource("1_panel")
+
+[node name="Panel" type="Panel" parent="."]
+anchors_preset = 6
+anchor_left = 1.0
+anchor_top = 0.5
+anchor_right = 1.0
+anchor_bottom = 0.5
+offset_left = -320.0
+offset_top = -250.0
+offset_right = -20.0
+offset_bottom = 250.0
+grow_horizontal = 0
+grow_vertical = 2
+
+[node name="VBoxContainer" type="VBoxContainer" parent="Panel"]
+layout_mode = 1
+anchors_preset = 15
+anchor_right = 1.0
+anchor_bottom = 1.0
+offset_left = 10.0
+offset_top = 10.0
+offset_right = -10.0
+offset_bottom = -10.0
+grow_horizontal = 2
+grow_vertical = 2
+theme_override_constants/separation = 8
+
+[node name="Header" type="HBoxContainer" parent="Panel/VBoxContainer"]
+layout_mode = 2
+
+[node name="Title" type="Label" parent="Panel/VBoxContainer/Header"]
+layout_mode = 2
+size_flags_horizontal = 3
+theme_override_font_sizes/font_size = 20
+text = "Inventar"
+
+[node name="GoldLabel" type="Label" parent="Panel/VBoxContainer/Header"]
+layout_mode = 2
+theme_override_font_sizes/font_size = 16
+theme_override_colors/font_color = Color(1, 0.85, 0, 1)
+text = "0 Gold"
+horizontal_alignment = 2
+
+[node name="HSeparator" type="HSeparator" parent="Panel/VBoxContainer"]
+layout_mode = 2
+
+[node name="ScrollContainer" type="ScrollContainer" parent="Panel/VBoxContainer"]
+layout_mode = 2
+size_flags_vertical = 3
+
+[node name="ItemGrid" type="GridContainer" parent="Panel/VBoxContainer/ScrollContainer"]
+layout_mode = 2
+size_flags_horizontal = 3
+size_flags_vertical = 3
+theme_override_constants/h_separation = 5
+theme_override_constants/v_separation = 5
+columns = 5
diff --git a/loot_entry.gd b/loot_entry.gd
new file mode 100644
index 0000000..c84dbaa
--- /dev/null
+++ b/loot_entry.gd
@@ -0,0 +1,7 @@
+# LootEntry.gd
+# Ein einzelner Eintrag in einer LootTable
+extends Resource
+class_name LootEntry
+
+@export var item: Equipment
+@export_range(0.0, 1.0) var drop_chance: float = 0.1 # 10% Standard
diff --git a/loot_entry.gd.uid b/loot_entry.gd.uid
new file mode 100644
index 0000000..1b7af3a
--- /dev/null
+++ b/loot_entry.gd.uid
@@ -0,0 +1 @@
+uid://cx2w8nkuoylv5
diff --git a/loot_table.gd b/loot_table.gd
new file mode 100644
index 0000000..ae688e8
--- /dev/null
+++ b/loot_table.gd
@@ -0,0 +1,24 @@
+# LootTable.gd
+# Definiert mögliche Drops eines Gegners
+extends Resource
+class_name LootTable
+
+# Gold-Drop
+@export var min_gold: int = 1
+@export var max_gold: int = 5
+
+# Item-Drops mit Wahrscheinlichkeiten
+@export var possible_drops: Array[LootEntry] = []
+
+# Generiert Loot basierend auf Tabelle
+func generate_loot() -> Dictionary:
+ var result = {
+ "gold": randi_range(min_gold, max_gold),
+ "items": []
+ }
+
+ for entry in possible_drops:
+ if randf() <= entry.drop_chance:
+ result["items"].append(entry.item)
+
+ return result
diff --git a/loot_table.gd.uid b/loot_table.gd.uid
new file mode 100644
index 0000000..c5e4b89
--- /dev/null
+++ b/loot_table.gd.uid
@@ -0,0 +1 @@
+uid://dej1tpamsi71r