...
This commit is contained in:
parent
8f6e50f3d8
commit
30b6ade7c4
38 changed files with 1059 additions and 0 deletions
82
prompts/main.txt
Normal file
82
prompts/main.txt
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
Für mein NWN/Godot Projekt brauche ich eine Referenzimplementierung für die Client/Server Logik.
|
||||
Client und Server sind in der gleichen Codebase/Projekt. Normal aufgerufen, kann der Anwender
|
||||
Join und Host auswählen. Stellt das Programm fest, dass es headless läuft, wird automatisch als Host gestartet.
|
||||
Die Szenen(Areas) in denen die Spieler laden, werden nach bedarf geladen. Wenn Spieler A in Area 1 ist, hat sein
|
||||
Client nur Area 1 geladen. Wenn Spieler B in Area 2 ist, hat sein Client nur Area 2 geladen. Nur
|
||||
Host hat beide Areas geladen, und synchronisiert seine Area 1 mit Area 1 des Clients von Spieler A und
|
||||
seine Area 2 mit der Area 2 des Clients von Spieler B. Ein Übergang zu einer anderen Area kann vom Host veranlasst
|
||||
werden . Er lädt die neue Area(Szene) und erzeugt den Avatar des Spielers. Der Client des betroffenen Spielers
|
||||
muss die neue Area(Szene) auf seiner Seite ebenfalls laden, damit die Szenenobjekte synchronisiert werden können.
|
||||
|
||||
Sorge dafür, dass die Areas auf dem Server sich nicht überlagern. Jeder MultiPlayerSynchronizer sollte nur
|
||||
position der Spieler synchronisieren, aber nicht global_position.
|
||||
|
||||
Jede Area soll auf dem Server einen eigenen SubViewport haben. (Godot Multi-World Physics)
|
||||
Sorge mit Visibility Filtering dafür, dass die MultiplayerSynchronizer nur die Objekte in ihrer jeweiligen Area synchronisieren.
|
||||
|
||||
Aus Performancegründen soll die Click-to-Move Funktionalität über AStar implementiert werden.
|
||||
|
||||
Das Spielermodell liegt unter res://systems/player/player.tres
|
||||
Area 1 liegt unter res://maps/outdoor/grass/keuwin_grasland.tscn
|
||||
Area 2 liegt unter res://maps/planes/fugue/halle_der_ahnen.tscn
|
||||
|
||||
Alle Scripte müssen in einem thematisch passenden Subfolder unterhalb res://systems/ abgelegt werden.
|
||||
|
||||
Dies ist die Struktur des Projektes:
|
||||
|
||||
/assets/ # REINE ROHDATEN (Dumm, keine Spiellogik)
|
||||
/characters/
|
||||
/humanoid/
|
||||
/base_meshes/ # .glb Dateien und .tres (Mesh-Resources)
|
||||
/materials/ # .tres (Material-Resources)
|
||||
/environment/
|
||||
/dungeon/ # Tileset-Modelle
|
||||
/nature/ # Bäume, Steine
|
||||
/items/
|
||||
/armor/
|
||||
/weapons/
|
||||
/consumables/
|
||||
|
||||
/systems/ # DAS GEHIRN (Logik, muss auf dem Server laufen)
|
||||
/core/ # Game-Loop, Signale, State-Machine
|
||||
/network/ # Multiplayer, Peer-Handling, Headless-Logik
|
||||
/player/ # Player-Controller (ohne Kamera/UI)
|
||||
/ai/ # NPC-Verhalten, Monster-Logik
|
||||
/combat/ # Regelwerk, Würfelwürfe, Stats
|
||||
/dialogue/ # Gesprächs-Logik, Quests
|
||||
/inventory/ # Item-Management, Container
|
||||
/interaction/ # Türen, Hebel, Portale
|
||||
/navigation/ # AStar-Management, Pathfinder
|
||||
/simulation/ # Tag-Nacht-Zyklus, Fraktionen
|
||||
/data/ # Speicher-Logik, DB-Anbindung
|
||||
/fx/ # Wetter-Logik, Sound-Trigger
|
||||
|
||||
/ui/ # DAS GESICHT (Nur für den Client)
|
||||
/hud/ # Permanente Anzeigen (HP, Chat)
|
||||
/menus/ # Startmenü, Optionen
|
||||
/windows/ # Inventar-Fenster, Charakterbogen
|
||||
/components/ # Buttons, Slots, wiederverwendbare Teile
|
||||
/themes/ # Schriften, Styles, Visual Design
|
||||
|
||||
/maps/ # DIE WELT (Szenen, in denen man spielt)
|
||||
/templates/ # Basis-Setups für neue Karten
|
||||
/outdoor/ # Wald, Wüste, Gebirge
|
||||
/indoor/ # Häuser, Burgen
|
||||
/dungeons/ # Krypten, Höhlen
|
||||
/planes/ # Andere Existenzebenen
|
||||
|
||||
/audio/ # KLANGWELT
|
||||
/music/ # Hintergrundmusik (.ogg)
|
||||
/sfx/ # Geräusche (Schwert, Schritte)
|
||||
/ambience/ # Atmosphäre-Loops (Wind, Feuer)
|
||||
|
||||
/data/ # DIE DEFINITIONEN (Inhaltliche Datenkarten)
|
||||
/items/ # .tres Dateien für jedes Schwert/Schild
|
||||
/tables/ # SQLite .db oder JSON-Tabellen
|
||||
|
||||
/licencing/ # Rechtliches (Asset-Lizenzen)
|
||||
|
||||
|
||||
Erstelle bitte eine Referenzimplementierung, die folgende Funktionen abdeckt: Host Game, Join Game, Scenenwechsel, Server-Authority
|
||||
Erzeuge so wenige Dateien wie möglich.
|
||||
|
||||
3
tools/start_server.sh
Executable file
3
tools/start_server.sh
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#/opt/godot/Godot_v4.6-stable_linux.x86_64 --path /home/torsten/repos/weltenauge/weltenauge --headless -- --server
|
||||
#/opt/godot/Godot_v4.6-stable_linux.x86_64 --path /home/torsten/Dokumente/Gamedev/Projekt_Weltenauge/Projekt_Weltenauge --headless -- --server
|
||||
/opt/godot/Godot_v4.6-stable_linux.x86_64 --path /home/tschneider/Dokumente/GameDev/Projekt_Weltenauge/Projekt_Weltenauge --headless -- --server
|
||||
0
weltenauge/.continue/refactor-godot.prompt
Normal file
0
weltenauge/.continue/refactor-godot.prompt
Normal file
1
weltenauge/.cursorrules
Normal file
1
weltenauge/.cursorrules
Normal file
|
|
@ -0,0 +1 @@
|
|||
Always use Godot 4.x GDScript syntax. Prefer static typing (e.g., var x: int = 5) and use the @onready annotation for nodes.
|
||||
4
weltenauge/.editorconfig
Normal file
4
weltenauge/.editorconfig
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
3
weltenauge/.vscode/settings.json
vendored
Normal file
3
weltenauge/.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"godotTools.editorPath.godot4": "/opt/godot/godot_v4.6-stable_linux.x86_64"
|
||||
}
|
||||
BIN
weltenauge/assets/characters/humanoid/dude.glb
Normal file
BIN
weltenauge/assets/characters/humanoid/dude.glb
Normal file
Binary file not shown.
54
weltenauge/assets/characters/humanoid/dude.glb.import
Normal file
54
weltenauge/assets/characters/humanoid/dude.glb.import
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://do451iws7munv"
|
||||
path="res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/characters/humanoid/dude.glb"
|
||||
dest_files=["res://.godot/imported/dude.glb-2cdcb6b05658711e71be066b772220a0.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/root_script=null
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
nodes/use_name_suffixes=true
|
||||
nodes/use_node_type_suffixes=true
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
materials/extract=0
|
||||
materials/extract_format=0
|
||||
materials/extract_path=""
|
||||
_subresources={
|
||||
"meshes": {
|
||||
"Dude_Cube_002": {
|
||||
"generate/lightmap_uv": 0,
|
||||
"generate/lods": 0,
|
||||
"generate/shadow_meshes": 0,
|
||||
"lods/normal_merge_angle": 20.0,
|
||||
"save_to_file/enabled": true,
|
||||
"save_to_file/fallback_path": "res://assets/characters/humanoid/Dude.tres",
|
||||
"save_to_file/path": "uid://c6h0s0by6gg3n"
|
||||
}
|
||||
}
|
||||
}
|
||||
gltf/naming_version=2
|
||||
gltf/embedded_image_handling=1
|
||||
99
weltenauge/assets/characters/humanoid/dude.tres
Normal file
99
weltenauge/assets/characters/humanoid/dude.tres
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
[gd_resource type="ArrayMesh" format=4 uid="uid://bi22s15yeh6mw"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_h8qyk"]
|
||||
resource_name = "pink.002"
|
||||
cull_mode = 2
|
||||
albedo_color = Color(0.8201731, 0.17311497, 0.9063355, 1)
|
||||
roughness = 0.5
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_c6dnh"]
|
||||
resource_name = "schwarz"
|
||||
cull_mode = 2
|
||||
albedo_color = Color(0, 0, 0, 1)
|
||||
roughness = 0.5
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_i8imj"]
|
||||
resource_name = "weiss"
|
||||
cull_mode = 2
|
||||
albedo_color = Color(0.9063318, 0.9063318, 0.9063318, 1)
|
||||
roughness = 0.5
|
||||
|
||||
[sub_resource type="ArrayMesh" id="ArrayMesh_wt8sa"]
|
||||
_surfaces = [{
|
||||
"aabb": AABB(-0.28403106, 0.008408189, -0.083770275, 0.6, 0.6000001, 0.60000014),
|
||||
"format": 34896613377,
|
||||
"index_count": 582,
|
||||
"index_data": PackedByteArray("PQAGAD4APQAEAAYAPwAGAAQAQAAEAD0APwAEAEAAHAAGAD8AHAA+AAYAQQA/AEAAQgA9AD4AQAA9AEMAQwA9AEIARABAAEMAQQBAAEQAGAA/AEEAGAAcAD8ANABBAEQAHAAYABoAHAAaAB0AGAAZABoAHgAcAB0AHgA+ABwAHgAdABsAFgAbABkAGAAWABkAFgAeABsAEQAYAEEAEQBBADQARQAWABgARQAYABEARQARABIAEQANABIARQASABMAEQBGAA0ARgARADQARgALAA0ARwBFABMARwAWAEUARwATABUARwAfABYAHwAeABYAFABHABUAFAAfAEcAFAAVABAARgAIAAsACAAKAAsARgA0AEgACABGAEgASAA0AEkANABEAEkASQBEAEoARABDAEoASABJAEsASgBDAEwAQwBCAEwASQBKAE0ASwBJAE0ASgBMADUATQBKADUATgBIAEsACABIAE4ASwBNAE8ATQA1AFAATwBNAFAAUQBLAE8ATgBLAFEABwBOAFEAUgAIAE4AUgBOAAcABwBRAAAAAABSAAcAUQBPAFMAAABRAFMAUwBPAFQATwBQAFQAAABTAFUAAABVAFIAUwBUAFYAVQBTAFYAVABQAFcAVQBYAFIAWAAIAFIAVQBWAFkAVQBZAFgAVgBUAFoAVABXAFoAWQBWAFsAVgBaAFsAWABcAAgACABcAAoAXAAMAAoAXQBcAFgAWQBdAFgAXABeAAwAXQBeAFwAXgAOAAwAWQBfAF0AWQBbAF8AYABeAF0AXwBgAF0AXgAJAA4AYAAJAF4ACQAPAA4AXwBhAGAACQBiAA8AYgAQAA8AAgAJAGAAYQACAGAAYgAUABAAYQABAAIAAgAwAAkAMABiAAkAAQAwAAIAMgAUAGIAMAAyAGIAAQAxADAAMQAyADAAYQAxAAEAXwBjAGEAYQBjADEAXwBbAGMAMQAzADIAYwAzADEAWwBkAGMAYwBkADMAWwBaAGQAMwA8ADIAMgA8ABQAZABlADMAMwBlADwAWgBmAGQAZABmAGUAWgBXAGYAPAAXABQAZQA7ADwAPAA7ABcAZgBnAGUAZQBnADsAVwBoAGYAZgBoAGcAFAAXAB8AVwBpAGgAUABpAFcAUAA1AGkANQBqAGkANQBMAGoAaQBrAGgAaQBqAGsAaABrADgAaAA4AGcATAA2AGoATABCADYAagBsAGsAagA2AGwAawADADgAawBsAAMAOAADAAUAZwA4ADoAOAAFADoAZwA6ADsAAwA5AAUAAwBsADkAOgAFADkAOwA6ACEAOgA5ACEAbAA3ADkAbAA2ADcAIQA5ADcAOwAhABcANgBtADcANgBCAG0AQgA+AG0AHgBtAD4AIAA3AG0AIABtAB4AIQA3ACAAHwAgAB4AKgAhACsAKwAhACwAIQAqACkAIAAsACEAIQApABcAIAAtACwAIAAuAC0ALgAgAC8ALwAgACYAHwAmACAAHwAkACYAJAAfACMAIwAfACIAFwAiAB8AFwAlACIAFwAnACUAJwAXACgAKAAXACkA"),
|
||||
"lods": [0.00012957268, PackedByteArray("AAABAAIAAQAwAAIAAQAxADAAAAAxAAEAAgAwAAkAMQAyADAAMAAyAAkAMQAzADIAAAAzADEAAAACAAcAAgAIAAcAAgAJAAgABwAEAAAACAA0AAcABwA0AAQAAAAEADUAAAA1ADMANAAGAAQANQAEADYANgAEAAYANgADADUAEQAGADQACAARADQANgAGADcAAwA2ADcANQADADgANQA4ADMAOAADAAUAAwA3ADkAAwA5AAUAOAAFADoAOgAFADkAMwA4ADoAIQA5ADcAOgA5ACEAMwA6ADsAOwA6ACEAMwA7ADwAMwA8ADIAPAA7ABcAOwAhABcAMgA8ABQAPAAXABQAMgAUAAkAJwAXACgAFwAnACUAKAAXACkAIQApABcAFwAlACIAIQAqACkAKgAhACsAKwAhACwAFwAiAB8AFAAXAB8AIwAfACIAJAAfACMAIAAsACEAHwAkACYAHwAmACAALwAgACYAIQA3ACAALgAgAC8AIAAtACwAIAAuAC0AIAA3AAYAHwAgAB4AIAAGAB4AHwAeABYAFAAfABYAHgAGABwAHgAcAB0AHgAdABsAFgAeABsAHAAaAB0AFgAbABkAGAAcAAYAHAAYABoAGAAZABoAGAAWABkAEQAYAAYAEQAWABgAFAAWABEAFAARABMAEQASABMAFAATABUAEQANABIAFAAVABAAEQAIAA0ACAALAA0ACAAKAAsACAAMAAoACQAUABAACAAJAAwACQAQAA8ACQAOAAwACQAPAA4A"), 0.00025139967, PackedByteArray("AAABAAIAAAADAAEAAAAEAAMAAQADAAUAAQAFAAIAAwAEAAYAAwAGAAUABwAEAAAAAAACAAcABwAGAAQAAgAIAAcACAAGAAcAAgAJAAgAAgAFAAkACAAKAAsACAAMAAoACAALAA0ACAAJAAwACQAOAAwACQAPAA4ACQAQAA8AEQAIAA0AEQANABIACAARAAYAEQASABMACQAUABAAFAARABMAFAAVABAAFAATABUABQAUAAkAFAAWABEABQAXABQAEQAWABgAEQAYAAYAGAAWABkAGAAZABoAFgAbABkAHAAYABoAGAAcAAYAHAAaAB0AHgAdABsAHgAcAB0AFgAeABsAHgAGABwAFAAfABYAHwAeABYAFAAXAB8AIAAGAB4AIAAFAAYAHwAgAB4ABQAhABcAIQAFACAAFwAiAB8AIwAfACIAJAAfACMAFwAlACIAHwAkACYAHwAmACAAFwAnACUAJwAXACgAKAAXACkAIQApABcAIQAqACkAKgAhACsAKwAhACwAIAAsACEAIAAtACwAIAAuAC0ALgAgAC8ALwAgACYA")],
|
||||
"name": "pink.002",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 110,
|
||||
"vertex_data": PackedByteArray("AAAAAAAAAAD//wAAAAAAAP//AAD//wAA/////wAAAAAAAP//AAAAAP///////wAAAAD/////AAAAAAAA//8AADIzqir//wAAzMyqKv//AABlZqoqefAAADIzqip58AAAmZmqKnnwAAAyM1RVefAAAMzMqip58AAAzMxUVXnwAADMzP9/efAAADIz/3///wAAMjP/f3nwAABlZv9/efAAAMzM/3///wAAmZn/f3nwAABlZqqq//8AAMzMqqr//wAAMjOqqv//AABlZqqq+PMAADIzqqr48wAAZWZU1fjzAAAyM1TV//8AADIzVNX48wAAZWZU1f//AACZmaqq//8AAJmZVNX//wAAzMxU1f//AACZmaqqKOwAAJmZ/78o7AAAmZmpyijsAAAhoqqqKOwAAJmZVNUo7AAAqaqqqijsAAAys6qqKOwAAMzMqqoo7AAAzMz/vyjsAADMzKnKKOwAAMzMVNUo7AAAMrNU1SjsAACpqlTVKOwAACGiVNUo7AAA//+qKv//AAD//6oqAAAAAP//VFX//wAA//9UVQAAAAAAAP9///8AAGVmqqoAAAAAmZn//wAAAACZmf////8AAP//VNUAAAAAzMz/////AAD//1TV//8AAP//qqr//wAA////f///AAAyM///AAAAADIz/////wAAAABU1f//AAAAAFTVAAAAAAAAqqr//wAAZWb//wAAAAAyM1TVAAAAAAAAqqoAAAAAZWb/f///AAAyM1RV//8AAJmZ/3///wAAAABVVf//AAAAAP9/AAAAADIzqqoAAAAAAABUVQAAAABlZlTVAAAAADIz/38AAAAAAACqKv//AAAyM1RVAAAAAGVm/38AAAAAAACqKgAAAAAyMwAA//8AADIzqioAAAAAZWZUVQAAAAAyMwAAAAAAAGVmqioAAAAAmZn/fwAAAABlZgAA//8AAGVmAAAAAAAAmZlUVQAAAACZmaoqAAAAAGVmqir//wAAmZkAAP//AACZmaoq//8AAJmZAAAAAAAAzMwAAP//AADMzAAAAAAAAMzMVFX//wAAzMyqKgAAAADMzFRVAAAAAP///38AAAAAzMz/fwAAAAD//6qqAAAAAMzMqqoAAAAAmZmqqgAAAACZmVTVAAAAAMzMVNUAAAAAzMz//wAAAABlZv////8AAA==")
|
||||
}, {
|
||||
"aabb": AABB(-0.16403107, 0.10840821, 0.46973133, 0.36, 0.39999998, 0.03833282),
|
||||
"format": 34896613377,
|
||||
"index_count": 174,
|
||||
"index_data": PackedByteArray("CgALAAwACgANAAsACgAOAA0ADwAMAAsADQAOABAAEAAMAA8ADQARAAsACwARABIACwASAA8ADQATABEADwASABQAEAAVAA0AEAAPABUAFQATAA0ADwAUABUAFQAUABMAFgAXABgAFgAZABcAGgAWABgAGgAYABsAHAAZABYAHAAdABkAHgAbAB8AHgAaABsAIAAaAB4AGgAhABYAFgAhACIAFgAiABwAGgAjACEAIAAkABoAJAAjABoAJQAkACAAJAAmACMAHAAiACYAHAAmACQAJQAnACQAJwAcACQAKAAnACUAKAApACcAJwAqABwAKQAqACcAKgAdABwAKQArACoAKgAsAB0AKwAsACoAKwAtACwAAAABAAIAAAAuAAEAAwABAC4ABQAuAAAAAwAuAAQABQAvAC4ALwAEAC4ACQAvAAUALwAGAAQACQAHAC8ABwAGAC8ABwAIAAYA"),
|
||||
"lods": [0.1056379, PackedByteArray("AAABAAIAAwABAAAAAwAAAAQABQAEAAAABQAGAAQABwAGAAUABwAIAAYACQAHAAUA")],
|
||||
"name": "schwarz",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 48,
|
||||
"vertex_data": PackedByteArray("VFUAAJdDAAAAAP8/l0MAAAAAAACXQwAAAAD/f5dDAABUVf9/l0MAAKqqAACXQwAAqqr/f5dDAAD///8/l0MAAP///3+XQwAA//8AAJdDAAAAAP+/THoAAK8MKORMegAAAAD//0x6AABtIrbkTHoAAFRV/79MegAA0gzr8kx6AABUVf//THoAAK8MKOT//wAA0gzr8v//AABtIrbk//8AAOUgD/P//wAA5SAP80x6AADiuP/vAAAAAKqq//8AAAAAqqr/7wAAAADiuP//AAAAAOK4/98AAAAAqqr/3wAAAAAxzP/vAAAAABvH//8AAAAA4rj/vwAAAACqqv+/AAAAABvH/78AAAAA4rj/72FgAAAxzP/vYWAAAOK4/99hYAAAMcz/3wAAAABU1f+/AAAAADHM/99hYAAAVNX/3wAAAAD///+/AAAAAP///98AAAAAVNX/7wAAAAD////vAAAAAFTV//8AAAAA/////wAAAABUVf8/l0MAAKqq/z+XQwAA")
|
||||
}, {
|
||||
"aabb": AABB(-0.14619195, 0.45840824, 0.48416355, 0.26931208, 0.029790878, 0.023900598),
|
||||
"format": 34896613377,
|
||||
"index_count": 12,
|
||||
"index_data": PackedByteArray("AAABAAIAAAADAAEABAAFAAYABAAHAAUA"),
|
||||
"name": "weiss",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 8,
|
||||
"vertex_data": PackedByteArray("//8AAAAAAAAv5tPWAAAAAC/mAAAAAAAA///T1gAAAAAuABr+//8AABAdVj///wAABBv/////AAAAAOU3//8AAA==")
|
||||
}]
|
||||
blend_shape_mode = 0
|
||||
|
||||
[resource]
|
||||
resource_name = "Dude_Cube_002"
|
||||
_surfaces = [{
|
||||
"aabb": AABB(-0.28403106, 0.008408189, -0.083770275, 0.6, 0.6000001, 0.60000014),
|
||||
"attribute_data": PackedByteArray("x6zHrOH9x6zh/eH9x6zh/cesclfg/XJX4P2MqMesjKhVEvZkHQJyV44i9mRVEntyN1NyV1US/3+OIntyVRIImx0CjKj/QgibN1OMqMYy9mTGMnty/0L/f/9C9mT/QntyjKjh/XJXx6yMqMesclfh/WEhjiJMJo4iTCbGMmEhN1NMJv9CTCY3UzxlN1NRYDdTUWCzRTxlLjhRYC44h5M3U1aX/0JWlzdTh5P/QnEvN1OHKjdThyr/QnEvjiKHKsYyhyqOIn9+s0XIhDdTf343U8iEdUzIhBRJyISzRR0Cx6w3U8esN1Ph/R0C4f1yV3JXjKiMqHJXjKiMqHJXYZ//QpGbN1ORm/9CYZ83U5yjN1Nrp7NFa6c3U5yjs0V1r7NFpqs3U6ars0V1rzdTRHo3U/tz/0JEev9C+3MbS/tzz037c4NQ+3M3U0yPN1MDibNFTI+zRQOJFEkDiXVMA4k3U3dp/0LAbzdTd2k3U8Bvg1DAb89NwG8bS8Bv/0IrVzdTFlwuOBZcs0UrVy44Flw3U1zwcldc8Iyoz8dyV9jijKhU1Yyoz8eMqEu6cldLuoyoLjg4zbNF4f03U3DdJh3h/aEP4f0dAvZkVRJyV44iclcdAntyHQL/fx0Cg40dAgibN1P/f1SYx6wbiMesG4jh/f9/cleqZ+H9qmfHrON34f3jd8esVJjh/TdT9mT/QnJXN1N7csYyclfGMv9//0KDjTdTg42OIv9/N1MIm/9CjKjGMoyoxjIIm44ijKiOIgibVRKMqFUSg40Im3JXCJuMqIONcleDjYyo/3+MqHtycld7coyo9mRyV/ZkjKip7cesqe3h/XDdx6xw3eH9OM3HrDjN4f3/vMes/7zh/djicldU1XJXs0Wp7TdTqe0uOKntLjjh/bNFcN0uOHDdqiqp7aoq4f2qKnDds0U4zTdTOM2qKjjNs0X/vDdT/7yzRcesLjjHrC44/7yqKsesqir/vCYdx6wmHf+8oQ/HrCYdOM2hD/+8HQL/vKEPOM0dAjjNJh1w3aEPcN0dAnDdJh2p7aEPqe0dAqntYSHGMmEh/0I8ZbNFcS//QnEvxjIrV7NF"),
|
||||
"format": 34896613399,
|
||||
"index_count": 582,
|
||||
"index_data": PackedByteArray("fQAZAH4AfQAbABkAfwB9AH4AfwB+AIAAewB/AIAAewCAAHoAgQB7AHoAgQB6AHkAGACBAHkAGAB5ABoAFgAMAIIAFgCDAAwAFwAWAIIAEwCDABYAFwCCAIQAEwCFAIMAFQAXAIQAFQCEAHgAhgAXABUAhwAVAHgAhgAUABcAhwB4AIgAiQAUAIYAEQCHAIgAEQCIAIoAiwARAIoAiwCKABIAjAARAIsAjACNABEAjgCNAIwAjgCPAI0AkACPAI4AkAAPAI8AEAAPAJAAEAB3AA8AdwCRAA8AdwB2AJEAdgANAJEAdgB1AA0AdQALAA0AdQB0AAsADQALAA4ADQAOAIkAiQAOABQADgATABQADgAKABMACgCFABMACgBzAIUAdAAIAAsACABzAAoAdABxAAgACAByAHMAcQByAAgAcQAJAHIAkgA8AJMAkgA+ADwAlACSAJMAlACTAJUAfACUAJUAfACVAJYAlwB8AJYAlwCWAJgAmQCXAJgAmQCYAJoAOwCZAJoAOwCaAD0AmwACAJwAmwABAAIAnQCbAJwAnQCcAJ4AnwCdAJ4AnwCeAKAAoQCfAKAAoQCgAKIAAAChAKIAAACiAAMAZAAGAGUAZAAFAAYAowBkAGUAowBlAGcApACjAGcApABnAGgAZgCkAGgAZgBoAGkAagBmAGkAagBpAGsABABqAGsABABrAAcApQA5AG0ApQCmADkApwClAG0ApwBtAKgAqQCmAKUAqQBuAKYAqgClAKcAqgCpAKUAqwCnAKgAqwCoAKwArQCqAKcArQCnAKsArgBuAKkArgCvAG4AbACpAKoAbACuAKkAsACqAK0AsABsAKoAsQCvAK4AsQCyAK8AswCyALEAswA4ALIAtACzALEAtQCxAK4AtACxALUAtQCuAGwAtgC0ALUAtwC1AGwAtgC1ALcAtwBsALAAuAC2ALcAuAC3ALkAuQC3ALAAugC4ALkAuQCwALsAugC5ALwAvAC5ALsANwC6ALwAuwCwAK0ANwC8AL0AvQC8AL4AvAC7AL4AvQC+AL8AuwCtAMAAvgC7AMAAwACtAKsAvwC+AMEAvgDAAMEAvwDBAMIAwACrAMMAwQDAAMMAwwCrAKwAwwCsAG8AwQDDAMQAwgDBAMQAxADDAG8AwgDEAMUAxABvAHAAxQDEAHAAxQBwADoAxgAdAB4AxgAcAB0AxwDGAB4AxwAeACAAHwDHACAAHwAgACEAyAAjACQAyAAiACMAJQDIACQAJQAkACYAJwAoACkAJwAqACgAyQAsAC0AyQArACwAygDJAC0AygAtAC8ALgDKAC8ALgAvADAAMQAyADMAMQA0ADIANAAxADUANQAxADYAPwBAAEEAPwBCAEAAQwBEAEUAQwBGAEQARwBIAEkARwBKAEgASwBMAE0ASwBOAEwASwBPAE4ATwBLAFAAUABLAFEAUgBTAFQAUgBVAFMAVQBSAFYAVgBSAFcAWABZAFoAWABbAFkAWABcAFsAXABYAF0AXQBYAF4AywBgAGEAywBiAGAAXwDLAGEAXwBhAGMA"),
|
||||
"lods": [0.00012957268, PackedByteArray("AAABAAIAAAACAAMAZAAGAGUAZAAFAAYAZgBkAGUAZgBlAGcAZgBnAGgAZgBoAGkAagBmAGkAagBpAGsABABqAGsABABrAAcAbAA5AG0AbgA5AGwAbAA4AG4AbABtAG8ANwA4AGwANwBsAG8ANwBvAHAANwBwADoAcQByAAgAcQAJAHIACAByAHMAdABxAAgACABzAAoAdAAIAAsAdQB0AAsACgBzAAwAdQALAA0AdgB1AA0ADQALAA4AdgANAA8AdwB2AA8AEAB3AA8AEAAPABEAEAARABIAEQB4ABIAEQAVAHgAFQAMAHgADQAUABUADQAOABQAFQAUABcAFQAXAAwADgATABQADgAKABMACgAMABMAFwAWAAwAEwAMABYAGAB5ABoAGAB6AHkAGAB7AHoAewAZAHoAewAbABkAHAAdAB4AHwAcAB4AHwAeACAAHwAgACEAIgAjACQAJQAiACQAJQAkACYAJwAoACkAJwAqACgAKwAsAC0ALgArAC0ALgAtAC8ALgAvADAAMQAyADMAMQA0ADIANAAxADUANQAxADYAOwA8AD0AOwB8ADwAfAA+ADwAPwBAAEEAPwBCAEAAQwBEAEUAQwBGAEQARwBIAEkARwBKAEgASwBMAE0ASwBOAEwASwBPAE4ATwBLAFAAUABLAFEAUgBTAFQAUgBVAFMAVQBSAFYAVgBSAFcAWABZAFoAWABbAFkAWABcAFsAXABYAF0AXQBYAF4AXwBgAGEAXwBiAGAAXwBhAGMA"), 0.00025139967, PackedByteArray("AAABAAIAAAACAAMABAAFAAYABAAGAAcACAAJAAoACQAIAAsACgAJAAwACQALAA0ADQALAA4ACQANAA8AEAAJAA8AEAAPABEAEAARABIAEQAMABIADgAKABMACgAMABMADQAOABQADgATABQADQAUABUAEQAVAAwAEwAMABYAFQAUABcAFwAWAAwAFQAXAAwAGAAZABoAGAAbABkAHAAdAB4AHwAcAB4AHwAeACAAHwAgACEAIgAjACQAJQAiACQAJQAkACYAJwAoACkAJwAqACgAKwAsAC0ALgArAC0ALgAtAC8ALgAvADAAMQAyADMAMQA0ADIANAAxADUANQAxADYANwA4ADkANwA5ADoAOwA8AD0AOwA+ADwAPwBAAEEAPwBCAEAAQwBEAEUAQwBGAEQARwBIAEkARwBKAEgASwBMAE0ASwBOAEwASwBPAE4ATwBLAFAAUABLAFEAUgBTAFQAUgBVAFMAVQBSAFYAVgBSAFcAWABZAFoAWABbAFkAWABcAFsAXABYAF0AXQBYAF4AXwBgAGEAXwBiAGAAXwBhAGMA")],
|
||||
"material": SubResource("StandardMaterial3D_h8qyk"),
|
||||
"name": "pink.002",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 204,
|
||||
"vertex_data": PackedByteArray("AAAAAAAA/7///wAAAAD/v///AAD///+/AAAAAP///7///wAAAABU1f////8AAFTV////////VNX//wAA//9U1czMVNX///////////////+ZmVTV/////8zMqqr/////AAD////////MzP9//////5mZqqr/////zMyqKv///////wAA/////zIzqir/////AAAAAP////9lZlTV/////2Vmqqr/////MjP/f/////8yM1TV/////zIzqqr//////////wAA/78AAP//////v/////////+/AAD//wAA/7/MzKoq//9U1czMqip58FTVmZmqKnnwVNUyM6oq//9U1WVmqip58FTVMjOqKnnwVNUyM6oq////vzIzqip58P+/MjNUVXnw/78yM/9/////vzIz/3958P+/MjOqqv//VNVlZqqq+PNU1TIzqqr481TVZWaqqv//VNUyM/9///9U1TIz/3958FTVZWb/f3nwVNXMzP9///9U1ZmZ/3958FTVzMz/f3nwVNXMzFTV////v8zMqqoo7P+/zMyqqv///7/MzP+/KOz/v8zMqcoo7P+/zMxU1Sjs/78AAAAAAAD/vwAA//8AAP+//////wAA/7///wAAAAD/vwAAAAD//1TVAAD//wAAVNUAAAAAAABU1QAA/////1TVZWZU1f//VNUyM1TV+PNU1WVmVNX481TVMjNU1f//VNVlZqqq////v2VmVNX48/+/ZWaqqvjz/79lZlTV////vzIzVNX///+/MjOqqvjz/78yM1TV+PP/vzIzqqr///+/mZlU1f//VNXMzFTVKOxU1czMVNX//1TVMrNU1SjsVNWpqlTVKOxU1SGiVNUo7FTVmZlU1SjsVNWZmaqq////v5mZVNUo7P+/mZlU1f///7+ZmanKKOz/v5mZ/78o7P+/mZmqqijs/7/MzKqq//9U1ZmZqqoo7FTVmZmqqv//VNUhoqqqKOxU1amqqqoo7FTVMrOqqijsVNXMzKqqKOxU1czMqir///+/zMz/f3nw/7/MzFRVefD/v8zM/3////+/zMyqKnnw/7///1TVAABU1f//VNX//1TV//9UVQAAVNX//6qq//9U1f///3///1TV//9UVf//VNX//6oqAABU1f//qir//1TVZWaqqgAA/7///1TVAAD/v5mZ//8AAP+///9UVQAA/7///6oqAAD/v///VNX/////zMz///////+Zmf//////////qqr/////////f////////1RV////////qir/////AAD/f//////MzP//////v5mZ//////+/mZn//wAA/78AAP9///9U1TIz//8AAP+/MjP//////79lZv//AAD/v2Vm//////+/zMz//wAA/78AAFTV/////zIz////////AACqqv////9lZv///////2Vm/3//////MjNUVf////8AAFVV/////5mZ/3//////AACqKv////8yMwAA/////2VmAAD/////ZWaqKv////+ZmQAA/////5mZqir/////zMwAAP/////MzFRV/////wAAVNX//1TVAABU1QAAVNUAAKqq//9U1QAAqqoAAFTVAAD/fwAAVNUAAFVV//9U1QAAVFUAAFTVAACqKv//VNUAAKoqAABU1czMAAAAAP+/zMwAAP///7+ZmQAAAAD/v5mZAAD///+/ZWYAAAAA/79lZgAA////vzIzAAAAAP+/MjMAAP///7///6qqAABU1f///38AAFTVzMxU1QAA/7/MzP//AAD/v8zMqqoAAP+///+qqgAA/7+ZmVTVAAD/v5mZqqoAAP+/zMz/fwAA/7////9/AAD/v5mZ/38AAP+/ZWZU1QAA/79lZv//AAD/v2Vm/38AAP+/MjNU1QAA/78yM///AAD/vwAAVNUAAP+/AACqqgAA/78yM6qqAAD/vwAA/38AAP+/MjP/fwAA/78AAFRVAAD/vzIzVFUAAP+/AACqKgAA/79lZlRVAAD/vzIzqioAAP+/MjMAAAAA/79lZqoqAAD/v2VmAAAAAP+/mZlUVQAA/7+ZmaoqAAD/v5mZAAAAAP+/zMxUVQAA/7/MzKoqAAD/v8zMAAAAAP+/mZmqKv//VNVlZqoq//9U1TIzVFX///+/ZWb/f///VNWZmf9///9U1czMVFX///+/////f////3////9/////f1TVVNVU1VTVVNVU1VTVVNX/f////3////9/////f////3////9/////f////3////9/////f/7//3////9/////f////3////9/////f///AAD/fwAA/38AAP9/AAD/f1RVVFVUVVRVVFVUVVRVVFVUVVRVVFVUVf9/////f////3////9/////f///VFVUVVRVVFVUVVRVVFVUVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqv9/AAD/fwAA/38AAP9/AAD/fwAA/38AAP////////////////////+qKqoqqiqqKqoqqiqqKqoqqqqqqqqqqqqqqqqqqqqqqv9/AAD/fwAA/38AAP9/AAD/f////3////9/////f///qqqpqqqqqqqqqqqqqqqpqqqqqaqpqqqqqqqqqv9//v//f/7//3////9//v//f/7//3///1VVVFVUVVVVVFVUVVRVVVVVVVRVVVVUVVRVVFX/fwAA/38AAP9/AAD/fwAA/38AAFTVVNVU1VTVVNVU1VTVVNVU1VTVVNVU1VTVVNVU1VTV////////////////////////////f////3////9/////f////3////9/////f////3/+/wAA/38AAP9/AAD/f6oqqioAAP9/AAD/fwAA/38AAP9/AAD/f/9/////f////3////9/////f////3/+//9//v//f////3////9/////f////3////9/////f////3////9///+qKqoqqiqqKqoqqiqqKqoqqiqqKqoqqiqqKqoqqiqqKqoqqir///9/////f////3////9/////f////3////9/////f1TVVNVU1VTV////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////VFVUVVRVVFX/f///qqqqqqqqqqr/fwAA")
|
||||
}, {
|
||||
"aabb": AABB(-0.16403107, 0.10840821, 0.46973133, 0.36, 0.39999998, 0.03833282),
|
||||
"attribute_data": PackedByteArray("HQL/QqEPN1MdAjdTJh03UyYd/0IdAsYyJh3GMqEPjiImHY4iHQKOIqwzN1NQO85QMUE3U24+x1BuO6xMMUH/Qqwz/0J1PvZMj0+DUPBSN1OPTzdT8FKDUC5Mg1CPT9dMLkw3U/BSz01sRYNQbEU3U2xFz00uTNdMbEUbSy5MG0tsRf9CLkz/Qo9PG0uPT/9C8FIbS/BS/0KhD/9CoQ/GMljgN1Nk3otPWOCLT2TeN1Pw8NZP4/I3U/DwN1Pj8tZPk+SLT4bmN1OT5DdThuaLT7XsN1PB6tZPtezWT8HqN1NKzDdTlclmT0rMZk+VyTdTpcIVT1rFN1OlwjdTWsUVT3XXL1Ap2jdTddc3UynaL1A60zdThdAZUDrTGVCF0DdT"),
|
||||
"format": 34896613399,
|
||||
"index_count": 174,
|
||||
"index_data": PackedByteArray("CgALAAwADQAMAAsACgAOAAsADwAMAA0ACgAQAA4ADgAQAA8ADwARAA4ADwANABEAEgATABQAEgAVABMAFgASABQAFwAVABIAFgAUABgAFwAZABUAGgAWABgAGgAYABsAHAAWABoAHAAdABYAHgAdABwAHgAfAB0AHwAXAB0AIAAfAB4AIAAhAB8AHwAiABcAIQAiAB8AIgAZABcAIQAjACIAIgAkABkAIwAkACIAIwAlACQAAAABAAIAAAAmAAEAAwABACYABQAmAAAAAwAmAAQABQAnACYAJwAEACYACQAnAAUAJwAGAAQACQAHACcABwAGACcABwAIAAYAKAApACoAKAArACkALAAtAC4ALAAvAC0AMAAxADIAMAAzADEANAA1ADYANAA3ADUAOAA5ADoAOAA7ADkAPAA9AD4APAA/AD0AQABBAEIAQABDAEEARABFAEYARABHAEUA"),
|
||||
"lods": [0.1056379, PackedByteArray("AAABAAIAAwABAAAAAwAAAAQABQAEAAAABQAGAAQABwAGAAUABwAIAAYACQAHAAUA")],
|
||||
"material": SubResource("StandardMaterial3D_c6dnh"),
|
||||
"name": "schwarz",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 72,
|
||||
"vertex_data": PackedByteArray("VFUAAJdD//8AAP8/l0P//wAAAACXQ///AAD/f5dD//9UVf9/l0P//6qqAACXQ///qqr/f5dD//////8/l0P//////3+XQ/////8AAJdD//8AAP+/THr//68MKORMev//AAD//0x6///SDOvyTHr//20ituRMev//VFX//0x6//9UVf+/THr//+UgD/NMev//4rj/7wAA//+qqv//AAD//6qq/+8AAP//4rj//wAA///iuP/fAAD//zHM/+8AAP//qqr/3wAA//8bx///AAD//+K4/78AAP//qqr/vwAA//8bx/+/AAD//zHM/98AAP//VNX/vwAA//9U1f/fAAD//////78AAP//////3wAA//9U1f/vAAD//////+8AAP//VNX//wAA////////AAD//1RV/z+XQ///qqr/P5dD///iuP/vAABU1THM/+9hYFTVMcz/7wAAVNXiuP/vYWBU1THM/+8AAP+/Mcz/32Fg/78xzP/fAAD/vzHM/+9hYP+/Mcz/3wAAVNXiuP/fYWBU1eK4/98AAFTVMcz/32FgVNXiuP/fAAD/v+K4/+9hYP+/4rj/7wAA/7/iuP/fYWD/v9IM6/JMeiXV5SAP8///JdXlIA/zTHol1dIM6/L//yXVbSK25Ex6qtSvDCjk//+q1K8MKORMeqrUbSK25P//qtTlIA/zTHoXwG0ituT//xfAbSK25Ex6F8DlIA/z//8XwK8MKORMev+/0gzr8v///7/SDOvyTHr/v68MKOT///+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v/+//7//v1RVVFVUVVRVVFVUVVRVVFX/f////3////9/////f///qqqqqqqqqqqqqqqqqqqqqv9/AAD/fwAA/38AAP9/AABxVRxVcVUcVXFVHFVxVRxVQqp5q0KqeatCqnmrQqp5q850ZvrOdGb6znRm+s50Zvp4fw0BeH8NAXh/DQF4fw0B")
|
||||
}, {
|
||||
"aabb": AABB(-0.14619195, 0.45840824, 0.48416355, 0.26931208, 0.029790878, 0.023900598),
|
||||
"attribute_data": PackedByteArray("CbuLT2q+N1MJuzdTar6LT862GlOwsxRPurZJT7CzN1M="),
|
||||
"format": 34896613399,
|
||||
"index_count": 12,
|
||||
"index_data": PackedByteArray("AAABAAIAAAADAAEABAAFAAYABAAHAAUA"),
|
||||
"material": SubResource("StandardMaterial3D_i8imj"),
|
||||
"name": "weiss",
|
||||
"primitive": 3,
|
||||
"uv_scale": Vector4(0, 0, 0, 0),
|
||||
"vertex_count": 8,
|
||||
"vertex_data": PackedByteArray("//8AAAAA//8v5tPWAAD//y/mAAAAAP/////T1gAA//8uABr+/////xAdVj//////BBv///////8AAOU3//////+//7//v/+//7//v/+//78Xv+fAF7/nwBe/58AXv+fA")
|
||||
}]
|
||||
blend_shape_mode = 0
|
||||
shadow_mesh = SubResource("ArrayMesh_wt8sa")
|
||||
6
weltenauge/assets/characters/humanoid/dude.tscn
Normal file
6
weltenauge/assets/characters/humanoid/dude.tscn
Normal file
|
|
@ -0,0 +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"]
|
||||
|
||||
[node name="Dude" type="MeshInstance3D" unique_id=1185543431]
|
||||
mesh = ExtResource("1_jchph")
|
||||
BIN
weltenauge/assets/icons/program/logo_projekt_weltenauge.png
Normal file
BIN
weltenauge/assets/icons/program/logo_projekt_weltenauge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
|
|
@ -0,0 +1,40 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d1cyxxj8ypfu"
|
||||
path="res://.godot/imported/logo_projekt_weltenauge.png-faafe98462d8081c55aa7ba6fc11610a.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"]
|
||||
|
||||
[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
|
||||
9
weltenauge/game_root.gd
Normal file
9
weltenauge/game_root.gd
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
extends Node
|
||||
|
||||
## Project Fugue - Zentrale Steuerung
|
||||
## Orchestriert den Übergang zwischen Menü und Spielwelt.
|
||||
|
||||
@onready var main_menu = $MainMenu
|
||||
|
||||
func _ready():
|
||||
print("--- Start: Projekt Weltenauge ---")
|
||||
1
weltenauge/game_root.gd.uid
Normal file
1
weltenauge/game_root.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://162cjpb4lac4
|
||||
9
weltenauge/game_root.tscn
Normal file
9
weltenauge/game_root.tscn
Normal file
|
|
@ -0,0 +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://bhywhrlwjox6t" path="res://ui/menus/main_menu.tscn" id="2_pjpa4"]
|
||||
|
||||
[node name="Game_root" type="Node2D" unique_id=1336425327]
|
||||
script = ExtResource("1_xj5yv")
|
||||
|
||||
[node name="MainMenu" parent="." unique_id=1731390780 instance=ExtResource("2_pjpa4")]
|
||||
1
weltenauge/icon.svg
Normal file
1
weltenauge/icon.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<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>
|
||||
|
After Width: | Height: | Size: 995 B |
43
weltenauge/icon.svg.import
Normal file
43
weltenauge/icon.svg.import
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[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
|
||||
8
weltenauge/main.tscn
Normal file
8
weltenauge/main.tscn
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[gd_scene format=3 uid="uid://2fal1f0f8fdh"]
|
||||
|
||||
[ext_resource type="ArrayMesh" uid="uid://bi22s15yeh6mw" path="res://assets/characters/humanoid/dude.tres" id="1_ig7tw"]
|
||||
|
||||
[node name="Node3D" type="Node3D" unique_id=1431241737]
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=231315459]
|
||||
mesh = ExtResource("1_ig7tw")
|
||||
43
weltenauge/maps/outdoor/grass/keuwin_grasland.tscn
Normal file
43
weltenauge/maps/outdoor/grass/keuwin_grasland.tscn
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
[gd_scene format=3 uid="uid://h5qt2pcidh8x"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
||||
|
||||
[sub_resource type="Sky" id="Sky_1yg6u"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_d3jw7")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_8r0t0"]
|
||||
background_mode = 2
|
||||
sky = SubResource("Sky_1yg6u")
|
||||
tonemap_mode = 2
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_30klc"]
|
||||
albedo_color = Color(9.3854965e-07, 0.4579985, 0.32070312, 1)
|
||||
|
||||
[sub_resource type="PlaneMesh" id="PlaneMesh_0iae2"]
|
||||
material = SubResource("StandardMaterial3D_30klc")
|
||||
|
||||
[node name="keuwin_grasland" type="Node3D" unique_id=1953380732]
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1262732162]
|
||||
transform = Transform3D(-0.8660254, -0.3535534, 0.3535534, 0, 0.70710677, 0.70710677, -0.50000006, 0.6123724, -0.6123724, 0, 0, 0)
|
||||
light_color = Color(0.90022373, 0.9250896, 0.6778064, 1)
|
||||
light_energy = 1.5
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1286599151]
|
||||
environment = SubResource("Environment_8r0t0")
|
||||
|
||||
[node name="Architecture" type="Node3D" parent="." unique_id=97923552]
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Architecture" unique_id=1708107393]
|
||||
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0)
|
||||
mesh = SubResource("PlaneMesh_0iae2")
|
||||
|
||||
[node name="Navigation" type="Node3D" parent="." unique_id=1472582667]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.01873529, 0)
|
||||
|
||||
[node name="SpawnPoints" type="Node3D" parent="." unique_id=438053421]
|
||||
|
||||
[node name="Interaction" type="Node3D" parent="." unique_id=1592705952]
|
||||
|
||||
[node name="Triggers" type="Node3D" parent="." unique_id=1507691477]
|
||||
47
weltenauge/maps/planes/fugue/halle_der_ahnen.tscn
Normal file
47
weltenauge/maps/planes/fugue/halle_der_ahnen.tscn
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
[gd_scene format=3 uid="uid://bef0tj7n6g8uo"]
|
||||
|
||||
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_d3jw7"]
|
||||
sky_top_color = Color(0.055328622, 0.3637527, 0.67898166, 1)
|
||||
ground_bottom_color = Color(0.28193337, 0.24096331, 0.19489476, 1)
|
||||
ground_horizon_color = Color(0.5439266, 0.5434616, 0.51488423, 1)
|
||||
|
||||
[sub_resource type="Sky" id="Sky_1yg6u"]
|
||||
sky_material = SubResource("ProceduralSkyMaterial_d3jw7")
|
||||
|
||||
[sub_resource type="Environment" id="Environment_8r0t0"]
|
||||
background_mode = 2
|
||||
sky = SubResource("Sky_1yg6u")
|
||||
tonemap_mode = 2
|
||||
fog_enabled = true
|
||||
fog_light_color = Color(0.061652586, 0.3592321, 0.673373, 1)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_30klc"]
|
||||
albedo_color = Color(0.1800012, 0.004964735, 0.2305904, 1)
|
||||
|
||||
[sub_resource type="PlaneMesh" id="PlaneMesh_0iae2"]
|
||||
material = SubResource("StandardMaterial3D_30klc")
|
||||
|
||||
[node name="halle_der_ahnen" type="Node3D" unique_id=1953380732]
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=1262732162]
|
||||
transform = Transform3D(-0.8660254, -0.12940952, 0.48296294, 0, 0.96592575, 0.258819, -0.50000006, 0.22414385, -0.8365162, 0, 0, 0)
|
||||
light_color = Color(0.94507605, 0.7726238, 0.95401555, 1)
|
||||
light_energy = 0.5
|
||||
shadow_enabled = true
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1286599151]
|
||||
environment = SubResource("Environment_8r0t0")
|
||||
|
||||
[node name="Architecture" type="Node3D" parent="." unique_id=97923552]
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Architecture" unique_id=1708107393]
|
||||
transform = Transform3D(10, 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0)
|
||||
mesh = SubResource("PlaneMesh_0iae2")
|
||||
|
||||
[node name="Navigation" type="Node3D" parent="." unique_id=1472582667]
|
||||
|
||||
[node name="SpawnPoints" type="Node3D" parent="." unique_id=438053421]
|
||||
|
||||
[node name="Interaction" type="Node3D" parent="." unique_id=1592705952]
|
||||
|
||||
[node name="Triggers" type="Node3D" parent="." unique_id=1507691477]
|
||||
32
weltenauge/project.godot
Normal file
32
weltenauge/project.godot
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Project Weltenauge"
|
||||
run/main_scene="uid://cpxxy0664jyjm"
|
||||
config/features=PackedStringArray("4.6", "Forward Plus")
|
||||
boot_splash/image="uid://d1cyxxj8ypfu"
|
||||
config/icon="res://icon.svg"
|
||||
boot_splash/minimum_display_time=1000
|
||||
|
||||
[autoload]
|
||||
|
||||
GameEvents="*uid://4xof67e363t4"
|
||||
ChatManager="*uid://c351ysuym2mdm"
|
||||
NetworkManager="*uid://tniwwfk5703p"
|
||||
|
||||
[physics]
|
||||
|
||||
3d/physics_engine="Jolt Physics"
|
||||
|
||||
[rendering]
|
||||
|
||||
rendering_device/driver.windows="d3d12"
|
||||
20
weltenauge/systems/core/game_events.gd
Normal file
20
weltenauge/systems/core/game_events.gd
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
extends Node
|
||||
|
||||
@warning_ignore("unused_signal")
|
||||
|
||||
# Spieler-bezogene Events
|
||||
# signal player_health_changed(new_health, max_health)
|
||||
# signal player_xp_gained(amount)
|
||||
|
||||
# Welt-bezogene Events
|
||||
# signal area_transition_started(area_name)
|
||||
# signal area_loading_finished
|
||||
|
||||
# Netzwerk-Events
|
||||
# signal server_message_received(message, type)
|
||||
|
||||
# UI-Events
|
||||
signal join_requested(ip: String)
|
||||
|
||||
@warning_ignore("unused_signal")
|
||||
signal host_requested()
|
||||
1
weltenauge/systems/core/game_events.gd.uid
Normal file
1
weltenauge/systems/core/game_events.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://4xof67e363t4
|
||||
26
weltenauge/systems/network/chat_manager.gd
Normal file
26
weltenauge/systems/network/chat_manager.gd
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
extends Node
|
||||
|
||||
# Signal für die UI, um neue Nachrichten anzuzeigen
|
||||
signal message_received(sender_name: String, message: String, channel: String)
|
||||
|
||||
@rpc("any_peer", "call_remote", "reliable")
|
||||
func send_message(message: String):
|
||||
var peer_id = multiplayer.get_remote_sender_id()
|
||||
|
||||
# Serverseitige Validierung (Spam-Schutz, Filter)
|
||||
if message.length() > 256:
|
||||
message = message.left(256)
|
||||
|
||||
var sender_name = "Player " + str(peer_id) # Hier später Name aus DB laden
|
||||
|
||||
# Ermittle die Area des Spielers (Sichtbarkeits-Logik)
|
||||
var area = NetworkManager.player_area_map.get(peer_id, "")
|
||||
|
||||
# Broadcast: Nur an Spieler in der gleichen Area senden (NWN-Style)
|
||||
for id in NetworkManager.player_area_map:
|
||||
if NetworkManager.player_area_map[id] == area:
|
||||
rpc_id(id, "receive_message", sender_name, message, "local")
|
||||
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func receive_message(sender_name: String, message: String, channel: String):
|
||||
message_received.emit(sender_name, message, channel)
|
||||
1
weltenauge/systems/network/chat_manager.gd.uid
Normal file
1
weltenauge/systems/network/chat_manager.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c351ysuym2mdm
|
||||
191
weltenauge/systems/network/network_manager.gd
Normal file
191
weltenauge/systems/network/network_manager.gd
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
extends Node
|
||||
|
||||
const PORT = 7777
|
||||
const MAX_CLIENTS = 32
|
||||
|
||||
# Kamera (wird nur auf dem Client gebraucht)
|
||||
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"
|
||||
}
|
||||
|
||||
# Server-seitiges Tracking: peer_id -> SubViewport (World)
|
||||
var player_worlds = {}
|
||||
|
||||
func _ready():
|
||||
GameEvents.host_requested.connect(host_game)
|
||||
GameEvents.join_requested.connect(join_game)
|
||||
|
||||
if DisplayServer.get_name() == "headless" or OS.get_cmdline_args().has("--server"):
|
||||
host_game()
|
||||
|
||||
func host_game():
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
peer.create_server(PORT, MAX_CLIENTS)
|
||||
multiplayer.multiplayer_peer = peer
|
||||
multiplayer.peer_connected.connect(_on_player_connected)
|
||||
print("Server gestartet. id=" + str(multiplayer.get_unique_id()))
|
||||
|
||||
func join_game(ip = "127.0.0.1"):
|
||||
var peer = ENetMultiplayerPeer.new()
|
||||
peer.create_client(ip, PORT)
|
||||
multiplayer.multiplayer_peer = peer
|
||||
|
||||
func _on_player_connected(id):
|
||||
print("Player connected with id:", id)
|
||||
# Standardmäßig in Area 1 starten
|
||||
change_player_area(id, "keuwin_grasland")
|
||||
|
||||
func change_player_area(id: int, area_key: String):
|
||||
if not multiplayer.is_server(): return
|
||||
print("Server is loading ", area_key)
|
||||
var path = area_paths[area_key]
|
||||
|
||||
var container_name = area_key + "_container"
|
||||
var viewport_name = area_key + "_viewport"
|
||||
|
||||
# Server: Erstelle SubViewportContainer + SubViewport für physikalische Trennung, falls nicht existent
|
||||
var container_node = get_node_or_null(container_name)
|
||||
if not container_node:
|
||||
#container_node = SubViewportContainer.new()
|
||||
container_node = Node3D.new()
|
||||
container_node.name = container_name
|
||||
add_child(container_node)
|
||||
|
||||
var viewport_node = container_node.get_node_or_null(viewport_name)
|
||||
var map_instance = null
|
||||
if not viewport_node:
|
||||
viewport_node = SubViewport.new()
|
||||
viewport_node.name = viewport_name
|
||||
viewport_node.own_world_3d = true # Multi-World Physics!
|
||||
container_node.add_child(viewport_node)
|
||||
else:
|
||||
map_instance = viewport_node.get_node_or_null(area_key)
|
||||
|
||||
# Spawner muss vor laden der map hinzugefügt werden
|
||||
var spawner = viewport_node.get_node_or_null("AreaSpawner")
|
||||
if not spawner:
|
||||
spawner = MultiplayerSpawner.new()
|
||||
spawner.name = "AreaSpawner"
|
||||
print("Viewport Name: " + str(viewport_node.name))
|
||||
# "." bedeutet: Er spawnt Objekte als direkte Kinder des Viewports
|
||||
spawner.add_spawnable_scene("res://systems/player/player.tscn")
|
||||
viewport_node.add_child(spawner)
|
||||
spawner.spawn_path = viewport_node.get_path()
|
||||
|
||||
map_instance = load(path).instantiate()
|
||||
map_instance.name = area_key
|
||||
viewport_node.add_child(map_instance)
|
||||
|
||||
# --- ALTEN ZUSTAND AUFRÄUMEN ---
|
||||
if player_worlds.has(id):
|
||||
player_worlds.erase(id)
|
||||
|
||||
# --- NEUEN ZUSTAND REGISTRIEREN ---
|
||||
player_worlds[id] = viewport_node
|
||||
|
||||
|
||||
# Client anweisen, Szene zu laden
|
||||
rpc_id(id, "client_load_area", area_key)
|
||||
|
||||
# Avatar auf Server erstellen erfolgt erst wenn Client Vollzug meldet (client_ready_to_spawn)
|
||||
#_spawn_player_in_world(id, viewport_node)
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func client_ready_to_spawn():
|
||||
var id = multiplayer.get_remote_sender_id()
|
||||
if not multiplayer.is_server(): return
|
||||
|
||||
if player_worlds.has(id):
|
||||
var viewport_node = player_worlds[id]
|
||||
print("Client ", id, " ist bereit. Spawne jetzt.")
|
||||
_spawn_player_in_world(id, viewport_node)
|
||||
|
||||
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func client_load_area(area_key):
|
||||
print("Client loads area")
|
||||
# Client löscht alte Map, lädt neue lokal in das Root
|
||||
for child in get_children():
|
||||
if child.is_in_group("maps"): child.queue_free()
|
||||
|
||||
var container_name = area_key + "_container"
|
||||
var viewport_name = area_key + "_viewport"
|
||||
|
||||
var container_node = SubViewportContainer.new()
|
||||
container_node.name = container_name
|
||||
container_node.stretch = true
|
||||
container_node.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(container_node)
|
||||
container_node.add_to_group("maps")
|
||||
|
||||
var viewport_node = SubViewport.new()
|
||||
viewport_node.own_world_3d = true
|
||||
viewport_node.name = viewport_name
|
||||
viewport_node.size = Vector2i(1280,720)
|
||||
container_node.add_child(viewport_node)
|
||||
|
||||
# Spawner muss existieren bevor die map zum Viewport hinzugefügt wird
|
||||
var spawner = MultiplayerSpawner.new()
|
||||
spawner.name = "AreaSpawner"
|
||||
spawner.add_spawnable_scene("res://systems/player/player.tscn")
|
||||
viewport_node.add_child(spawner)
|
||||
spawner.spawn_path = viewport_node.get_path()
|
||||
|
||||
var map = load(area_paths[area_key]).instantiate()
|
||||
map.name = area_key
|
||||
viewport_node.add_child(map)
|
||||
|
||||
|
||||
# Kamera-Setup nur beim ersten Laden oder falls sie gelöscht wurde
|
||||
if not multiplayer.is_server() and local_camera == null:
|
||||
setup_client_camera(viewport_node)
|
||||
|
||||
# Jetzt können wir dem Server ok fürs Spawnen geben
|
||||
client_ready_to_spawn.rpc_id(1) # Server ist immer id=1
|
||||
|
||||
func setup_client_camera(node):
|
||||
local_camera = Camera3D.new()
|
||||
local_camera.set_script(load("res://systems/player/camera_logic.gd"))
|
||||
local_camera.current = true
|
||||
node.add_child(local_camera)
|
||||
# Ein AudioListener gehört auf dem Client auch an die Kamera
|
||||
local_camera.add_child(AudioListener3D.new())
|
||||
|
||||
|
||||
func _spawn_player_in_world(id, viewport_node):
|
||||
var player_scene = load("res://systems/player/player.tscn")
|
||||
var player = player_scene.instantiate()
|
||||
player.name = str(id)
|
||||
player.set_multiplayer_authority(id)
|
||||
|
||||
viewport_node.add_child(player)
|
||||
|
||||
# Visibility Filtering: Nur Spieler im gleichen Viewport sehen sich
|
||||
var sync = player.get_node("MultiplayerSynchronizer")
|
||||
|
||||
for other in viewport_node.get_children():
|
||||
if other.is_in_group("players"):
|
||||
var other_id = other.name.to_int()
|
||||
|
||||
# Der neue Spieler sieht den alten
|
||||
other.get_node("MultiplayerSynchronizer").set_visibility_for(id, true)
|
||||
|
||||
# Der alte Spieler sieht den neuen
|
||||
sync.set_visibility_for(other_id, true)
|
||||
|
||||
# Wir schicken dem Client eine Info, welchen Node er verfolgen soll
|
||||
# (Da der Name des Player-Nodes die ID ist, weiß der Client welcher seiner ist)
|
||||
rpc_id(id, "assign_camera_target", str(id))
|
||||
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func assign_camera_target(node_name: String):
|
||||
# Der Client sucht seinen Player-Node im Baum
|
||||
var p = get_tree().root.find_child(node_name, true, false)
|
||||
if p and local_camera:
|
||||
local_camera.target = p
|
||||
|
||||
# var camera = get_viewport().get_camera_3d()
|
||||
1
weltenauge/systems/network/network_manager.gd.uid
Normal file
1
weltenauge/systems/network/network_manager.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://tniwwfk5703p
|
||||
12
weltenauge/systems/player/camera_logic.gd
Normal file
12
weltenauge/systems/player/camera_logic.gd
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
extends Camera3D
|
||||
|
||||
var target: Node3D = null
|
||||
#var offset = Vector3(0, 12, 8) # Klassische NWN Perspektive
|
||||
var offset = Vector3(0, 3, 4) # Klassische NWN Perspektive
|
||||
|
||||
func _process(delta):
|
||||
if is_instance_valid(target):
|
||||
# Sanftes Folgen (Lerp) für smoothe Bewegungen
|
||||
var target_pos = target.global_position + offset
|
||||
global_position = global_position.lerp(target_pos, delta * 5.0)
|
||||
look_at(target.global_position)
|
||||
1
weltenauge/systems/player/camera_logic.gd.uid
Normal file
1
weltenauge/systems/player/camera_logic.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://ctxhm624vs1ya
|
||||
34
weltenauge/systems/player/player.tscn
Normal file
34
weltenauge/systems/player/player.tscn
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
[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"]
|
||||
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_ktl23"]
|
||||
|
||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_fqfg4"]
|
||||
properties/0/path = NodePath("CharacterBody3D:sync_position")
|
||||
properties/0/spawn = true
|
||||
properties/0/replication_mode = 1
|
||||
properties/1/path = NodePath("CharacterBody3D:sync_rotation")
|
||||
properties/1/spawn = true
|
||||
properties/1/replication_mode = 1
|
||||
|
||||
[node name="CharacterBody3D" type="CharacterBody3D" unique_id=682006733]
|
||||
script = ExtResource("1_ktl23")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=159496934]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0185384, 0)
|
||||
shape = SubResource("CylinderShape3D_ktl23")
|
||||
|
||||
[node name="Visuals" type="Node3D" parent="." unique_id=1840405751]
|
||||
|
||||
[node name="Dude" parent="Visuals" unique_id=1185543431 instance=ExtResource("1_2anqx")]
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1343500738]
|
||||
root_node = NodePath("../..")
|
||||
|
||||
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=656518492]
|
||||
root_path = NodePath("../..")
|
||||
replication_interval = 0.05
|
||||
replication_config = SubResource("SceneReplicationConfig_fqfg4")
|
||||
public_visibility = false
|
||||
110
weltenauge/systems/player/player_controller.gd
Normal file
110
weltenauge/systems/player/player_controller.gd
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
extends CharacterBody3D
|
||||
|
||||
@onready var synchronizer = $MultiplayerSynchronizer
|
||||
@export var target_position: Vector3
|
||||
|
||||
@export var sync_position: Vector3
|
||||
@export var sync_rotation: Vector3
|
||||
|
||||
var path: PackedVector3Array = []
|
||||
var speed = 5.0
|
||||
|
||||
func _enter_tree():
|
||||
# Da der Name des Nodes die Peer-ID ist, setzen wir die Authority einfach selbst
|
||||
if name.is_valid_int():
|
||||
set_multiplayer_authority(name.to_int())
|
||||
|
||||
func _ready():
|
||||
target_position = global_position
|
||||
|
||||
# Wir schalten die automatische Physik-Synchronisation aus
|
||||
set_physics_process(multiplayer.is_server())
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
# Dieser Teil läuft NUR auf dem Server
|
||||
if path.size() > 0:
|
||||
var next_point = path[0]
|
||||
var direction = (next_point - global_position).normalized()
|
||||
|
||||
# Wir nutzen move_and_slide, damit Kollisionen (Wände) funktionieren
|
||||
velocity = direction * speed
|
||||
move_and_slide()
|
||||
|
||||
# Nach der Bewegung speichern wir das Ergebnis für die Clients
|
||||
sync_position = global_position
|
||||
sync_rotation = rotation
|
||||
|
||||
if global_position.distance_to(next_point) < 0.2:
|
||||
path.remove_at(0)
|
||||
else:
|
||||
velocity = Vector3.ZERO
|
||||
sync_position = global_position # Sicherstellen, dass Standbild syncron bleibt
|
||||
|
||||
|
||||
|
||||
@rpc("any_peer", "call_remote", "reliable")
|
||||
func request_move(target: Vector3):
|
||||
if not multiplayer.is_server(): return
|
||||
|
||||
# Sicherheits-Check: Nur der Besitzer des Avatars darf ihn bewegen
|
||||
if multiplayer.get_remote_sender_id() != get_multiplayer_authority():
|
||||
return
|
||||
|
||||
# Hier später: path = astar.get_point_path(global_position, target)
|
||||
#path = PackedVector3Array([target])
|
||||
print("Target: ", target)
|
||||
path = [target]
|
||||
target_position = target
|
||||
|
||||
func _input(event):
|
||||
# NUR der Client, der diesen Spieler kontrolliert, darf klicken
|
||||
if not is_multiplayer_authority(): return
|
||||
if DisplayServer.get_name() == "headless": return # Server ignoriert Klicks
|
||||
|
||||
if event is InputEventMouseButton and event.pressed:
|
||||
print("Click")
|
||||
var target = _get_click_floor_pos()
|
||||
if target != Vector3.INF:
|
||||
print(" Request move")
|
||||
print(" ", target)
|
||||
# RPC an den Server (ID 1)
|
||||
request_move.rpc_id(1, target)
|
||||
|
||||
|
||||
func _get_click_floor_pos():
|
||||
# Wir brauchen die Kamera, die tatsächlich für diesen Viewport zuständig ist
|
||||
var camera = get_viewport().get_camera_3d()
|
||||
|
||||
# DEBUG: Falls keine Kamera gefunden wird, wissen wir woran es liegt
|
||||
if not camera:
|
||||
print("Keine Kamera im Viewport von ", name, " gefunden!")
|
||||
return Vector3.INF
|
||||
|
||||
var mouse_pos = get_viewport().get_mouse_position()
|
||||
var ray_origin = camera.project_ray_origin(mouse_pos)
|
||||
var ray_dir = camera.project_ray_normal(mouse_pos)
|
||||
|
||||
# Da wir in einer isolierten World3D sind, müssen wir den Physics-State
|
||||
# des Viewports direkt abfragen, statt nur gegen eine Plane zu prüfen:
|
||||
var space_state = get_world_3d().direct_space_state
|
||||
var query = PhysicsRayQueryParameters3D.create(ray_origin, ray_origin + ray_dir * 1000)
|
||||
|
||||
# Falls du Layer nutzt: query.collision_mask = 1
|
||||
var result = space_state.intersect_ray(query)
|
||||
|
||||
if result:
|
||||
return result.position
|
||||
|
||||
# Fallback auf Plane, falls kein Mesh getroffen wurde
|
||||
var world_plane = Plane(Vector3.UP, 0)
|
||||
var intersection = world_plane.intersects_ray(ray_origin, ray_dir)
|
||||
return intersection if intersection else Vector3.INF
|
||||
|
||||
|
||||
func _process(_delta):
|
||||
# Dieser Teil läuft auf dem Client (besonders dem, der die Authority hat)
|
||||
if not multiplayer.is_server():
|
||||
# Wir erzwingen die Position, die der Server berechnet hat
|
||||
global_position = sync_position
|
||||
rotation = sync_rotation
|
||||
1
weltenauge/systems/player/player_controller.gd.uid
Normal file
1
weltenauge/systems/player/player_controller.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bhym64rc7xtin
|
||||
13
weltenauge/ui/menus/main_menu.gd
Normal file
13
weltenauge/ui/menus/main_menu.gd
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
extends Control
|
||||
|
||||
@onready var ip_input: TextEdit = $IPInput
|
||||
|
||||
func _on_host_pressed():
|
||||
print("host pressed")
|
||||
GameEvents.host_requested.emit()
|
||||
hide()
|
||||
|
||||
func _on_join_pressed():
|
||||
print("join pressed")
|
||||
GameEvents.join_requested.emit(ip_input.text)
|
||||
hide()
|
||||
1
weltenauge/ui/menus/main_menu.gd.uid
Normal file
1
weltenauge/ui/menus/main_menu.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bp7b3a25eh6dh
|
||||
36
weltenauge/ui/menus/main_menu.tscn
Normal file
36
weltenauge/ui/menus/main_menu.tscn
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
[gd_scene format=3 uid="uid://bhywhrlwjox6t"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bp7b3a25eh6dh" path="res://ui/menus/main_menu.gd" id="1_5oih7"]
|
||||
|
||||
[node name="MainMenu" type="Control" unique_id=1694671237]
|
||||
layout_mode = 3
|
||||
anchors_preset = 0
|
||||
script = ExtResource("1_5oih7")
|
||||
|
||||
[node name="IPInput" type="TextEdit" parent="." unique_id=1340335140]
|
||||
custom_minimum_size = Vector2(150, 40)
|
||||
layout_mode = 0
|
||||
offset_left = 8.0
|
||||
offset_top = 7.0
|
||||
offset_right = 158.0
|
||||
offset_bottom = 47.0
|
||||
text = "127.0.0.1"
|
||||
|
||||
[node name="Join_Button" type="Button" parent="." unique_id=811892478]
|
||||
layout_mode = 0
|
||||
offset_left = 13.0
|
||||
offset_top = 58.0
|
||||
offset_right = 51.0
|
||||
offset_bottom = 89.0
|
||||
text = "Join"
|
||||
|
||||
[node name="Host_Button" type="Button" parent="." unique_id=1465654892]
|
||||
layout_mode = 0
|
||||
offset_left = 111.0
|
||||
offset_top = 58.0
|
||||
offset_right = 155.0
|
||||
offset_bottom = 89.0
|
||||
text = "Host"
|
||||
|
||||
[connection signal="button_up" from="Join_Button" to="." method="_on_join_pressed"]
|
||||
[connection signal="button_up" from="Host_Button" to="." method="_on_host_pressed"]
|
||||
126
workbench/zauberturm_html/index.html
Normal file
126
workbench/zauberturm_html/index.html
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Zauberturm Projekt-Log</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg-color: #0f111a;
|
||||
--card-bg: #1a1d2e;
|
||||
--accent-color: #7c4dff;
|
||||
--text-color: #e0e0e0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--bg-color);
|
||||
color: var(--text-color);
|
||||
font-family: 'Segoe UI', sans-serif;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
header {
|
||||
width: 100%;
|
||||
padding: 3rem 0;
|
||||
text-align: center;
|
||||
background: linear-gradient(to bottom, #161b33, var(--bg-color));
|
||||
border-bottom: 2px solid var(--accent-color);
|
||||
}
|
||||
|
||||
.gallery {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
|
||||
gap: 2rem;
|
||||
width: 90%;
|
||||
max-width: 1200px;
|
||||
padding: 3rem 0;
|
||||
}
|
||||
|
||||
.screenshot-card {
|
||||
background: var(--card-bg);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgba(255, 255, 255, 0.05);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.screenshot-card:hover {
|
||||
transform: translateY(-5px);
|
||||
border-color: var(--accent-color);
|
||||
box-shadow: 0 10px 20px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.screenshot-card img {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.info { padding: 1rem; text-align: center; border-top: 1px solid rgba(255,255,255,0.05); }
|
||||
.info span { font-size: 0.85rem; color: #888; font-family: monospace; }
|
||||
.info small { display: block; margin-top: 4px; color: #555; }
|
||||
|
||||
.empty-msg { grid-column: 1 / -1; text-align: center; padding: 5rem; color: #555; }
|
||||
|
||||
footer { margin-top: auto; padding: 2rem; color: #444; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<h1>Zauberturm.de</h1>
|
||||
<p>Projekt-Entwicklung: Screenshot Log</p>
|
||||
</header>
|
||||
|
||||
<div class="gallery">
|
||||
<?php
|
||||
$log_dir = 'image_log';
|
||||
$allowed_extensions = ['jpg', 'jpeg', 'png', 'webp'];
|
||||
|
||||
// Verzeichnis erstellen, falls es nicht existiert
|
||||
if (!is_dir($log_dir)) {
|
||||
mkdir($log_dir, 0755, true);
|
||||
}
|
||||
|
||||
// Dateien im Unterordner scannen
|
||||
$files = array_diff(scandir($log_dir), array('..', '.'));
|
||||
|
||||
if (count($files) > 0) {
|
||||
// Sortieren: Neueste Dateien zuerst
|
||||
usort($files, function($a, $b) use ($log_dir) {
|
||||
return filemtime($log_dir . '/' . $b) - filemtime($log_dir . '/' . $a);
|
||||
});
|
||||
|
||||
foreach ($files as $file) {
|
||||
$file_path = $log_dir . '/' . $file;
|
||||
$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
|
||||
|
||||
if (in_array($ext, $allowed_extensions)) {
|
||||
$date = date("d.m.Y H:i", filemtime($file_path));
|
||||
echo "
|
||||
<div class='screenshot-card'>
|
||||
<a href='$file_path' target='_blank'>
|
||||
<img src='$file_path' alt='Projekt Screenshot'>
|
||||
</a>
|
||||
<div class='info'>
|
||||
<span>$file</span>
|
||||
<small>$date</small>
|
||||
</div>
|
||||
</div>";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echo "<div class='empty-msg'>Keine Screenshots im Ordner /image_log/ gefunden.</div>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<footer>© 2026 zauberturm.de</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
BIN
workbench/zauberturm_html/logo_projekt_weltenauge.png
Normal file
BIN
workbench/zauberturm_html/logo_projekt_weltenauge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
workbench/zauberturm_html/logo_zauberturm.png
Normal file
BIN
workbench/zauberturm_html/logo_zauberturm.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
Loading…
Add table
Add a link
Reference in a new issue