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"
|
||||
|
||||
static func save_character(data: CharacterData):
|
||||
var save_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 save_dict = data.to_dict()
|
||||
|
||||
var file = FileAccess.open(SAVE_PATH, FileAccess.WRITE)
|
||||
if file:
|
||||
|
|
@ -35,11 +25,7 @@ static func load_character() -> CharacterData:
|
|||
return null
|
||||
|
||||
var char_data = CharacterData.new()
|
||||
char_data.id = data["id"]
|
||||
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"])
|
||||
char_data.from_dict(data)
|
||||
print("Loaded player data from ", SAVE_PATH)
|
||||
return char_data
|
||||
else:
|
||||
|
|
@ -1,16 +1,13 @@
|
|||
extends Node
|
||||
|
||||
signal ui_join_requested(ip: String, username: String, password: String)
|
||||
|
||||
signal ui_host_requested()
|
||||
|
||||
signal player_area_join_requested(area_key: String)
|
||||
signal ui_create_character_screen()
|
||||
signal ui_character_created(character: CharacterData)
|
||||
signal ui_character_select()
|
||||
signal ui_area_join_requested(area_key: String)
|
||||
|
||||
signal player_area_join_requested(area_key: String)
|
||||
|
||||
signal network_show_characters(characters:Array)
|
||||
|
||||
signal ui_create_character_screen()
|
||||
|
||||
signal ui_character_created(character: CharacterData)
|
||||
|
||||
signal ui_character_select()
|
||||
signal network_new_character_received(character: CharacterData)
|
||||
|
|
@ -8,8 +8,8 @@ var local_camera: Camera3D = null
|
|||
|
||||
# Mapping der Areas
|
||||
var area_paths = {
|
||||
"keuwin_grasland": "res://maps/outdoor/grass/keuwin_grasland.tscn",
|
||||
"ahnenhalle": "res://maps/planes/fugue/halle_der_ahnen.tscn"
|
||||
"keuwin_grasland": "res://05_worlds/area/outdoor/grass/keuwin_grasland.tscn",
|
||||
"ahnenhalle": "res://05_worlds/area/planes/fugue/halle_der_ahnen.tscn"
|
||||
}
|
||||
|
||||
# Server-seitiges Tracking: peer_id -> SubViewportContainer
|
||||
|
|
@ -18,6 +18,7 @@ var player_worlds = {}
|
|||
func _ready():
|
||||
GameEvents.ui_host_requested.connect(host_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"):
|
||||
host_game()
|
||||
|
|
@ -158,7 +159,7 @@ func cl_load_area(area_key):
|
|||
func setup_client_camera(node):
|
||||
local_camera = Camera3D.new()
|
||||
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
|
||||
node.add_child(local_camera)
|
||||
# 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:
|
||||
print("Old viewport:", old_viewport)
|
||||
|
||||
print("Player for erasing not found:", id)
|
||||
|
||||
# 2. Bestehende Funktion für den Wechsel aufrufen
|
||||
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
|
||||
type="PackedScene"
|
||||
uid="uid://do451iws7munv"
|
||||
path="res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"
|
||||
path="res://.godot/imported/dude.glb-ff042c8f74305db1da7e47c7a83b2cea.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/characters/humanoid/dude.glb"
|
||||
dest_files=["res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"]
|
||||
source_file="res://02_library/meshes/humanoid/dude.glb"
|
||||
dest_files=["res://.godot/imported/dude.glb-ff042c8f74305db1da7e47c7a83b2cea.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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]
|
||||
mesh = ExtResource("1_jchph")
|
||||
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d1cyxxj8ypfu"
|
||||
path="res://.godot/imported/logo_projekt_weltenauge.png-faafe98462d8081c55aa7ba6fc11610a.ctex"
|
||||
path="res://.godot/imported/logo_projekt_weltenauge.png-050b0b56f8f1da7cb817f7c3bf842b44.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/icons/program/logo_projekt_weltenauge.png"
|
||||
dest_files=["res://.godot/imported/logo_projekt_weltenauge.png-faafe98462d8081c55aa7ba6fc11610a.ctex"]
|
||||
source_file="res://02_library/ui_assets/icons/program/logo_projekt_weltenauge.png"
|
||||
dest_files=["res://.godot/imported/logo_projekt_weltenauge.png-050b0b56f8f1da7cb817f7c3bf842b44.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
[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://systems/player/player_controller.gd" id="1_ktl23"]
|
||||
[ext_resource type="Script" uid="uid://bhym64rc7xtin" path="res://04_entities/player/player_controller.gd" id="1_pnayr"]
|
||||
[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"]
|
||||
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_fqfg4"]
|
||||
|
||||
[node name="CharacterBody3D" type="CharacterBody3D" unique_id=682006733 groups=["players"]]
|
||||
script = ExtResource("1_ktl23")
|
||||
script = ExtResource("1_pnayr")
|
||||
interpolation_speed = 5.0
|
||||
|
||||
[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]
|
||||
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]
|
||||
root_node = NodePath("../..")
|
||||
|
|
@ -5,6 +5,7 @@ extends Control
|
|||
func _on_host_button_pressed() -> void:
|
||||
print("host pressed")
|
||||
GameEvents.ui_host_requested.emit()
|
||||
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_MINIMIZED)
|
||||
hide()
|
||||
|
||||
func _on_join_button_pressed():
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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]
|
||||
layout_mode = 3
|
||||
|
|
@ -12,7 +12,8 @@ func show_creation_screen():
|
|||
func _on_create_button_pressed() -> void:
|
||||
var new_character = CharacterData.new()
|
||||
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()
|
||||
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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]
|
||||
layout_mode = 3
|
||||
|
|
@ -6,9 +6,9 @@ var characters: Array[CharacterData] = []
|
|||
|
||||
func _ready():
|
||||
GameEvents.network_show_characters.connect(show_list)
|
||||
GameEvents.ui_character_created.connect(character_created)
|
||||
|
||||
func character_created(character):
|
||||
GameEvents.network_new_character_received.connect(receive_new_character)
|
||||
|
||||
func receive_new_character(character: CharacterData):
|
||||
characters.append(character)
|
||||
character_item_list.add_item(character.name)
|
||||
show()
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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]
|
||||
layout_mode = 3
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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"]
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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"]
|
||||
sky_top_color = Color(0.055328622, 0.3637527, 0.67898166, 1)
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[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"]
|
||||
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:
|
||||
|
||||
- `/core/`: Haupt-Game-Loop, State-Machine (Laden, Menü, Spiel).
|
||||
- `/network/`: Peer-Verbindung, Headless-Logik, Synchronisation, RPCs.
|
||||
- `/player/`: Input-Handling, Kamera-Steuerung, lokale Charakter-Steuerung.
|
||||
- `/ai/`: NPC-Verhaltenslogik (z.B. Behavior Trees).
|
||||
- `/combat/`: Kampfsystem, Trefferberechnung, Würfelwürfe.
|
||||
- `/dialogue/`: Gesprächs-System.
|
||||
- `/inventory/`: Item-Management, Ausrüstung, Truhen.
|
||||
- `/interaction/`: Interaktionslogik für Türen, Hebel, Portale.
|
||||
- `/navigation/`: A-Stern (AStar) Pfadfindungs-Logik.
|
||||
- `/data/`: Speicher-Logik, Daten-Wrapper (z.B. für JSON, SQLite).
|
||||
- `/ui/`: (Existierender Ordner) UI-Szenen und Skripte.
|
||||
/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
|
||||
|
||||
## 4. Wichtige Dateien & Szenen
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
[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="PackedScene" uid="uid://ca2bhph2k3xpy" path="res://ui/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://cdwkmx452hc4k" path="res://ui/character_create/character_create.tscn" id="4_lkrbl"]
|
||||
[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://04_entities/ui/windows/account/login.tscn" id="3_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]
|
||||
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]
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ run/main_scene="uid://cpxxy0664jyjm"
|
|||
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||
run/low_processor_mode=true
|
||||
boot_splash/image="uid://d1cyxxj8ypfu"
|
||||
config/icon="res://icon.svg"
|
||||
config/icon="uid://d1cyxxj8ypfu"
|
||||
boot_splash/minimum_display_time=1000
|
||||
|
||||
[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