Structure Refactor
This commit is contained in:
parent
df727c4c88
commit
98199a1543
44 changed files with 143 additions and 197 deletions
|
|
@ -3,17 +3,7 @@ class_name SaveLoad
|
||||||
const SAVE_PATH = "user://player_data.json"
|
const SAVE_PATH = "user://player_data.json"
|
||||||
|
|
||||||
static func save_character(data: CharacterData):
|
static func save_character(data: CharacterData):
|
||||||
var save_dict = {
|
var save_dict = data.to_dict()
|
||||||
"id": data.id,
|
|
||||||
"name": data.name,
|
|
||||||
"level": data.level,
|
|
||||||
"area": data.area,
|
|
||||||
"position": { # Vector3 als Dictionary speichern
|
|
||||||
"x": data.position.x,
|
|
||||||
"y": data.position.y,
|
|
||||||
"z": data.position.z
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
||||||
if file:
|
if file:
|
||||||
|
|
@ -35,11 +25,7 @@ static func load_character() -> CharacterData:
|
||||||
return null
|
return null
|
||||||
|
|
||||||
var char_data = CharacterData.new()
|
var char_data = CharacterData.new()
|
||||||
char_data.id = data["id"]
|
char_data.from_dict(data)
|
||||||
char_data.name = data["name"]
|
|
||||||
char_data.level = data["level"]
|
|
||||||
char_data.area = data["area"]
|
|
||||||
char_data.position = Vector3(data["position"]["x"],data["position"]["y"],data["position"]["z"])
|
|
||||||
print("Loaded player data from ", SAVE_PATH)
|
print("Loaded player data from ", SAVE_PATH)
|
||||||
return char_data
|
return char_data
|
||||||
else:
|
else:
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
signal ui_join_requested(ip: String, username: String, password: String)
|
signal ui_join_requested(ip: String, username: String, password: String)
|
||||||
|
|
||||||
signal ui_host_requested()
|
signal ui_host_requested()
|
||||||
|
signal ui_create_character_screen()
|
||||||
signal player_area_join_requested(area_key: String)
|
signal ui_character_created(character: CharacterData)
|
||||||
|
signal ui_character_select()
|
||||||
signal ui_area_join_requested(area_key: String)
|
signal ui_area_join_requested(area_key: String)
|
||||||
|
|
||||||
|
signal player_area_join_requested(area_key: String)
|
||||||
|
|
||||||
signal network_show_characters(characters:Array)
|
signal network_show_characters(characters:Array)
|
||||||
|
signal network_new_character_received(character: CharacterData)
|
||||||
signal ui_create_character_screen()
|
|
||||||
|
|
||||||
signal ui_character_created(character: CharacterData)
|
|
||||||
|
|
||||||
signal ui_character_select()
|
|
||||||
|
|
@ -8,8 +8,8 @@ var local_camera: Camera3D = null
|
||||||
|
|
||||||
# Mapping der Areas
|
# Mapping der Areas
|
||||||
var area_paths = {
|
var area_paths = {
|
||||||
"keuwin_grasland": "res://maps/outdoor/grass/keuwin_grasland.tscn",
|
"keuwin_grasland": "res://05_worlds/area/outdoor/grass/keuwin_grasland.tscn",
|
||||||
"ahnenhalle": "res://maps/planes/fugue/halle_der_ahnen.tscn"
|
"ahnenhalle": "res://05_worlds/area/planes/fugue/halle_der_ahnen.tscn"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Server-seitiges Tracking: peer_id -> SubViewportContainer
|
# Server-seitiges Tracking: peer_id -> SubViewportContainer
|
||||||
|
|
@ -18,6 +18,7 @@ var player_worlds = {}
|
||||||
func _ready():
|
func _ready():
|
||||||
GameEvents.ui_host_requested.connect(host_game)
|
GameEvents.ui_host_requested.connect(host_game)
|
||||||
GameEvents.ui_join_requested.connect(join_game)
|
GameEvents.ui_join_requested.connect(join_game)
|
||||||
|
GameEvents.ui_character_created.connect(request_character_store)
|
||||||
|
|
||||||
if DisplayServer.get_name() == "headless" or OS.get_cmdline_args().has("--server"):
|
if DisplayServer.get_name() == "headless" or OS.get_cmdline_args().has("--server"):
|
||||||
host_game()
|
host_game()
|
||||||
|
|
@ -158,7 +159,7 @@ func cl_load_area(area_key):
|
||||||
func setup_client_camera(node):
|
func setup_client_camera(node):
|
||||||
local_camera = Camera3D.new()
|
local_camera = Camera3D.new()
|
||||||
local_camera.name = "Camera3D"
|
local_camera.name = "Camera3D"
|
||||||
local_camera.set_script(load("res://systems/player/camera_logic.gd"))
|
local_camera.set_script(load("res://01_core/components/camera_logic.gd"))
|
||||||
local_camera.current = true
|
local_camera.current = true
|
||||||
node.add_child(local_camera)
|
node.add_child(local_camera)
|
||||||
# Ein AudioListener gehört auf dem Client auch an die Kamera
|
# Ein AudioListener gehört auf dem Client auch an die Kamera
|
||||||
|
|
@ -224,8 +225,25 @@ func srv_handle_area_change_request(area_key: String):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Old viewport:", old_viewport)
|
print("Old viewport:", old_viewport)
|
||||||
|
|
||||||
print("Player for erasing not found:", id)
|
print("Player for erasing not found:", id)
|
||||||
|
|
||||||
# 2. Bestehende Funktion für den Wechsel aufrufen
|
# 2. Bestehende Funktion für den Wechsel aufrufen
|
||||||
change_player_area(id, area_key)
|
change_player_area(id, area_key)
|
||||||
|
|
||||||
|
func request_character_store(new_character: CharacterData):
|
||||||
|
var character_dict = new_character.to_dict()
|
||||||
|
srv_store_new_character.rpc_id(1,character_dict)
|
||||||
|
|
||||||
|
@rpc("any_peer", "call_remote", "reliable")
|
||||||
|
func srv_store_new_character(character_dict: Dictionary):
|
||||||
|
var new_character = CharacterData.new()
|
||||||
|
new_character.from_dict(character_dict)
|
||||||
|
# TODO: In Zukunft erhalten neue Charaktere einen area_key und position gesetzt
|
||||||
|
var client_id = multiplayer.get_remote_sender_id()
|
||||||
|
cl_receive_new_character.rpc_id(client_id, new_character.to_dict())
|
||||||
|
|
||||||
|
@rpc("authority", "call_remote", "reliable")
|
||||||
|
func cl_receive_new_character(char_dict: Dictionary):
|
||||||
|
var new_character = CharacterData.new()
|
||||||
|
new_character.from_dict(char_dict)
|
||||||
|
GameEvents.network_new_character_received.emit(new_character)
|
||||||
|
|
@ -4,12 +4,12 @@ importer="scene"
|
||||||
importer_version=1
|
importer_version=1
|
||||||
type="PackedScene"
|
type="PackedScene"
|
||||||
uid="uid://do451iws7munv"
|
uid="uid://do451iws7munv"
|
||||||
path="res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"
|
path="res://.godot/imported/dude.glb-ff042c8f74305db1da7e47c7a83b2cea.scn"
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/characters/humanoid/dude.glb"
|
source_file="res://02_library/meshes/humanoid/dude.glb"
|
||||||
dest_files=["res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"]
|
dest_files=["res://.godot/imported/dude.glb-ff042c8f74305db1da7e47c7a83b2cea.scn"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://dgjgtr82ye25d"]
|
[gd_scene format=3 uid="uid://dgjgtr82ye25d"]
|
||||||
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://bi22s15yeh6mw" path="res://assets/characters/humanoid/dude.tres" id="1_jchph"]
|
[ext_resource type="ArrayMesh" uid="uid://bi22s15yeh6mw" path="res://02_library/meshes/humanoid/dude.tres" id="1_jchph"]
|
||||||
|
|
||||||
[node name="Dude" type="MeshInstance3D" unique_id=1185543431]
|
[node name="Dude" type="MeshInstance3D" unique_id=1185543431]
|
||||||
mesh = ExtResource("1_jchph")
|
mesh = ExtResource("1_jchph")
|
||||||
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
|
@ -3,15 +3,15 @@
|
||||||
importer="texture"
|
importer="texture"
|
||||||
type="CompressedTexture2D"
|
type="CompressedTexture2D"
|
||||||
uid="uid://d1cyxxj8ypfu"
|
uid="uid://d1cyxxj8ypfu"
|
||||||
path="res://.godot/imported/logo_projekt_weltenauge.png-faafe98462d8081c55aa7ba6fc11610a.ctex"
|
path="res://.godot/imported/logo_projekt_weltenauge.png-050b0b56f8f1da7cb817f7c3bf842b44.ctex"
|
||||||
metadata={
|
metadata={
|
||||||
"vram_texture": false
|
"vram_texture": false
|
||||||
}
|
}
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
|
|
||||||
source_file="res://assets/icons/program/logo_projekt_weltenauge.png"
|
source_file="res://02_library/ui_assets/icons/program/logo_projekt_weltenauge.png"
|
||||||
dest_files=["res://.godot/imported/logo_projekt_weltenauge.png-faafe98462d8081c55aa7ba6fc11610a.ctex"]
|
dest_files=["res://.godot/imported/logo_projekt_weltenauge.png-050b0b56f8f1da7cb817f7c3bf842b44.ctex"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
[gd_scene format=3 uid="uid://bjurf8vfd1fg8"]
|
[gd_scene format=3 uid="uid://bjurf8vfd1fg8"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://dgjgtr82ye25d" path="res://assets/characters/humanoid/dude.tscn" id="1_2anqx"]
|
[ext_resource type="Script" uid="uid://bhym64rc7xtin" path="res://04_entities/player/player_controller.gd" id="1_pnayr"]
|
||||||
[ext_resource type="Script" uid="uid://bhym64rc7xtin" path="res://systems/player/player_controller.gd" id="1_ktl23"]
|
[ext_resource type="PackedScene" uid="uid://dgjgtr82ye25d" path="res://02_library/meshes/humanoid/dude.tscn" id="2_11qf6"]
|
||||||
|
|
||||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_ktl23"]
|
[sub_resource type="CylinderShape3D" id="CylinderShape3D_ktl23"]
|
||||||
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_fqfg4"]
|
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_fqfg4"]
|
||||||
|
|
||||||
[node name="CharacterBody3D" type="CharacterBody3D" unique_id=682006733 groups=["players"]]
|
[node name="CharacterBody3D" type="CharacterBody3D" unique_id=682006733 groups=["players"]]
|
||||||
script = ExtResource("1_ktl23")
|
script = ExtResource("1_pnayr")
|
||||||
interpolation_speed = 5.0
|
interpolation_speed = 5.0
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=159496934]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=159496934]
|
||||||
|
|
@ -20,7 +20,7 @@ shape = SubResource("CylinderShape3D_ktl23")
|
||||||
[node name="Visuals" type="Node3D" parent="." unique_id=1840405751]
|
[node name="Visuals" type="Node3D" parent="." unique_id=1840405751]
|
||||||
transform = Transform3D(-0.99988204, 0, 0.015358234, 0, 1, 0, -0.015358234, 0, -0.99988204, 0, 0, 0)
|
transform = Transform3D(-0.99988204, 0, 0.015358234, 0, 1, 0, -0.015358234, 0, -0.99988204, 0, 0, 0)
|
||||||
|
|
||||||
[node name="Dude" parent="Visuals" unique_id=1185543431 instance=ExtResource("1_2anqx")]
|
[node name="Dude" parent="Visuals" unique_id=1185543431 instance=ExtResource("2_11qf6")]
|
||||||
|
|
||||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1343500738]
|
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1343500738]
|
||||||
root_node = NodePath("../..")
|
root_node = NodePath("../..")
|
||||||
|
|
@ -5,6 +5,7 @@ extends Control
|
||||||
func _on_host_button_pressed() -> void:
|
func _on_host_button_pressed() -> void:
|
||||||
print("host pressed")
|
print("host pressed")
|
||||||
GameEvents.ui_host_requested.emit()
|
GameEvents.ui_host_requested.emit()
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
func _on_join_button_pressed():
|
func _on_join_button_pressed():
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://lb6btb6426mi"]
|
[gd_scene format=3 uid="uid://lb6btb6426mi"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c6yngwnpqsnpi" path="res://ui/account/login.gd" id="1_x74xt"]
|
[ext_resource type="Script" uid="uid://c6yngwnpqsnpi" path="res://04_entities/ui/windows/account/login.gd" id="1_x74xt"]
|
||||||
|
|
||||||
[node name="Login" type="Control" unique_id=1694671237]
|
[node name="Login" type="Control" unique_id=1694671237]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|
@ -12,7 +12,8 @@ func show_creation_screen():
|
||||||
func _on_create_button_pressed() -> void:
|
func _on_create_button_pressed() -> void:
|
||||||
var new_character = CharacterData.new()
|
var new_character = CharacterData.new()
|
||||||
new_character.name = name_line_edit.text
|
new_character.name = name_line_edit.text
|
||||||
GameEvents.ui_character_created.emit(new_character)
|
print("Create Button pressed")
|
||||||
|
GameEvents.ui_character_created.emit(new_character)
|
||||||
hide()
|
hide()
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://cdwkmx452hc4k"]
|
[gd_scene format=3 uid="uid://cdwkmx452hc4k"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://dx24rxnsd0eoj" path="res://ui/character_create/character_create.gd" id="1_mdh5q"]
|
[ext_resource type="Script" uid="uid://dx24rxnsd0eoj" path="res://04_entities/ui/windows/character_create/character_create.gd" id="1_mdh5q"]
|
||||||
|
|
||||||
[node name="CharacterCreate" type="Control" unique_id=2056198803]
|
[node name="CharacterCreate" type="Control" unique_id=2056198803]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|
@ -6,9 +6,9 @@ var characters: Array[CharacterData] = []
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
GameEvents.network_show_characters.connect(show_list)
|
GameEvents.network_show_characters.connect(show_list)
|
||||||
GameEvents.ui_character_created.connect(character_created)
|
GameEvents.network_new_character_received.connect(receive_new_character)
|
||||||
|
|
||||||
func character_created(character):
|
func receive_new_character(character: CharacterData):
|
||||||
characters.append(character)
|
characters.append(character)
|
||||||
character_item_list.add_item(character.name)
|
character_item_list.add_item(character.name)
|
||||||
show()
|
show()
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://ca2bhph2k3xpy"]
|
[gd_scene format=3 uid="uid://ca2bhph2k3xpy"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://b5htxbkq23mo6" path="res://ui/character_select/character_select.gd" id="1_o7qwi"]
|
[ext_resource type="Script" uid="uid://b5htxbkq23mo6" path="res://04_entities/ui/windows/character_select/character_select.gd" id="1_o7qwi"]
|
||||||
|
|
||||||
[node name="CharacterSelect" type="Control" unique_id=2056198803]
|
[node name="CharacterSelect" type="Control" unique_id=2056198803]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://h5qt2pcidh8x"]
|
[gd_scene format=3 uid="uid://h5qt2pcidh8x"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://coq1j1cdrvqyn" path="res://systems/interaction/portal/portal.tscn" id="1_1yg6u"]
|
[ext_resource type="PackedScene" uid="uid://coq1j1cdrvqyn" path="res://05_worlds/prefabs/portal/portal.tscn" id="1_1yg6u"]
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://bef0tj7n6g8uo"]
|
[gd_scene format=3 uid="uid://bef0tj7n6g8uo"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://coq1j1cdrvqyn" path="res://systems/interaction/portal/portal.tscn" id="1_4r2hu"]
|
[ext_resource type="PackedScene" uid="uid://coq1j1cdrvqyn" path="res://05_worlds/prefabs/portal/portal.tscn" id="1_4r2hu"]
|
||||||
|
|
||||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
||||||
sky_top_color = Color(0.055328622, 0.3637527, 0.67898166, 1)
|
sky_top_color = Color(0.055328622, 0.3637527, 0.67898166, 1)
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://coq1j1cdrvqyn"]
|
[gd_scene format=3 uid="uid://coq1j1cdrvqyn"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://c23uu6akws8nj" path="res://systems/interaction/portal/portal.gd" id="1_8dnr8"]
|
[ext_resource type="Script" uid="uid://c23uu6akws8nj" path="res://05_worlds/prefabs/portal/portal.gd" id="1_8dnr8"]
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_h1tlh"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_h1tlh"]
|
||||||
size = Vector3(3.2, 1, 1)
|
size = Vector3(3.2, 1, 1)
|
||||||
|
|
@ -24,17 +24,48 @@
|
||||||
|
|
||||||
Alle Skripte und die dazugehörige Logik sollen thematisch in Unterordnern unter `res://systems/` abgelegt werden:
|
Alle Skripte und die dazugehörige Logik sollen thematisch in Unterordnern unter `res://systems/` abgelegt werden:
|
||||||
|
|
||||||
- `/core/`: Haupt-Game-Loop, State-Machine (Laden, Menü, Spiel).
|
/project_root
|
||||||
- `/network/`: Peer-Verbindung, Headless-Logik, Synchronisation, RPCs.
|
│
|
||||||
- `/player/`: Input-Handling, Kamera-Steuerung, lokale Charakter-Steuerung.
|
├── 01_core/ # Die Logik (Script-only, Architektur)
|
||||||
- `/ai/`: NPC-Verhaltenslogik (z.B. Behavior Trees).
|
│ ├── systems/ # Globale Manager (Autoloads): network.gd, game_state.gd, signal_bus.gd
|
||||||
- `/combat/`: Kampfsystem, Trefferberechnung, Würfelwürfe.
|
│ ├── components/ # Logik-Nodes: health_component.gd, interactor.gd, inventory_controller.gd
|
||||||
- `/dialogue/`: Gesprächs-System.
|
│ └── base_classes/ # Definitionen & Klassen: item_data.gd, spell_base.gd, entity_base.gd
|
||||||
- `/inventory/`: Item-Management, Ausrüstung, Truhen.
|
│
|
||||||
- `/interaction/`: Interaktionslogik für Türen, Hebel, Portale.
|
├── 02_library/ # Das Rohmaterial (Assets & Bausteine)
|
||||||
- `/navigation/`: A-Stern (AStar) Pfadfindungs-Logik.
|
│ ├── meshes/ # 3D-Importe (.glb, .obj) nach Kategorien: nature/, architecture/
|
||||||
- `/data/`: Speicher-Logik, Daten-Wrapper (z.B. für JSON, SQLite).
|
│ ├── mesh_libraries/ # Deine fertigen GridMap-Kataloge (.tres)
|
||||||
- `/ui/`: (Existierender Ordner) UI-Szenen und Skripte.
|
│ ├── materials/ # Globale Materialien (.tres): wood.tres, stone.tres, metal.tres
|
||||||
|
│ ├── textures/ # Roh-Bilder für Materialien & Shader
|
||||||
|
│ ├── ui_assets/ # Visuelles Interface: icons/, fonts/, themes/
|
||||||
|
│ ├── shaders/ # Shader-Dateien (.gdshader)
|
||||||
|
│ ├── vfx/ # Partikelsysteme und visuelle Effekte
|
||||||
|
│ └── audio/ # Sound-Dateien: sfx/, music/, ambient/
|
||||||
|
│
|
||||||
|
├── 03_database/ # Die Spieldaten (Content-Definitionen)
|
||||||
|
│ ├── items/ # Hunderte .tres Dateien (iron_sword.tres, health_potion.tres)
|
||||||
|
│ ├── spells/ # Zaubersprüche als Resources (.tres)
|
||||||
|
│ ├── loot_tables/ # Definitionen für Drops und Wahrscheinlichkeiten
|
||||||
|
│ ├── dialogues/ # Dialog-Skripte oder JSON-Dateien
|
||||||
|
│ ├── localization/ # Übersetzungsdateien (.csv, .po)
|
||||||
|
│ └── spawn_tables/ # Definitionen: Welche Monster-Gruppe spawnt in welcher Area?
|
||||||
|
│
|
||||||
|
├── 04_entities/ # Die Spielobjekte (Zusammengesetzte Szenen)
|
||||||
|
│ ├── player/ # Spieler-Szene (player.tscn + player.gd)
|
||||||
|
│ ├── npcs/ # Monster, Händler, KI-Gegner
|
||||||
|
│ ├── props/ # Interaktive Welt-Objekte: chest.tscn, door.tscn
|
||||||
|
│ ├── pickups/ # Das world_item.tscn (Visualisierung von Database-Items)
|
||||||
|
│ ├── ui/ # UI-Szenen: hud/, windows/, menus/, shared/
|
||||||
|
│ └── markers/ # Unsichtbare Helfer: spawn_point.tscn, area_trigger.tscn
|
||||||
|
│
|
||||||
|
├── 05_worlds/ # Die Level (Das "NWN Modul")
|
||||||
|
│ ├── areas/ # Die eigentlichen Karten/Level (.tscn)
|
||||||
|
│ ├── prefabs/ # Wiederverwendbare Szenen-Gruppen (Häuser, Lagerfeuer-Sets)
|
||||||
|
│ └── environments/ # Licht- & Welt-Einstellungen (.tres)
|
||||||
|
│
|
||||||
|
└── 06_tests/ # Die Sandkästen (Isolierte Prototypen)
|
||||||
|
├── test_ui.tscn # Nur UI-Fenster testen
|
||||||
|
├── test_combat.tscn # Kampf-Mechanik ohne Level testen
|
||||||
|
└── test_inventory.tscn # Item-Logik prüfen
|
||||||
|
|
||||||
## 4. Wichtige Dateien & Szenen
|
## 4. Wichtige Dateien & Szenen
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
[gd_scene format=3 uid="uid://cpxxy0664jyjm"]
|
[gd_scene format=3 uid="uid://cpxxy0664jyjm"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://162cjpb4lac4" path="res://game_root.gd" id="1_xj5yv"]
|
[ext_resource type="Script" uid="uid://162cjpb4lac4" path="res://game_root.gd" id="1_xj5yv"]
|
||||||
[ext_resource type="PackedScene" uid="uid://ca2bhph2k3xpy" path="res://ui/character_select/character_select.tscn" id="3_bxsma"]
|
[ext_resource type="PackedScene" uid="uid://ca2bhph2k3xpy" path="res://04_entities/ui/windows/character_select/character_select.tscn" id="3_bxsma"]
|
||||||
[ext_resource type="PackedScene" uid="uid://lb6btb6426mi" path="res://ui/account/login.tscn" id="3_lkrbl"]
|
[ext_resource type="PackedScene" uid="uid://lb6btb6426mi" path="res://04_entities/ui/windows/account/login.tscn" id="3_lkrbl"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cdwkmx452hc4k" path="res://ui/character_create/character_create.tscn" id="4_lkrbl"]
|
[ext_resource type="PackedScene" uid="uid://cdwkmx452hc4k" path="res://04_entities/ui/windows/character_create/character_create.tscn" id="4_lkrbl"]
|
||||||
|
|
||||||
[node name="Game_root" type="Node2D" unique_id=1336425327]
|
[node name="Game_root" type="Node2D" unique_id=1336425327]
|
||||||
script = ExtResource("1_xj5yv")
|
script = ExtResource("1_xj5yv")
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
|
|
||||||
|
Before Width: | Height: | Size: 995 B |
|
|
@ -1,43 +0,0 @@
|
||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://d4fyt5amswlam"
|
|
||||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://icon.svg"
|
|
||||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.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
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[gd_scene format=3 uid="uid://2fal1f0f8fdh"]
|
[gd_scene format=3 uid="uid://dvmffuxafo75u"]
|
||||||
|
|
||||||
[ext_resource type="ArrayMesh" uid="uid://bi22s15yeh6mw" path="res://assets/characters/humanoid/dude.tres" id="1_ig7tw"]
|
[ext_resource type="ArrayMesh" uid="uid://bi22s15yeh6mw" path="res://02_library/meshes/humanoid/dude.tres" id="1_ig7tw"]
|
||||||
|
|
||||||
[node name="Node3D" type="Node3D" unique_id=1431241737]
|
[node name="Node3D" type="Node3D" unique_id=1431241737]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ run/main_scene="uid://cpxxy0664jyjm"
|
||||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||||
run/low_processor_mode=true
|
run/low_processor_mode=true
|
||||||
boot_splash/image="uid://d1cyxxj8ypfu"
|
boot_splash/image="uid://d1cyxxj8ypfu"
|
||||||
config/icon="res://icon.svg"
|
config/icon="uid://d1cyxxj8ypfu"
|
||||||
boot_splash/minimum_display_time=1000
|
boot_splash/minimum_display_time=1000
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
# test_player_movement.gd
|
|
||||||
extends Node
|
|
||||||
|
|
||||||
#@onready var multiplayer = MultiplayerPeerExtension.new()
|
|
||||||
var player: CharacterBody3D
|
|
||||||
var initial_position: Vector3
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
# 1. Szene laden
|
|
||||||
var test_scene = load("res://maps/outdoor/grass/keuwin_grasland.tscn").instantiate()
|
|
||||||
add_child(test_scene)
|
|
||||||
|
|
||||||
# 2. MultiplayerSpawner finden und Player erstellen
|
|
||||||
var spawner = test_scene.get_node("AreaSpawner")
|
|
||||||
if not spawner:
|
|
||||||
printerr("Kein Spawner gefunden!")
|
|
||||||
queue_free() # Test beenden
|
|
||||||
|
|
||||||
# Test-Spieler erstellen
|
|
||||||
var player_scene = load("res://systems/player/player.tscn")
|
|
||||||
player = player_scene.instantiate()
|
|
||||||
player.name = "TestPlayer"
|
|
||||||
spawner.get_parent().add_child(player)
|
|
||||||
|
|
||||||
# Initialen Zustand speichern
|
|
||||||
initial_position = player.global_position
|
|
||||||
print("Initial position: ", initial_position)
|
|
||||||
|
|
||||||
# 3. Test starten (verzögert, damit alles geladen ist)
|
|
||||||
call_deferred("start_test")
|
|
||||||
|
|
||||||
func start_test():
|
|
||||||
print("Starte Bewegungstest...")
|
|
||||||
|
|
||||||
# Simulieren eines Klicks
|
|
||||||
var target_position = Vector3(5, 0, 5) # Irgendein Punkt in der Nähe
|
|
||||||
print("Simuliere Klick auf: ", target_position)
|
|
||||||
|
|
||||||
# Hier MÜSSEN wir den RPC direkt aufrufen. InputEvent geht nicht.
|
|
||||||
player.server_request_move.rpc_id(1, target_position) # 1 = Server
|
|
||||||
|
|
||||||
# Auf Bewegung warten (etwas unsauber, aber für den Moment ok)
|
|
||||||
await get_tree().create_timer(1.0).timeout # Warte 1 Sekunde
|
|
||||||
|
|
||||||
# Ergebnis überprüfen
|
|
||||||
var new_position = player.global_position
|
|
||||||
print("Neue Position: ", new_position)
|
|
||||||
|
|
||||||
# Toleranz, da die Bewegung nicht exakt sein muss
|
|
||||||
var tolerance = 0.5
|
|
||||||
if new_position.distance_to(initial_position) > tolerance:
|
|
||||||
print("Test erfolgreich! Avatar hat sich bewegt.")
|
|
||||||
else:
|
|
||||||
printerr("Test fehlgeschlagen! Avatar hat sich nicht bewegt.")
|
|
||||||
|
|
||||||
# Test beenden (optional)
|
|
||||||
queue_free()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""Erläuterungen:
|
|
||||||
|
|
||||||
1.) Szene laden: Lädt eine Test-Szene (keuwin_grasland.tscn). Das heisst, diese muss eine Spawner Instanz mit dem Namen AreaSpawner enthalten.
|
|
||||||
2.) Avatar erzeugen: Sucht den Spawner und erzeugt einen Avatar (keinen Multiplayer, nur lokal für den Test).
|
|
||||||
3.) Test starten (deferred): Startet den Test in start_test(), um sicherzustellen, dass alles geladen ist.
|
|
||||||
4.) Simulierter Klick: Sendet den request_move-RPC direkt an den Avatar.
|
|
||||||
5.) Warten: Wartet 1 Sekunde (eine sehr einfache, blockierende Methode).
|
|
||||||
6.) Ergebnis prüfen: Vergleicht die neue Position mit der alten.
|
|
||||||
|
|
||||||
Wie man diesen Test benutzt:
|
|
||||||
|
|
||||||
1.) Erstelle eine neue Szene (z.B. test_scene.tscn).
|
|
||||||
2.) Füge einen Node vom Typ Node als Root hinzu.
|
|
||||||
3.) Speichere das obige Skript (test_player_movement.gd) im Ordner /systems/player/.
|
|
||||||
3.) Füge ein Script Node hinzu und weise ihm das Skript test_player_movement.gd zu.
|
|
||||||
4.) Starte die Szene test_scene.tscn.
|
|
||||||
5.) Das Skript sollte automatisch ablaufen, die Ergebnisse in der Konsole ausgeben und sich dann selbst beenden.
|
|
||||||
|
|
||||||
Wichtige Einschränkungen:
|
|
||||||
|
|
||||||
Kein echter Multiplayer: Dies ist ein reiner Einzelspieler-Test. Er prüft nur, ob sich der lokale Avatar bewegt.
|
|
||||||
Blockierendes Warten: Die Verwendung von create_timer(1.0).timeout.await blockiert den Haupt-Thread. Für einen echten Test wäre das schlecht, aber für unseren einfachen Zweck ist es akzeptabel.
|
|
||||||
Geringe Präzision: Der Toleranzwert von 0.5 bedeutet, dass kleine Bewegungen möglicherweise nicht erkannt werden.
|
|
||||||
Keine Fehlerbehandlung: Wenn irgendetwas schiefgeht (kein Spawner, keine Szene, falscher Node-Name), bricht der Test einfach ab.
|
|
||||||
Auch mit diesen Einschränkungen ist dieser Test extrem wertvoll. Er gibt uns eine schnelle und einfache Möglichkeit, um sicherzustellen, dass die grundlegende Click-to-Move-Mechanik weiterhin funktioniert, wenn wir Änderungen am Code vornehmen."""
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
uid://c8p3yn461hle1
|
|
||||||
42
weltenauge_struktur.txt
Normal file
42
weltenauge_struktur.txt
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
/project_root
|
||||||
|
│
|
||||||
|
├── 01_core/ # Die Logik (Script-only, Architektur)
|
||||||
|
│ ├── systems/ # Globale Manager (Autoloads): network.gd, game_state.gd, signal_bus.gd
|
||||||
|
│ ├── components/ # Logik-Nodes: health_component.gd, interactor.gd, inventory_controller.gd
|
||||||
|
│ └── base_classes/ # Definitionen & Klassen: item_data.gd, spell_base.gd, entity_base.gd
|
||||||
|
│
|
||||||
|
├── 02_library/ # Das Rohmaterial (Assets & Bausteine)
|
||||||
|
│ ├── meshes/ # 3D-Importe (.glb, .obj) nach Kategorien: nature/, architecture/
|
||||||
|
│ ├── mesh_libraries/ # Deine fertigen GridMap-Kataloge (.tres)
|
||||||
|
│ ├── materials/ # Globale Materialien (.tres): wood.tres, stone.tres, metal.tres
|
||||||
|
│ ├── textures/ # Roh-Bilder für Materialien & Shader
|
||||||
|
│ ├── ui_assets/ # Visuelles Interface: icons/, fonts/, themes/
|
||||||
|
│ ├── shaders/ # Shader-Dateien (.gdshader)
|
||||||
|
│ ├── vfx/ # Partikelsysteme und visuelle Effekte
|
||||||
|
│ └── audio/ # Sound-Dateien: sfx/, music/, ambient/
|
||||||
|
│
|
||||||
|
├── 03_database/ # Die Spieldaten (Content-Definitionen)
|
||||||
|
│ ├── items/ # Hunderte .tres Dateien (iron_sword.tres, health_potion.tres)
|
||||||
|
│ ├── spells/ # Zaubersprüche als Resources (.tres)
|
||||||
|
│ ├── loot_tables/ # Definitionen für Drops und Wahrscheinlichkeiten
|
||||||
|
│ ├── dialogues/ # Dialog-Skripte oder JSON-Dateien
|
||||||
|
│ ├── localization/ # Übersetzungsdateien (.csv, .po)
|
||||||
|
│ └── spawn_tables/ # Definitionen: Welche Monster-Gruppe spawnt in welcher Area?
|
||||||
|
│
|
||||||
|
├── 04_entities/ # Die Spielobjekte (Zusammengesetzte Szenen)
|
||||||
|
│ ├── player/ # Spieler-Szene (player.tscn + player.gd)
|
||||||
|
│ ├── npcs/ # Monster, Händler, KI-Gegner
|
||||||
|
│ ├── props/ # Interaktive Welt-Objekte: chest.tscn, door.tscn
|
||||||
|
│ ├── pickups/ # Das world_item.tscn (Visualisierung von Database-Items)
|
||||||
|
│ ├── ui/ # UI-Szenen: hud/, windows/, menus/, shared/
|
||||||
|
│ └── markers/ # Unsichtbare Helfer: spawn_point.tscn, area_trigger.tscn
|
||||||
|
│
|
||||||
|
├── 05_worlds/ # Die Level (Das "NWN Modul")
|
||||||
|
│ ├── areas/ # Die eigentlichen Karten/Level (.tscn)
|
||||||
|
│ ├── prefabs/ # Wiederverwendbare Szenen-Gruppen (Häuser, Lagerfeuer-Sets)
|
||||||
|
│ └── environments/ # Licht- & Welt-Einstellungen (.tres)
|
||||||
|
│
|
||||||
|
└── 06_tests/ # Die Sandkästen (Isolierte Prototypen)
|
||||||
|
├── test_ui.tscn # Nur UI-Fenster testen
|
||||||
|
├── test_combat.tscn # Kampf-Mechanik ohne Level testen
|
||||||
|
└── test_inventory.tscn # Item-Logik prüfen
|
||||||
Loading…
Add table
Add a link
Reference in a new issue