merge: feat/tavern-scene into main
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Ruf der Pilze — Projektstatus
|
||||
|
||||
Zuletzt aktualisiert: 2026-04-14 (Plan Schritt 6 fertig)
|
||||
Zuletzt aktualisiert: 2026-04-14 (Schritt 5 abgeschlossen)
|
||||
|
||||
---
|
||||
|
||||
@@ -13,14 +13,13 @@ Zuletzt aktualisiert: 2026-04-14 (Plan Schritt 6 fertig)
|
||||
- **Multiplayer Grundgerüst** — ENet Server/Client, NetworkManager Autoload, welcome RPC verifiziert
|
||||
- **Lobby + Rollen** — Join-UI, Warteraum, Spieler/DM-Rollen, Sync, Kick, Spiel-Start-Signal
|
||||
- **Tavern Lobby** — 3D-Taverne ersetzt die flache Lobby-UI; SceneManager Autoload eingeführt
|
||||
- **Taverne + Szenen-Wechsel** — 2-stöckige In-Game-Taverne (Blockout), taproom.tscn als Sub-Scene,
|
||||
game_started → Spieler in zugewiesenem Zimmer (SpawnPoint), DM in dm_view.tscn Stub
|
||||
|
||||
### 🔄 In Arbeit
|
||||
— (nichts aktiv)
|
||||
|
||||
### ⏳ Als nächstes
|
||||
- **Taverne + Szenen-Wechsel nach Spielstart** — 2-stöckige In-Game-Taverne (Blockout), taproom als Sub-Scene, game_started → Spieler in Zimmer, DM in Stub-Szene
|
||||
Spec: `docs/superpowers/specs/2026-04-14-tavern-scene-design.md`
|
||||
Plan: `docs/plans/2026-04-14-tavern-scene-plan.md`
|
||||
- **DM Regiepult Basics** — Top-Down-Karte (EG/OG), Spieler-Positionsmarker, Live-Cam-Feeds pro Spieler, Overlay-Toggle
|
||||
Plan: `docs/plans/2026-04-14-dm-regiepult-basics.md`
|
||||
|
||||
@@ -32,7 +31,7 @@ Zuletzt aktualisiert: 2026-04-14 (Plan Schritt 6 fertig)
|
||||
2. ✅ Multiplayer Grundgerüst (Server, Clients verbinden, rpc testen)
|
||||
3. ✅ Lobby + Rollen (Spieler registrieren sich, DM kriegt Sonderrechte)
|
||||
4. ✅ Tavern Lobby — 3D-Taverne als Warteraum, SceneManager Autoload
|
||||
5. ⏳ Szenen-Wechsel nach Spielstart — Chamber/DM-Szene nach game_started
|
||||
5. ✅ Szenen-Wechsel nach Spielstart — taproom Sub-Scene, 2 Etagen, SpawnPoints, dm_view Stub
|
||||
6. ⏳ DM Regiepult Basics — Overlay-Toggle, Top-Down pro Etage, Player-Cams
|
||||
Plan: `docs/plans/2026-04-14-dm-regiepult-basics.md`
|
||||
7. ⏳ Refectorium — asymmetrische Wahrnehmung (erster Raum)
|
||||
|
||||
@@ -233,10 +233,9 @@ Verzeichnis: `../Anna_Model/` (außerhalb von `ruf-der-pilze/`, im Repo-Root)
|
||||
2. ✅ Multiplayer Grundgerüst (Server, Clients verbinden, rpc testen)
|
||||
3. ✅ Lobby + Rollen (Spieler mit Name + Rolle, DM-Sonderrechte)
|
||||
4. ✅ Tavern Lobby — 3D-Taverne als Warteraum, SceneManager Autoload
|
||||
5. ⏳ Taverne + Szenen-Wechsel — 2-stöckige In-Game-Taverne (Blockout), taproom.tscn
|
||||
5. ✅ Taverne + Szenen-Wechsel — 2-stöckige In-Game-Taverne (Blockout), taproom.tscn
|
||||
als Sub-Scene, game_started → Spieler in Zimmer (SpawnPoint), DM → dm_view.tscn
|
||||
Kein separates "chamber" — Zimmer sind Teil von tavern.tscn
|
||||
Plan: ../docs/plans/2026-04-14-tavern-scene-plan.md
|
||||
6. ⏳ DM Regiepult Basics — Overlay-Toggle, Top-Down pro Etage, Player-Cams
|
||||
Plan: `../docs/plans/2026-04-14-dm-regiepult-basics.md`
|
||||
7. ⏳ Erster Raum — Refectory mit asymmetrischer Wahrnehmung
|
||||
|
||||
@@ -5,55 +5,27 @@
|
||||
[node name="DmView" type="Node"]
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="RootLayout" type="VBoxContainer" parent="."]
|
||||
[node name="ViewportContainer" type="SubViewportContainer" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="TopSection" type="HSplitContainer" parent="RootLayout"]
|
||||
size_flags_vertical = 3
|
||||
[node name="SubViewport" type="SubViewport" parent="ViewportContainer"]
|
||||
|
||||
[node name="MapContainer" type="SubViewportContainer" parent="RootLayout/TopSection"]
|
||||
custom_minimum_size = Vector2(700, 500)
|
||||
size_flags_horizontal = 3
|
||||
stretch = true
|
||||
|
||||
[node name="MapViewport" type="SubViewport" parent="RootLayout/TopSection/MapContainer"]
|
||||
size = Vector2i(700, 500)
|
||||
|
||||
[node name="MapRoot" type="Node3D" parent="RootLayout/TopSection/MapContainer/MapViewport"]
|
||||
|
||||
[node name="PlayerMarkers" type="Node3D" parent="RootLayout/TopSection/MapContainer/MapViewport/MapRoot"]
|
||||
|
||||
[node name="TopDownCam" type="Camera3D" parent="RootLayout/TopSection/MapContainer/MapViewport/MapRoot"]
|
||||
transform = Transform3D(1, 0, 0, 0, 0, -1, 0, 1, 0, 2, 25, 0)
|
||||
[node name="Camera3D" type="Camera3D" parent="ViewportContainer/SubViewport"]
|
||||
transform = Transform3D(1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 20, 0)
|
||||
current = true
|
||||
|
||||
[node name="SidePanel" type="VBoxContainer" parent="RootLayout/TopSection"]
|
||||
custom_minimum_size = Vector2(220, 0)
|
||||
[node name="UI" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="LblFloor" type="Label" parent="RootLayout/TopSection/SidePanel"]
|
||||
text = "Etage"
|
||||
|
||||
[node name="FloorButtons" type="HBoxContainer" parent="RootLayout/TopSection/SidePanel"]
|
||||
|
||||
[node name="BtnEG" type="Button" parent="RootLayout/TopSection/SidePanel/FloorButtons"]
|
||||
text = "Erdgeschoss"
|
||||
toggle_mode = true
|
||||
button_pressed = true
|
||||
|
||||
[node name="BtnOG" type="Button" parent="RootLayout/TopSection/SidePanel/FloorButtons"]
|
||||
text = "Obergeschoss"
|
||||
toggle_mode = true
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="RootLayout/TopSection/SidePanel"]
|
||||
|
||||
[node name="LblOverlay" type="Label" parent="RootLayout/TopSection/SidePanel"]
|
||||
text = "Overlays"
|
||||
|
||||
[node name="OverlayScroll" type="ScrollContainer" parent="RootLayout/TopSection/SidePanel"]
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="PlayerList" type="VBoxContainer" parent="RootLayout/TopSection/SidePanel/OverlayScroll"]
|
||||
|
||||
[node name="HSeparator2" type="HSeparator" parent="RootLayout"]
|
||||
|
||||
[node name="PlayerCamsRow" type="HBoxContainer" parent="RootLayout"]
|
||||
custom_minimum_size = Vector2(0, 200)
|
||||
[node name="StubLabel" type="Label" parent="UI"]
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -150.0
|
||||
offset_top = -30.0
|
||||
offset_right = 150.0
|
||||
offset_bottom = 30.0
|
||||
text = "DM View — Stub
|
||||
(wird in Schritt 7 ausgebaut)"
|
||||
horizontal_alignment = 1
|
||||
|
||||
120
ruf-der-pilze/scenes/taproom.tscn
Normal file
120
ruf-der-pilze/scenes/taproom.tscn
Normal file
@@ -0,0 +1,120 @@
|
||||
[gd_scene load_steps=22 format=3]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="Material_wood"]
|
||||
albedo_color = Color(0.169, 0.102, 0.051, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_floor"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_floor"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_ceiling"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_ceiling"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_wallback"]
|
||||
size = Vector3(12, 4, 0.1)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wallback"]
|
||||
size = Vector3(12, 4, 0.1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_wallleft"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wallleft"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_wallright"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wallright"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_bar"]
|
||||
size = Vector3(4, 1.1, 0.3)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_bar"]
|
||||
size = Vector3(4, 1.1, 0.3)
|
||||
|
||||
[sub_resource type="Environment" id="Environment_1"]
|
||||
background_mode = 1
|
||||
background_color = Color(0.102, 0.059, 0, 1)
|
||||
ambient_light_color = Color(0.6, 0.35, 0.1, 1)
|
||||
ambient_light_energy = 0.4
|
||||
fog_enabled = true
|
||||
fog_light_color = Color(0.102, 0.059, 0, 1)
|
||||
fog_density = 0.05
|
||||
|
||||
[node name="Taproom" type="Node3D"]
|
||||
|
||||
[node name="Floor" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Floor"]
|
||||
mesh = SubResource("BoxMesh_floor")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Floor"]
|
||||
shape = SubResource("BoxShape3D_floor")
|
||||
|
||||
[node name="Ceiling" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.05, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ceiling"]
|
||||
mesh = SubResource("BoxMesh_ceiling")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ceiling"]
|
||||
shape = SubResource("BoxShape3D_ceiling")
|
||||
|
||||
[node name="WallBack" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, -4)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="WallBack"]
|
||||
mesh = SubResource("BoxMesh_wallback")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallBack"]
|
||||
shape = SubResource("BoxShape3D_wallback")
|
||||
|
||||
[node name="WallLeft" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 2, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="WallLeft"]
|
||||
mesh = SubResource("BoxMesh_wallleft")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallLeft"]
|
||||
shape = SubResource("BoxShape3D_wallleft")
|
||||
|
||||
[node name="WallRight" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 2, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="WallRight"]
|
||||
mesh = SubResource("BoxMesh_wallright")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="WallRight"]
|
||||
shape = SubResource("BoxShape3D_wallright")
|
||||
|
||||
[node name="Bar" type="StaticBody3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 0.55, -3.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Bar"]
|
||||
mesh = SubResource("BoxMesh_bar")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Bar"]
|
||||
shape = SubResource("BoxShape3D_bar")
|
||||
|
||||
[node name="Light" type="OmniLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
|
||||
light_color = Color(0.91, 0.643, 0.29, 1)
|
||||
light_energy = 1.2
|
||||
omni_range = 10.0
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_1")
|
||||
@@ -1,108 +1,402 @@
|
||||
[gd_scene load_steps=8 format=3]
|
||||
[gd_scene load_steps=28 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/tavern.gd" id="1"]
|
||||
[ext_resource type="PackedScene" path="res://scenes/taproom.tscn" id="2"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_1"]
|
||||
background_mode = 1
|
||||
background_color = Color(0.102, 0.059, 0, 1)
|
||||
ambient_light_color = Color(0.6, 0.35, 0.1, 1)
|
||||
ambient_light_energy = 0.4
|
||||
fog_enabled = true
|
||||
fog_light_color = Color(0.102, 0.059, 0, 1)
|
||||
fog_density = 0.05
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="Material_1"]
|
||||
[sub_resource type="StandardMaterial3D" id="Material_wood"]
|
||||
albedo_color = Color(0.169, 0.102, 0.051, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_floor"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
[sub_resource type="StandardMaterial3D" id="Material_myzel"]
|
||||
albedo_color = Color(0.2, 0.8, 0.3, 1)
|
||||
emission_enabled = true
|
||||
emission = Color(0.1, 0.4, 0.1, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_ceiling"]
|
||||
size = Vector3(12, 0.1, 8)
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kitchen_back"]
|
||||
size = Vector3(4, 3, 0.1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_back"]
|
||||
size = Vector3(12, 4, 0.1)
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_kitchen_back"]
|
||||
size = Vector3(4, 3, 0.1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_left"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_kitchen_side"]
|
||||
size = Vector3(0.1, 3, 2.3)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_right"]
|
||||
size = Vector3(0.1, 4, 8)
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_kitchen_side"]
|
||||
size = Vector3(0.1, 3, 2.3)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_door"]
|
||||
size = Vector3(0.1, 4, 2)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_door"]
|
||||
size = Vector3(0.1, 4, 2)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_trail_long"]
|
||||
size = Vector3(0.5, 0.01, 3)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_trail_medium"]
|
||||
size = Vector3(0.5, 0.01, 4)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_stairs"]
|
||||
size = Vector3(1.5, 0.2, 4)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_stairs"]
|
||||
size = Vector3(1.5, 0.2, 4)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_upper_floor"]
|
||||
size = Vector3(18, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_upper_floor"]
|
||||
size = Vector3(18, 0.1, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_upper_wall_long"]
|
||||
size = Vector3(18, 3, 0.1)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_upper_wall_long"]
|
||||
size = Vector3(18, 3, 0.1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_upper_wall_short"]
|
||||
size = Vector3(0.1, 3, 8)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_upper_wall_short"]
|
||||
size = Vector3(0.1, 3, 8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_bed"]
|
||||
size = Vector3(1.8, 0.5, 0.9)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_bed"]
|
||||
size = Vector3(1.8, 0.5, 0.9)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_anna_door"]
|
||||
size = Vector3(0.05, 2.5, 1.2)
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_anna_door"]
|
||||
size = Vector3(0.05, 2.5, 1.2)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_myzel_patch"]
|
||||
size = Vector3(0.8, 0.01, 0.8)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_myzel_trail_anna"]
|
||||
size = Vector3(0.4, 0.01, 1.5)
|
||||
|
||||
[node name="Tavern" type="Node3D"]
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.951, 0.309, 0, -0.309, 0.951, 0, 3, 6)
|
||||
fov = 70.0
|
||||
current = true
|
||||
[node name="Taproom" parent="." instance=ExtResource("2")]
|
||||
|
||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||
environment = SubResource("Environment_1")
|
||||
[node name="GroundFloor" type="Node3D" parent="."]
|
||||
|
||||
[node name="OmniLight3D" type="OmniLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.5, 0)
|
||||
light_color = Color(0.91, 0.643, 0.29, 1)
|
||||
light_energy = 1.2
|
||||
omni_range = 10.0
|
||||
[node name="KitchenBack" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 1.5, -5.9)
|
||||
|
||||
[node name="Floor" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0)
|
||||
mesh = SubResource("BoxMesh_floor")
|
||||
surface_material_override/0 = SubResource("Material_1")
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/KitchenBack"]
|
||||
mesh = SubResource("BoxMesh_kitchen_back")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="Ceiling" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 4.05, 0)
|
||||
mesh = SubResource("BoxMesh_ceiling")
|
||||
surface_material_override/0 = SubResource("Material_1")
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/KitchenBack"]
|
||||
shape = SubResource("BoxShape3D_kitchen_back")
|
||||
|
||||
[node name="WallBack" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, -4)
|
||||
mesh = SubResource("BoxMesh_back")
|
||||
surface_material_override/0 = SubResource("Material_1")
|
||||
[node name="KitchenLeft" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.05, 1.5, -4.85)
|
||||
|
||||
[node name="WallLeft" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 2, 0)
|
||||
mesh = SubResource("BoxMesh_left")
|
||||
surface_material_override/0 = SubResource("Material_1")
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/KitchenLeft"]
|
||||
mesh = SubResource("BoxMesh_kitchen_side")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="WallRight" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 2, 0)
|
||||
mesh = SubResource("BoxMesh_right")
|
||||
surface_material_override/0 = SubResource("Material_1")
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/KitchenLeft"]
|
||||
shape = SubResource("BoxShape3D_kitchen_side")
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
[node name="KitchenRight" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.95, 1.5, -4.85)
|
||||
|
||||
[node name="JoinPanel" type="VBoxContainer" parent="CanvasLayer"]
|
||||
offset_left = 300.0
|
||||
offset_top = 200.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 500.0
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/KitchenRight"]
|
||||
mesh = SubResource("BoxMesh_kitchen_side")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="Title" type="Label" parent="CanvasLayer/JoinPanel"]
|
||||
text = "Ruf der Pilze"
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/KitchenRight"]
|
||||
shape = SubResource("BoxShape3D_kitchen_side")
|
||||
|
||||
[node name="NameInput" type="LineEdit" parent="CanvasLayer/JoinPanel"]
|
||||
placeholder_text = "Dein Name"
|
||||
[node name="PrivateRoomDoor" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 2, 2)
|
||||
|
||||
[node name="RoleOption" type="OptionButton" parent="CanvasLayer/JoinPanel"]
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/PrivateRoomDoor"]
|
||||
mesh = SubResource("BoxMesh_door")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="JoinButton" type="Button" parent="CanvasLayer/JoinPanel"]
|
||||
text = "Beitreten"
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/PrivateRoomDoor"]
|
||||
shape = SubResource("BoxShape3D_door")
|
||||
|
||||
[node name="WaitPanel" type="VBoxContainer" parent="CanvasLayer"]
|
||||
visible = false
|
||||
offset_left = 300.0
|
||||
offset_top = 200.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 500.0
|
||||
[node name="ExitDoor" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6, 2, 4)
|
||||
|
||||
[node name="WaitLabel" type="Label" parent="CanvasLayer/WaitPanel"]
|
||||
text = "Warte auf Spieler..."
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/ExitDoor"]
|
||||
mesh = SubResource("BoxMesh_door")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="PlayerList" type="ItemList" parent="CanvasLayer/WaitPanel"]
|
||||
custom_minimum_size = Vector2(0, 150)
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/ExitDoor"]
|
||||
shape = SubResource("BoxShape3D_door")
|
||||
|
||||
[node name="StartButton" type="Button" parent="CanvasLayer/WaitPanel"]
|
||||
text = "Spiel starten"
|
||||
visible = false
|
||||
[node name="MyzelTrailGround" type="Node3D" parent="GroundFloor"]
|
||||
|
||||
[node name="TrailSegment1" type="MeshInstance3D" parent="GroundFloor/MyzelTrailGround"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.06, 1.5)
|
||||
mesh = SubResource("BoxMesh_trail_long")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
[node name="TrailSegment2" type="MeshInstance3D" parent="GroundFloor/MyzelTrailGround"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 0.06, 0)
|
||||
mesh = SubResource("BoxMesh_trail_medium")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
[node name="Stairs" type="StaticBody3D" parent="GroundFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.906, -0.423, 0, 0.423, 0.906, 0, 1, 3)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="GroundFloor/Stairs"]
|
||||
mesh = SubResource("BoxMesh_stairs")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundFloor/Stairs"]
|
||||
shape = SubResource("BoxShape3D_stairs")
|
||||
|
||||
[node name="UpperFloor" type="Node3D" parent="."]
|
||||
|
||||
[node name="Floor" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 4, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Floor"]
|
||||
mesh = SubResource("BoxMesh_upper_floor")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Floor"]
|
||||
shape = SubResource("BoxShape3D_upper_floor")
|
||||
|
||||
[node name="Ceiling" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 7, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Ceiling"]
|
||||
mesh = SubResource("BoxMesh_upper_floor")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Ceiling"]
|
||||
shape = SubResource("BoxShape3D_upper_floor")
|
||||
|
||||
[node name="WallBack" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 5.5, -4)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/WallBack"]
|
||||
mesh = SubResource("BoxMesh_upper_wall_long")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/WallBack"]
|
||||
shape = SubResource("BoxShape3D_upper_wall_long")
|
||||
|
||||
[node name="WallFront" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 5.5, 4)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/WallFront"]
|
||||
mesh = SubResource("BoxMesh_upper_wall_long")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/WallFront"]
|
||||
shape = SubResource("BoxShape3D_upper_wall_long")
|
||||
|
||||
[node name="WallLeft" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -6, 5.5, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/WallLeft"]
|
||||
mesh = SubResource("BoxMesh_upper_wall_short")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/WallLeft"]
|
||||
shape = SubResource("BoxShape3D_upper_wall_short")
|
||||
|
||||
[node name="WallRight" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 5.5, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/WallRight"]
|
||||
mesh = SubResource("BoxMesh_upper_wall_short")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/WallRight"]
|
||||
shape = SubResource("BoxShape3D_upper_wall_short")
|
||||
|
||||
[node name="CorridorWall" type="StaticBody3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 5.5, 2)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/CorridorWall"]
|
||||
mesh = SubResource("BoxMesh_upper_wall_long")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/CorridorWall"]
|
||||
shape = SubResource("BoxShape3D_upper_wall_long")
|
||||
|
||||
[node name="Room1" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -5, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room1"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room1/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room1/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room1"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room2" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -3, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room2/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room2/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room2"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room3" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room3"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room3/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room3/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room3"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room4" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room4"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room4/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room4/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room4"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room5" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room5"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room5/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room5/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room5"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room6" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room6"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room6/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room6/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room6"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room7" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room7"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room7/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room7/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room7"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room8" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room8"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room8/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room8/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room8"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="Room9" type="Node3D" parent="UpperFloor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11, 4.1, 2.8)
|
||||
|
||||
[node name="Bed" type="StaticBody3D" parent="UpperFloor/Room9"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.25, -2.5)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room9/Bed"]
|
||||
mesh = SubResource("BoxMesh_bed")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room9/Bed"]
|
||||
shape = SubResource("BoxShape3D_bed")
|
||||
|
||||
[node name="SpawnPoint" type="Marker3D" parent="UpperFloor/Room9"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0, -1)
|
||||
|
||||
[node name="OpenDoor" type="StaticBody3D" parent="UpperFloor/Room9"]
|
||||
transform = Transform3D(0, 0, 1, 0, 1, 0, -1, 0, 0, 0.6, 1.25, 0.2)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="UpperFloor/Room9/OpenDoor"]
|
||||
mesh = SubResource("BoxMesh_anna_door")
|
||||
surface_material_override/0 = SubResource("Material_wood")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="UpperFloor/Room9/OpenDoor"]
|
||||
shape = SubResource("BoxShape3D_anna_door")
|
||||
|
||||
[node name="MyzelDecor" type="Node3D" parent="UpperFloor/Room9"]
|
||||
|
||||
[node name="MyzelPatch1" type="MeshInstance3D" parent="UpperFloor/Room9/MyzelDecor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.3, 0.01, -2)
|
||||
mesh = SubResource("BoxMesh_myzel_patch")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
[node name="MyzelPatch2" type="MeshInstance3D" parent="UpperFloor/Room9/MyzelDecor"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.5, 0.8, -3.8)
|
||||
mesh = SubResource("BoxMesh_myzel_patch")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
[node name="MyzelTrailAnna" type="Node3D" parent="UpperFloor/Room9"]
|
||||
|
||||
[node name="TrailOut" type="MeshInstance3D" parent="UpperFloor/Room9/MyzelTrailAnna"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.06, 1.2)
|
||||
mesh = SubResource("BoxMesh_myzel_trail_anna")
|
||||
surface_material_override/0 = SubResource("Material_myzel")
|
||||
|
||||
50
ruf-der-pilze/scenes/tavern_lobby.tscn
Normal file
50
ruf-der-pilze/scenes/tavern_lobby.tscn
Normal file
@@ -0,0 +1,50 @@
|
||||
[gd_scene load_steps=2 format=3]
|
||||
|
||||
[ext_resource type="Script" path="res://scripts/tavern_lobby.gd" id="1"]
|
||||
[ext_resource type="PackedScene" path="res://scenes/taproom.tscn" id="2"]
|
||||
|
||||
[node name="TavernLobby" type="Node3D"]
|
||||
script = ExtResource("1")
|
||||
|
||||
[node name="Taproom" parent="." instance=ExtResource("2")]
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.951, 0.309, 0, -0.309, 0.951, 0, 3, 6)
|
||||
fov = 70.0
|
||||
current = true
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="JoinPanel" type="VBoxContainer" parent="CanvasLayer"]
|
||||
offset_left = 300.0
|
||||
offset_top = 200.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 500.0
|
||||
|
||||
[node name="Title" type="Label" parent="CanvasLayer/JoinPanel"]
|
||||
text = "Ruf der Pilze"
|
||||
|
||||
[node name="NameInput" type="LineEdit" parent="CanvasLayer/JoinPanel"]
|
||||
placeholder_text = "Dein Name"
|
||||
|
||||
[node name="RoleOption" type="OptionButton" parent="CanvasLayer/JoinPanel"]
|
||||
|
||||
[node name="JoinButton" type="Button" parent="CanvasLayer/JoinPanel"]
|
||||
text = "Beitreten"
|
||||
|
||||
[node name="WaitPanel" type="VBoxContainer" parent="CanvasLayer"]
|
||||
visible = false
|
||||
offset_left = 300.0
|
||||
offset_top = 200.0
|
||||
offset_right = 700.0
|
||||
offset_bottom = 500.0
|
||||
|
||||
[node name="WaitLabel" type="Label" parent="CanvasLayer/WaitPanel"]
|
||||
text = "Warte auf Spieler..."
|
||||
|
||||
[node name="PlayerList" type="ItemList" parent="CanvasLayer/WaitPanel"]
|
||||
custom_minimum_size = Vector2(0, 150)
|
||||
|
||||
[node name="StartButton" type="Button" parent="CanvasLayer/WaitPanel"]
|
||||
text = "Spiel starten"
|
||||
visible = false
|
||||
@@ -1,216 +1,5 @@
|
||||
extends Node
|
||||
|
||||
const TAVERN_SCENE := "res://scenes/tavern.tscn"
|
||||
const CAM_EG_Y := 25.0
|
||||
const CAM_OG_Y := 30.0
|
||||
const OVERLAY_CYCLE := ["default", "spore_active"]
|
||||
|
||||
var _top_down_cam: Camera3D
|
||||
var _player_markers: Node3D
|
||||
var _markers_by_id: Dictionary = {} # peer_id → MeshInstance3D
|
||||
var _player_cam_cams: Dictionary = {} # peer_id → Camera3D (in SubViewport)
|
||||
var _showing_upper_floor: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$RootLayout.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
||||
_load_tavern_into_viewport()
|
||||
_setup_floor_buttons()
|
||||
_setup_player_cams()
|
||||
_setup_overlay_panel()
|
||||
|
||||
|
||||
func _load_tavern_into_viewport() -> void:
|
||||
var packed := ResourceLoader.load(TAVERN_SCENE, "PackedScene") as PackedScene
|
||||
if packed == null:
|
||||
push_error("[DmView] tavern.tscn nicht gefunden — wird nach Schritt 5 verfügbar sein")
|
||||
return
|
||||
var map_root := $RootLayout/TopSection/MapContainer/MapViewport/MapRoot as Node3D
|
||||
_top_down_cam = map_root.get_node("TopDownCam") as Camera3D
|
||||
_player_markers = map_root.get_node("PlayerMarkers") as Node3D
|
||||
var tavern := packed.instantiate()
|
||||
tavern.name = "Tavern"
|
||||
map_root.add_child(tavern)
|
||||
print("[DmView] Tavern in SubViewport geladen")
|
||||
|
||||
|
||||
func _setup_floor_buttons() -> void:
|
||||
var btn_eg := $RootLayout/TopSection/SidePanel/FloorButtons/BtnEG as Button
|
||||
var btn_og := $RootLayout/TopSection/SidePanel/FloorButtons/BtnOG as Button
|
||||
btn_eg.pressed.connect(func() -> void: _switch_floor(false))
|
||||
btn_og.pressed.connect(func() -> void: _switch_floor(true))
|
||||
|
||||
|
||||
func _switch_floor(upper: bool) -> void:
|
||||
_showing_upper_floor = upper
|
||||
if _top_down_cam == null:
|
||||
return
|
||||
_top_down_cam.global_position.y = CAM_OG_Y if upper else CAM_EG_Y
|
||||
print("[DmView] Etage gewechselt → %s" % ("OG" if upper else "EG"))
|
||||
|
||||
|
||||
# --- Player Cam Feeds (Task 7) ---
|
||||
|
||||
func _setup_player_cams() -> void:
|
||||
NetworkManager.player_joined.connect(_on_player_joined_cam)
|
||||
NetworkManager.player_left.connect(_on_player_left_cam)
|
||||
for peer_id in NetworkManager.players.keys():
|
||||
var info: Dictionary = NetworkManager.players[peer_id]
|
||||
if info.get("role", "") == "player":
|
||||
_create_player_cam(peer_id, info.get("name", "???"))
|
||||
|
||||
|
||||
func _on_player_joined_cam(peer_id: int, player_name: String, role: String) -> void:
|
||||
if role == "player":
|
||||
_create_player_cam(peer_id, player_name)
|
||||
|
||||
|
||||
func _on_player_left_cam(peer_id: int) -> void:
|
||||
var row := $RootLayout/PlayerCamsRow
|
||||
var panel := row.get_node_or_null("CamPanel_%d" % peer_id)
|
||||
if panel != null:
|
||||
panel.queue_free()
|
||||
_player_cam_cams.erase(peer_id)
|
||||
|
||||
|
||||
func _create_player_cam(peer_id: int, player_name: String) -> void:
|
||||
var packed := ResourceLoader.load(TAVERN_SCENE, "PackedScene") as PackedScene
|
||||
if packed == null:
|
||||
push_error("[DmView] tavern.tscn nicht gefunden für Player-Cam")
|
||||
return
|
||||
|
||||
var viewport := SubViewport.new()
|
||||
viewport.size = Vector2i(320, 180)
|
||||
|
||||
var scene_root := Node3D.new()
|
||||
var tavern := packed.instantiate()
|
||||
scene_root.add_child(tavern)
|
||||
|
||||
var cam := Camera3D.new()
|
||||
cam.name = "PlayerCam"
|
||||
cam.current = true
|
||||
scene_root.add_child(cam)
|
||||
viewport.add_child(scene_root)
|
||||
|
||||
var container := SubViewportContainer.new()
|
||||
container.name = "CamPanel_%d" % peer_id
|
||||
container.custom_minimum_size = Vector2(320, 180)
|
||||
container.stretch = true
|
||||
container.add_child(viewport)
|
||||
|
||||
var wrapper := VBoxContainer.new()
|
||||
var label := Label.new()
|
||||
label.text = player_name
|
||||
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
wrapper.add_child(label)
|
||||
wrapper.add_child(container)
|
||||
|
||||
$RootLayout/PlayerCamsRow.add_child(wrapper)
|
||||
_player_cam_cams[peer_id] = cam
|
||||
print("[DmView] Player-Cam erstellt für %s (Peer %d)" % [player_name, peer_id])
|
||||
|
||||
|
||||
# --- Overlay Panel (Task 8) ---
|
||||
|
||||
func _setup_overlay_panel() -> void:
|
||||
NetworkManager.player_joined.connect(_on_player_joined)
|
||||
NetworkManager.player_left.connect(_on_player_left)
|
||||
for peer_id in NetworkManager.players.keys():
|
||||
var info: Dictionary = NetworkManager.players[peer_id]
|
||||
if info.get("role", "") == "player":
|
||||
_add_overlay_row(peer_id, info.get("name", "???"))
|
||||
|
||||
|
||||
func _on_player_joined(peer_id: int, player_name: String, role: String) -> void:
|
||||
if role == "player":
|
||||
_add_overlay_row(peer_id, player_name)
|
||||
|
||||
|
||||
func _on_player_left(peer_id: int) -> void:
|
||||
var list := $RootLayout/TopSection/SidePanel/OverlayScroll/PlayerList as VBoxContainer
|
||||
var row := list.get_node_or_null("Row_%d" % peer_id)
|
||||
if row != null:
|
||||
row.queue_free()
|
||||
|
||||
|
||||
func _add_overlay_row(peer_id: int, player_name: String) -> void:
|
||||
var list := $RootLayout/TopSection/SidePanel/OverlayScroll/PlayerList as VBoxContainer
|
||||
var row := HBoxContainer.new()
|
||||
row.name = "Row_%d" % peer_id
|
||||
var label := Label.new()
|
||||
label.text = player_name
|
||||
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
||||
var btn := Button.new()
|
||||
btn.text = "● default"
|
||||
btn.pressed.connect(func() -> void: _toggle_overlay(peer_id, btn))
|
||||
row.add_child(label)
|
||||
row.add_child(btn)
|
||||
list.add_child(row)
|
||||
|
||||
|
||||
func _toggle_overlay(peer_id: int, btn: Button) -> void:
|
||||
var current := GameState.get_overlay(peer_id)
|
||||
var idx := OVERLAY_CYCLE.find(current)
|
||||
var next: String = OVERLAY_CYCLE[(idx + 1) % OVERLAY_CYCLE.size()]
|
||||
NetworkManager.request_set_overlay.rpc_id(1, peer_id, next)
|
||||
GameState.set_overlay_local(peer_id, next)
|
||||
btn.text = "● %s" % next
|
||||
print("[DmView] Overlay-Toggle → Spieler %d: %s" % [peer_id, next])
|
||||
|
||||
|
||||
# --- _process: Marker + Cam updates ---
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
_update_player_markers()
|
||||
_update_player_cams()
|
||||
|
||||
|
||||
func _update_player_markers() -> void:
|
||||
if _player_markers == null:
|
||||
return
|
||||
for peer_id in GameState.player_positions.keys():
|
||||
var data: Dictionary = GameState.player_positions[peer_id]
|
||||
var pos: Vector3 = data.get("position", Vector3.ZERO)
|
||||
var rot: Vector3 = data.get("rotation", Vector3.ZERO)
|
||||
var marker := _get_or_create_marker(peer_id)
|
||||
marker.global_position = pos + Vector3(0, 0.2, 0)
|
||||
marker.rotation.y = rot.y
|
||||
var is_upper := pos.y > 3.5
|
||||
marker.visible = (is_upper == _showing_upper_floor)
|
||||
|
||||
|
||||
func _get_or_create_marker(peer_id: int) -> MeshInstance3D:
|
||||
if peer_id in _markers_by_id:
|
||||
return _markers_by_id[peer_id]
|
||||
var mesh := MeshInstance3D.new()
|
||||
var sphere := SphereMesh.new()
|
||||
sphere.radius = 0.25
|
||||
sphere.height = 0.5
|
||||
mesh.mesh = sphere
|
||||
var mat := StandardMaterial3D.new()
|
||||
mat.albedo_color = _peer_color(peer_id)
|
||||
mat.emission_enabled = true
|
||||
mat.emission = mat.albedo_color
|
||||
mat.emission_energy_multiplier = 0.5
|
||||
mesh.material_override = mat
|
||||
_player_markers.add_child(mesh)
|
||||
_markers_by_id[peer_id] = mesh
|
||||
print("[DmView] Marker erstellt für Peer %d" % peer_id)
|
||||
return mesh
|
||||
|
||||
|
||||
func _peer_color(peer_id: int) -> Color:
|
||||
var colors := [Color.RED, Color.CYAN, Color.YELLOW, Color.MAGENTA, Color.GREEN]
|
||||
return colors[peer_id % colors.size()]
|
||||
|
||||
|
||||
func _update_player_cams() -> void:
|
||||
for peer_id in _player_cam_cams.keys():
|
||||
if not GameState.player_positions.has(peer_id):
|
||||
continue
|
||||
var data: Dictionary = GameState.player_positions[peer_id]
|
||||
var pos: Vector3 = data.get("position", Vector3.ZERO)
|
||||
var rot: Vector3 = data.get("rotation", Vector3.ZERO)
|
||||
var cam: Camera3D = _player_cam_cams[peer_id]
|
||||
cam.global_position = pos
|
||||
cam.global_rotation = rot
|
||||
print("[DmView] DM-Szene geladen (Stub)")
|
||||
|
||||
@@ -118,14 +118,27 @@ func request_start_game() -> void:
|
||||
var requester_id := multiplayer.get_remote_sender_id()
|
||||
if players.get(requester_id, {}).get("role", "") != "dm":
|
||||
return
|
||||
start_game.rpc()
|
||||
var assignments := _build_room_assignments()
|
||||
start_game.rpc(assignments)
|
||||
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func start_game() -> void:
|
||||
func start_game(room_assignments: Dictionary) -> void:
|
||||
if my_id in room_assignments:
|
||||
SceneManager.pending_room_index = room_assignments[my_id]
|
||||
game_started.emit()
|
||||
|
||||
|
||||
func _build_room_assignments() -> Dictionary:
|
||||
var result := {}
|
||||
var player_peers: Array = players.keys().filter(
|
||||
func(id: int) -> bool: return players[id].role == "player"
|
||||
)
|
||||
for i in player_peers.size():
|
||||
result[player_peers[i]] = i % 8 # 8 Gästezimmer (Index 0–7)
|
||||
return result
|
||||
|
||||
|
||||
# call_remote: Server hat lokal bereits gelöscht; nur Clients führen aus
|
||||
@rpc("authority", "call_remote", "reliable")
|
||||
func _broadcast_player_left(peer_id: int) -> void:
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
extends Node
|
||||
|
||||
const SCENES := {
|
||||
"tavern": "res://scenes/tavern.tscn",
|
||||
"chamber": "res://scenes/chamber.tscn",
|
||||
"lobby": "res://scenes/tavern_lobby.tscn",
|
||||
"tavern": "res://scenes/tavern.tscn",
|
||||
"dm_view": "res://scenes/dm_view.tscn",
|
||||
"entrance_hall": "res://scenes/entrance_hall.tscn",
|
||||
"refectory": "res://scenes/refectory.tscn",
|
||||
"library": "res://scenes/library.tscn",
|
||||
"chapel": "res://scenes/chapel.tscn",
|
||||
"cloister": "res://scenes/cloister.tscn",
|
||||
"sanctum": "res://scenes/sanctum.tscn",
|
||||
"refectory": "res://scenes/refectory.tscn",
|
||||
"library": "res://scenes/library.tscn",
|
||||
"chapel": "res://scenes/chapel.tscn",
|
||||
"cloister": "res://scenes/cloister.tscn",
|
||||
"sanctum": "res://scenes/sanctum.tscn",
|
||||
}
|
||||
|
||||
var pending_room_index: int = 0
|
||||
var _current_scene_node: Node = null
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
NetworkManager.game_started.connect(_on_game_started)
|
||||
# Defer until main.tscn and its CurrentScene node are in the tree.
|
||||
# call_deferred is not sufficient here — autoloads init before the main
|
||||
# scene. Connect to root.ready (fires once, after main scene is ready).
|
||||
get_tree().root.ready.connect(_on_root_ready, CONNECT_ONE_SHOT)
|
||||
|
||||
|
||||
@@ -26,7 +25,7 @@ func _on_root_ready() -> void:
|
||||
var args := OS.get_cmdline_args() + OS.get_cmdline_user_args()
|
||||
var is_server := OS.has_feature("dedicated_server") or "--server" in args
|
||||
if not is_server:
|
||||
transition_to("tavern")
|
||||
transition_to("lobby")
|
||||
|
||||
|
||||
func transition_to(scene_name: String) -> void:
|
||||
@@ -51,13 +50,8 @@ func _on_game_started() -> void:
|
||||
var args := OS.get_cmdline_args() + OS.get_cmdline_user_args()
|
||||
if OS.has_feature("dedicated_server") or "--server" in args:
|
||||
return
|
||||
# TODO next feature: call _load_for_role("chamber") here once role routing is implemented
|
||||
print("[SceneManager] Spiel gestartet — chamber transition kommt im nächsten Feature")
|
||||
|
||||
|
||||
func _load_for_role(scene_name: String) -> void:
|
||||
# my_id is only valid after NetworkManager._on_connected_to_server fires.
|
||||
# Do not call before game_started — my_id will be 0 before that.
|
||||
var role: String = NetworkManager.players.get(NetworkManager.my_id, {}).get("role", "player")
|
||||
# TODO next feature: load dm variant when role == "dm"
|
||||
print("[SceneManager] Role %s → %s (stub, not switching yet)" % [role, scene_name])
|
||||
if role == "dm":
|
||||
transition_to("dm_view")
|
||||
else:
|
||||
transition_to("tavern")
|
||||
|
||||
@@ -1,68 +1,29 @@
|
||||
extends Node3D
|
||||
|
||||
var _local_role: String = ""
|
||||
var _pending_player_name: String = ""
|
||||
const ROOM_COUNT := 8
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$CanvasLayer/JoinPanel/RoleOption.add_item("Spieler")
|
||||
$CanvasLayer/JoinPanel/RoleOption.add_item("DM")
|
||||
|
||||
$CanvasLayer/JoinPanel/JoinButton.pressed.connect(_on_join_pressed)
|
||||
$CanvasLayer/WaitPanel/StartButton.pressed.connect(_on_start_pressed)
|
||||
|
||||
NetworkManager.connected_to_server.connect(_on_connected)
|
||||
NetworkManager.connection_failed.connect(_on_connection_failed)
|
||||
NetworkManager.player_joined.connect(_on_player_joined)
|
||||
NetworkManager.player_left.connect(_on_player_left)
|
||||
NetworkManager.player_list_synced.connect(_rebuild_player_list)
|
||||
|
||||
|
||||
func _on_join_pressed() -> void:
|
||||
var player_name: String = ($CanvasLayer/JoinPanel/NameInput as LineEdit).text.strip_edges()
|
||||
if player_name.is_empty():
|
||||
var args := OS.get_cmdline_args() + OS.get_cmdline_user_args()
|
||||
if OS.has_feature("dedicated_server") or "--server" in args:
|
||||
return
|
||||
_local_role = "dm" if $CanvasLayer/JoinPanel/RoleOption.selected == 1 else "player"
|
||||
_pending_player_name = player_name
|
||||
NetworkManager.join_server("127.0.0.1", 4242)
|
||||
var room_index := SceneManager.pending_room_index
|
||||
_spawn_player(room_index)
|
||||
|
||||
|
||||
func _on_connected() -> void:
|
||||
NetworkManager.register.rpc_id(1, _pending_player_name, _local_role)
|
||||
$CanvasLayer/JoinPanel.visible = false
|
||||
$CanvasLayer/WaitPanel.visible = true
|
||||
$CanvasLayer/WaitPanel/StartButton.visible = (_local_role == "dm")
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
NetworkManager.connected_to_server.disconnect(_on_connected)
|
||||
NetworkManager.connection_failed.disconnect(_on_connection_failed)
|
||||
NetworkManager.player_joined.disconnect(_on_player_joined)
|
||||
NetworkManager.player_left.disconnect(_on_player_left)
|
||||
NetworkManager.player_list_synced.disconnect(_rebuild_player_list)
|
||||
|
||||
|
||||
func _on_connection_failed() -> void:
|
||||
push_error("[Tavern] Verbindung fehlgeschlagen")
|
||||
_local_role = ""
|
||||
_pending_player_name = ""
|
||||
$CanvasLayer/JoinPanel.visible = true
|
||||
$CanvasLayer/WaitPanel.visible = false
|
||||
|
||||
|
||||
func _on_player_joined(_peer_id: int, _player_name: String, _role: String) -> void:
|
||||
_rebuild_player_list()
|
||||
|
||||
|
||||
func _on_player_left(_peer_id: int) -> void:
|
||||
_rebuild_player_list()
|
||||
|
||||
|
||||
func _rebuild_player_list() -> void:
|
||||
$CanvasLayer/WaitPanel/PlayerList.clear()
|
||||
for p in NetworkManager.players.values():
|
||||
$CanvasLayer/WaitPanel/PlayerList.add_item("%s (%s)" % [p.name, p.role])
|
||||
|
||||
|
||||
func _on_start_pressed() -> void:
|
||||
NetworkManager.request_start_game.rpc_id(1)
|
||||
func _spawn_player(room_index: int) -> void:
|
||||
var room_num := (room_index % ROOM_COUNT) + 1 # Zimmer heißen Room1..Room8
|
||||
var spawn_path := "UpperFloor/Room%d/SpawnPoint" % room_num
|
||||
var spawn := get_node_or_null(spawn_path) as Marker3D
|
||||
if spawn == null:
|
||||
push_error("[Tavern] SpawnPoint nicht gefunden: %s" % spawn_path)
|
||||
return
|
||||
var controller := Node3D.new()
|
||||
controller.name = "PlayerController"
|
||||
var camera := Camera3D.new()
|
||||
camera.name = "Camera3D"
|
||||
camera.current = true
|
||||
controller.add_child(camera)
|
||||
add_child(controller)
|
||||
controller.global_transform = spawn.global_transform
|
||||
print("[Tavern] Spieler gespawnt in %s" % spawn_path)
|
||||
|
||||
68
ruf-der-pilze/scripts/tavern_lobby.gd
Normal file
68
ruf-der-pilze/scripts/tavern_lobby.gd
Normal file
@@ -0,0 +1,68 @@
|
||||
extends Node3D
|
||||
|
||||
var _local_role: String = ""
|
||||
var _pending_player_name: String = ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
$CanvasLayer/JoinPanel/RoleOption.add_item("Spieler")
|
||||
$CanvasLayer/JoinPanel/RoleOption.add_item("DM")
|
||||
|
||||
$CanvasLayer/JoinPanel/JoinButton.pressed.connect(_on_join_pressed)
|
||||
$CanvasLayer/WaitPanel/StartButton.pressed.connect(_on_start_pressed)
|
||||
|
||||
NetworkManager.connected_to_server.connect(_on_connected)
|
||||
NetworkManager.connection_failed.connect(_on_connection_failed)
|
||||
NetworkManager.player_joined.connect(_on_player_joined)
|
||||
NetworkManager.player_left.connect(_on_player_left)
|
||||
NetworkManager.player_list_synced.connect(_rebuild_player_list)
|
||||
|
||||
|
||||
func _on_join_pressed() -> void:
|
||||
var player_name: String = ($CanvasLayer/JoinPanel/NameInput as LineEdit).text.strip_edges()
|
||||
if player_name.is_empty():
|
||||
return
|
||||
_local_role = "dm" if $CanvasLayer/JoinPanel/RoleOption.selected == 1 else "player"
|
||||
_pending_player_name = player_name
|
||||
NetworkManager.join_server("127.0.0.1", 4242)
|
||||
|
||||
|
||||
func _on_connected() -> void:
|
||||
NetworkManager.register.rpc_id(1, _pending_player_name, _local_role)
|
||||
$CanvasLayer/JoinPanel.visible = false
|
||||
$CanvasLayer/WaitPanel.visible = true
|
||||
$CanvasLayer/WaitPanel/StartButton.visible = (_local_role == "dm")
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
NetworkManager.connected_to_server.disconnect(_on_connected)
|
||||
NetworkManager.connection_failed.disconnect(_on_connection_failed)
|
||||
NetworkManager.player_joined.disconnect(_on_player_joined)
|
||||
NetworkManager.player_left.disconnect(_on_player_left)
|
||||
NetworkManager.player_list_synced.disconnect(_rebuild_player_list)
|
||||
|
||||
|
||||
func _on_connection_failed() -> void:
|
||||
push_error("[Tavern] Verbindung fehlgeschlagen")
|
||||
_local_role = ""
|
||||
_pending_player_name = ""
|
||||
$CanvasLayer/JoinPanel.visible = true
|
||||
$CanvasLayer/WaitPanel.visible = false
|
||||
|
||||
|
||||
func _on_player_joined(_peer_id: int, _player_name: String, _role: String) -> void:
|
||||
_rebuild_player_list()
|
||||
|
||||
|
||||
func _on_player_left(_peer_id: int) -> void:
|
||||
_rebuild_player_list()
|
||||
|
||||
|
||||
func _rebuild_player_list() -> void:
|
||||
$CanvasLayer/WaitPanel/PlayerList.clear()
|
||||
for p in NetworkManager.players.values():
|
||||
$CanvasLayer/WaitPanel/PlayerList.add_item("%s (%s)" % [p.name, p.role])
|
||||
|
||||
|
||||
func _on_start_pressed() -> void:
|
||||
NetworkManager.request_start_game.rpc_id(1)
|
||||
Reference in New Issue
Block a user