diff --git a/splunk/game-logic/game_manager.gd b/splunk/game-logic/game_manager.gd new file mode 100644 index 0000000..d0c41ba --- /dev/null +++ b/splunk/game-logic/game_manager.gd @@ -0,0 +1,31 @@ +extends Node + +var players: Array[int] = [] + +var player_spawner: MultiplayerSpawner + +@onready var debug_ui: PackedScene = preload("res://ui/multiplayer-debug-ui/multiplayer-debug-ui.tscn") +var debug_ui_instance + + +func _ready() -> void: + player_spawner = get_tree().root.get_node("Lobby/PlayerSpawner") as MultiplayerSpawner + + debug_ui_instance = debug_ui.instantiate() + get_tree().root.add_child.call_deferred(debug_ui_instance) + debug_ui_instance.hide() + + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("toggle_watch"): + debug_ui_instance.visible = !debug_ui_instance.visible + + +@rpc("any_peer", "call_local", "reliable") +func request_server_to_spawn_player(peer_id: int, player_name: String) -> void: + var data: Dictionary = {} + + data["peer_id"] = peer_id + data["player_name"] = player_name + + player_spawner.spawn(data) diff --git a/splunk/game-logic/game_manager.gd.uid b/splunk/game-logic/game_manager.gd.uid new file mode 100644 index 0000000..d0614ef --- /dev/null +++ b/splunk/game-logic/game_manager.gd.uid @@ -0,0 +1 @@ +uid://dsl58fvqxa6ul diff --git a/splunk/levels/lobby-scene/lobby-terrain.blend b/splunk/levels/lobby-scene/lobby-terrain.blend deleted file mode 100644 index f1dd138..0000000 Binary files a/splunk/levels/lobby-scene/lobby-terrain.blend and /dev/null differ diff --git a/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend new file mode 100644 index 0000000..3c429e9 Binary files /dev/null and b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend differ diff --git a/splunk/levels/lobby-scene/lobby-terrain.blend.import b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend.import similarity index 84% rename from splunk/levels/lobby-scene/lobby-terrain.blend.import rename to splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend.import index ee1fb85..1b4f740 100644 --- a/splunk/levels/lobby-scene/lobby-terrain.blend.import +++ b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend.import @@ -4,12 +4,12 @@ importer="scene" importer_version=1 type="PackedScene" uid="uid://b5xb0fsfpn7r3" -path="res://.godot/imported/lobby-terrain.blend-1020d7f6f6a9a581e1b1682b5ac8d125.scn" +path="res://.godot/imported/lobby-terrain.blend-a6c0be77548df4815861d8f088c594f5.scn" [deps] -source_file="res://levels/lobby-scene/lobby-terrain.blend" -dest_files=["res://.godot/imported/lobby-terrain.blend-1020d7f6f6a9a581e1b1682b5ac8d125.scn"] +source_file="res://levels/lobby-scene/lobby-terrain/lobby-terrain.blend" +dest_files=["res://.godot/imported/lobby-terrain.blend-a6c0be77548df4815861d8f088c594f5.scn"] [params] diff --git a/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend1 b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend1 new file mode 100644 index 0000000..344b3b7 Binary files /dev/null and b/splunk/levels/lobby-scene/lobby-terrain/lobby-terrain.blend1 differ diff --git a/splunk/levels/lobby-scene/lobby-terrain/textures/grass.png b/splunk/levels/lobby-scene/lobby-terrain/textures/grass.png new file mode 100644 index 0000000..b19e4a9 Binary files /dev/null and b/splunk/levels/lobby-scene/lobby-terrain/textures/grass.png differ diff --git a/splunk/levels/lobby-scene/textures/line.png.import b/splunk/levels/lobby-scene/lobby-terrain/textures/grass.png.import similarity index 66% rename from splunk/levels/lobby-scene/textures/line.png.import rename to splunk/levels/lobby-scene/lobby-terrain/textures/grass.png.import index cf999a4..9aedb1f 100644 --- a/splunk/levels/lobby-scene/textures/line.png.import +++ b/splunk/levels/lobby-scene/lobby-terrain/textures/grass.png.import @@ -2,18 +2,17 @@ importer="texture" type="CompressedTexture2D" -uid="uid://httteb3u35qr" -path.s3tc="res://.godot/imported/line.png-1b1fccbe8a0fdb9beb81829cbd429a35.s3tc.ctex" +uid="uid://dpkeaqjnr3bsb" +path.s3tc="res://.godot/imported/grass.png-72267d35d6d4105c20ad91641e676c75.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true } -generator_parameters={} [deps] -source_file="res://levels/lobby-scene/textures/line.png" -dest_files=["res://.godot/imported/line.png-1b1fccbe8a0fdb9beb81829cbd429a35.s3tc.ctex"] +source_file="res://levels/lobby-scene/lobby-terrain/textures/grass.png" +dest_files=["res://.godot/imported/grass.png-72267d35d6d4105c20ad91641e676c75.s3tc.ctex"] [params] diff --git a/splunk/levels/lobby-scene/lobby.tscn b/splunk/levels/lobby-scene/lobby.tscn index 118c94b..78e2fcb 100644 --- a/splunk/levels/lobby-scene/lobby.tscn +++ b/splunk/levels/lobby-scene/lobby.tscn @@ -1,8 +1,9 @@ -[gd_scene load_steps=9 format=3 uid="uid://bj52j4ew2lfr6"] +[gd_scene load_steps=10 format=3 uid="uid://bj52j4ew2lfr6"] [ext_resource type="PackedScene" uid="uid://5vggmy1srgxb" path="res://tools/human-height-reference.tscn" id="1_yyu2g"] -[ext_resource type="PackedScene" uid="uid://b5xb0fsfpn7r3" path="res://levels/lobby-scene/lobby-terrain.blend" id="3_f73ky"] -[ext_resource type="PackedScene" uid="uid://csmfxg011xisf" path="res://player/Player.tscn" id="4_0aw1h"] +[ext_resource type="PackedScene" uid="uid://bhgahenvxqhec" path="res://levels/lobby-scene/tree/tree.blend" id="3_0u2wx"] +[ext_resource type="PackedScene" uid="uid://b5xb0fsfpn7r3" path="res://levels/lobby-scene/lobby-terrain/lobby-terrain.blend" id="3_f73ky"] +[ext_resource type="Script" uid="uid://bbhx0fwgcgjr4" path="res://networking/player_spawner.gd" id="3_qjimh"] [ext_resource type="PackedScene" uid="uid://c4cew4af3h306" path="res://levels/lobby-scene/tent/tent.blend" id="4_qjimh"] [ext_resource type="PackedScene" uid="uid://wcsd1tb0quj3" path="res://levels/lobby-scene/campfire/campfire.tscn" id="5_qjimh"] @@ -36,38 +37,47 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.33741, 0.953, -5.00694) [node name="lobby-terrain" parent="." instance=ExtResource("3_f73ky")] -[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="."] +[node name="Node3D" type="Node3D" parent="lobby-terrain"] + +[node name="tree" parent="lobby-terrain/Node3D" instance=ExtResource("3_0u2wx")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.47232, 0, -12.0981) + +[node name="Node3D" type="Node3D" parent="lobby-terrain"] + +[node name="tree" parent="lobby-terrain/Node3D" instance=ExtResource("3_0u2wx")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.47232, 0, -12.0981) + +[node name="PlayerSpawner" type="MultiplayerSpawner" parent="."] + _spawnable_scenes = PackedStringArray("uid://csmfxg011xisf") spawn_path = NodePath("../Marker3D") -spawn_limit = 1 +script = ExtResource("3_qjimh") [node name="Marker3D" type="Marker3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.269072, -8.35164) -[node name="Player" parent="." instance=ExtResource("4_0aw1h")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.444747, 0.992996, -4.71496) - [node name="Campsite" type="Node3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -15.724, 0, -17.6721) [node name="TentPlot1" type="Marker3D" parent="Campsite"] -transform = Transform3D(-0.998887, 0, -0.0471587, 0, 1, 0, 0.0471587, 0, -0.998887, -0.468871, 0, -6.31805) +transform = Transform3D(-0.998887, 0, -0.0471587, 0, 1, 0, 0.0471587, 0, -0.998887, -0.468871, 0.334599, -6.31805) [node name="tent" parent="Campsite/TentPlot1" instance=ExtResource("4_qjimh")] [node name="TentPlot2" type="Marker3D" parent="Campsite"] -transform = Transform3D(-0.240973, 0, -0.970532, 0, 1, 0, 0.970532, 0, -0.240973, -6.46887, 0, -2.31805) +transform = Transform3D(-0.240973, 0, -0.970532, 0, 1, 0, 0.970532, 0, -0.240973, -6.46887, 0.334599, -2.31805) [node name="tent" parent="Campsite/TentPlot2" instance=ExtResource("4_qjimh")] [node name="TentPlot3" type="Marker3D" parent="Campsite"] -transform = Transform3D(0.689594, 0, -0.724196, 0, 1, 0, 0.724196, 0, 0.689594, -4.46887, 0, 4.68195) +transform = Transform3D(0.689594, 0, -0.724196, 0, 1, 0, 0.724196, 0, 0.689594, -4.46887, 0.334599, 4.68195) [node name="tent" parent="Campsite/TentPlot3" instance=ExtResource("4_qjimh")] [node name="TentPlot4" type="Marker3D" parent="Campsite"] -transform = Transform3D(-0.0217975, 0, 0.999762, 0, 1, 0, -0.999762, 0, -0.0217975, 6.53113, 0, -2.31805) +transform = Transform3D(-0.0217975, 0, 0.999762, 0, 1, 0, -0.999762, 0, -0.0217975, 6.53113, 0.334599, -2.31805) [node name="tent" parent="Campsite/TentPlot4" instance=ExtResource("4_qjimh")] [node name="Campfire" parent="Campsite" instance=ExtResource("5_qjimh")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.392361, 0) diff --git a/splunk/levels/lobby-scene/tent/tent.blend b/splunk/levels/lobby-scene/tent/tent.blend index f57dda2..bacea3e 100644 Binary files a/splunk/levels/lobby-scene/tent/tent.blend and b/splunk/levels/lobby-scene/tent/tent.blend differ diff --git a/splunk/levels/lobby-scene/tent/tent.blend1 b/splunk/levels/lobby-scene/tent/tent.blend1 new file mode 100644 index 0000000..e0173fb Binary files /dev/null and b/splunk/levels/lobby-scene/tent/tent.blend1 differ diff --git a/splunk/levels/lobby-scene/textures/line.png b/splunk/levels/lobby-scene/textures/line.png deleted file mode 100644 index e02ff7b..0000000 Binary files a/splunk/levels/lobby-scene/textures/line.png and /dev/null differ diff --git a/splunk/levels/lobby-scene/textures/pins.png b/splunk/levels/lobby-scene/textures/pins.png deleted file mode 100644 index f0c9a05..0000000 Binary files a/splunk/levels/lobby-scene/textures/pins.png and /dev/null differ diff --git a/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg b/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg deleted file mode 100644 index e39dab1..0000000 Binary files a/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg and /dev/null differ diff --git a/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg.import b/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg.import deleted file mode 100644 index 5e50691..0000000 --- a/splunk/levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg.import +++ /dev/null @@ -1,35 +0,0 @@ -[remap] - -importer="texture" -type="CompressedTexture2D" -uid="uid://dxeibfk11lodj" -path.s3tc="res://.godot/imported/rocky_terrain_02_diff_1k.jpg-a0faf17242828e040608373f3cdaba10.s3tc.ctex" -metadata={ -"imported_formats": ["s3tc_bptc"], -"vram_texture": true -} - -[deps] - -source_file="res://levels/lobby-scene/textures/rocky_terrain_02_diff_1k.jpg" -dest_files=["res://.godot/imported/rocky_terrain_02_diff_1k.jpg-a0faf17242828e040608373f3cdaba10.s3tc.ctex"] - -[params] - -compress/mode=2 -compress/high_quality=false -compress/lossy_quality=0.7 -compress/hdr_compression=1 -compress/normal_map=0 -compress/channel_pack=0 -mipmaps/generate=true -mipmaps/limit=-1 -roughness/mode=0 -roughness/src_normal="" -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=0 diff --git a/splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png b/splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png deleted file mode 100644 index 46b56ab..0000000 Binary files a/splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png and /dev/null differ diff --git a/splunk/levels/lobby-scene/textures/tent-canvas.png b/splunk/levels/lobby-scene/textures/tent-canvas.png deleted file mode 100644 index ec85dfc..0000000 Binary files a/splunk/levels/lobby-scene/textures/tent-canvas.png and /dev/null differ diff --git a/splunk/levels/lobby-scene/tree/textures/leaves.png b/splunk/levels/lobby-scene/tree/textures/leaves.png new file mode 100644 index 0000000..bf983a1 Binary files /dev/null and b/splunk/levels/lobby-scene/tree/textures/leaves.png differ diff --git a/splunk/levels/lobby-scene/textures/pins.png.import b/splunk/levels/lobby-scene/tree/textures/leaves.png.import similarity index 66% rename from splunk/levels/lobby-scene/textures/pins.png.import rename to splunk/levels/lobby-scene/tree/textures/leaves.png.import index b005364..9e3d3ed 100644 --- a/splunk/levels/lobby-scene/textures/pins.png.import +++ b/splunk/levels/lobby-scene/tree/textures/leaves.png.import @@ -2,18 +2,17 @@ importer="texture" type="CompressedTexture2D" -uid="uid://dd8afqm2eo5tb" -path.s3tc="res://.godot/imported/pins.png-9e7d62b7100f3992201f360fd11b8753.s3tc.ctex" +uid="uid://bd53ybrlho0d1" +path.s3tc="res://.godot/imported/leaves.png-530373898a77b84d2e3909cbed29021f.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true } -generator_parameters={} [deps] -source_file="res://levels/lobby-scene/textures/pins.png" -dest_files=["res://.godot/imported/pins.png-9e7d62b7100f3992201f360fd11b8753.s3tc.ctex"] +source_file="res://levels/lobby-scene/tree/textures/leaves.png" +dest_files=["res://.godot/imported/leaves.png-530373898a77b84d2e3909cbed29021f.s3tc.ctex"] [params] diff --git a/splunk/levels/lobby-scene/tree/textures/trunk.png b/splunk/levels/lobby-scene/tree/textures/trunk.png new file mode 100644 index 0000000..50f2243 Binary files /dev/null and b/splunk/levels/lobby-scene/tree/textures/trunk.png differ diff --git a/splunk/levels/lobby-scene/textures/tent-canvas.png.import b/splunk/levels/lobby-scene/tree/textures/trunk.png.import similarity index 65% rename from splunk/levels/lobby-scene/textures/tent-canvas.png.import rename to splunk/levels/lobby-scene/tree/textures/trunk.png.import index 0966c96..d101762 100644 --- a/splunk/levels/lobby-scene/textures/tent-canvas.png.import +++ b/splunk/levels/lobby-scene/tree/textures/trunk.png.import @@ -2,18 +2,17 @@ importer="texture" type="CompressedTexture2D" -uid="uid://oemi5vymwrij" -path.s3tc="res://.godot/imported/tent-canvas.png-eb337bb8ec4691a22e92d3af49a9828d.s3tc.ctex" +uid="uid://cxuxtdscvpcru" +path.s3tc="res://.godot/imported/trunk.png-4d6cd7f252205478b8e4bf2b892c9b44.s3tc.ctex" metadata={ "imported_formats": ["s3tc_bptc"], "vram_texture": true } -generator_parameters={} [deps] -source_file="res://levels/lobby-scene/textures/tent-canvas.png" -dest_files=["res://.godot/imported/tent-canvas.png-eb337bb8ec4691a22e92d3af49a9828d.s3tc.ctex"] +source_file="res://levels/lobby-scene/tree/textures/trunk.png" +dest_files=["res://.godot/imported/trunk.png-4d6cd7f252205478b8e4bf2b892c9b44.s3tc.ctex"] [params] diff --git a/splunk/levels/lobby-scene/tree/tree.blend b/splunk/levels/lobby-scene/tree/tree.blend new file mode 100644 index 0000000..6029d19 Binary files /dev/null and b/splunk/levels/lobby-scene/tree/tree.blend differ diff --git a/splunk/levels/lobby-scene/tree/tree.blend.import b/splunk/levels/lobby-scene/tree/tree.blend.import new file mode 100644 index 0000000..6c81377 --- /dev/null +++ b/splunk/levels/lobby-scene/tree/tree.blend.import @@ -0,0 +1,53 @@ +[remap] + +importer="scene" +importer_version=1 +type="PackedScene" +uid="uid://bhgahenvxqhec" +path="res://.godot/imported/tree.blend-2e97b0c94b4b9f627dfe10b7f953c7fe.scn" + +[deps] + +source_file="res://levels/lobby-scene/tree/tree.blend" +dest_files=["res://.godot/imported/tree.blend-2e97b0c94b4b9f627dfe10b7f953c7fe.scn"] + +[params] + +nodes/root_type="" +nodes/root_name="" +nodes/apply_root_scale=true +nodes/root_scale=1.0 +nodes/import_as_skeleton_bones=false +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="" +_subresources={} +blender/nodes/visible=0 +blender/nodes/active_collection_only=false +blender/nodes/punctual_lights=true +blender/nodes/cameras=true +blender/nodes/custom_properties=true +blender/nodes/modifiers=1 +blender/meshes/colors=false +blender/meshes/uvs=true +blender/meshes/normals=true +blender/meshes/export_geometry_nodes_instances=false +blender/meshes/tangents=true +blender/meshes/skins=2 +blender/meshes/export_bones_deforming_mesh_only=false +blender/materials/unpack_enabled=true +blender/materials/export_materials=1 +blender/animation/limit_playback=true +blender/animation/always_sample=true +blender/animation/group_tracks=true diff --git a/splunk/levels/lobby-scene/tree/tree.blend1 b/splunk/levels/lobby-scene/tree/tree.blend1 new file mode 100644 index 0000000..1cdac8b Binary files /dev/null and b/splunk/levels/lobby-scene/tree/tree.blend1 differ diff --git a/splunk/levels/lobby-scene/tree/trunk.png b/splunk/levels/lobby-scene/tree/trunk.png new file mode 100644 index 0000000..831c7ba Binary files /dev/null and b/splunk/levels/lobby-scene/tree/trunk.png differ diff --git a/splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png.import b/splunk/levels/lobby-scene/tree/trunk.png.import similarity index 63% rename from splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png.import rename to splunk/levels/lobby-scene/tree/trunk.png.import index 2ef703c..1be0ecb 100644 --- a/splunk/levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png.import +++ b/splunk/levels/lobby-scene/tree/trunk.png.import @@ -2,16 +2,16 @@ importer="texture" type="CompressedTexture2D" -uid="uid://c31rlthxjvvbp" -path="res://.godot/imported/rocky_terrain_02_spec_1k.png-79c9d42463680422048e46f05a653dfb.ctex" +uid="uid://chrva3l6shfhg" +path="res://.godot/imported/trunk.png-b162fd3ffcc29a857809c16bdc1c00bb.ctex" metadata={ "vram_texture": false } [deps] -source_file="res://levels/lobby-scene/textures/rocky_terrain_02_spec_1k.png" -dest_files=["res://.godot/imported/rocky_terrain_02_spec_1k.png-79c9d42463680422048e46f05a653dfb.ctex"] +source_file="res://levels/lobby-scene/tree/trunk.png" +dest_files=["res://.godot/imported/trunk.png-b162fd3ffcc29a857809c16bdc1c00bb.ctex"] [params] diff --git a/splunk/networking/player_spawner.gd b/splunk/networking/player_spawner.gd new file mode 100644 index 0000000..be96167 --- /dev/null +++ b/splunk/networking/player_spawner.gd @@ -0,0 +1,43 @@ +extends MultiplayerSpawner + +@onready var player_scene: PackedScene = load("res://player/Player.tscn") + + +func _ready() -> void: + spawn_function = spawn_player + + +func spawn_player(data: Dictionary) -> Player: + var new_player = player_scene.instantiate() as Player + + var peer_id = str(data["peer_id"]) + var player_name = str(data["player_name"]) + + new_player.set_multiplayer_authority(int(peer_id), true) + new_player.set_player_name(peer_id, player_name) + new_player.position = Vector3.UP + + GameManager.players.append(int(peer_id)) + + return new_player + + + #var steam_id_of_player = peer_to_steam_id_map.get(peer_id) + #if steam_id_of_player == null: + #print("!!! [%s] CRITICAL: Cannot spawn player for Peer %s, not in map." % [multiplayer.get_unique_id(), peer_id]) + #return + # + #if players.has(peer_id): return +# + #var player_name = Steam.getFriendPersonaName(steam_id_of_player) + #print("-> [%s] Spawning character for Peer %s (Name: %s)." % [multiplayer.get_unique_id(), peer_id, player_name]) + # + #var new_player = player_scene.instantiate() as Player + #new_player.name = str(peer_id) + # + #players[peer_id] = new_player + #add_child(new_player) + #new_player.position = Vector3.UP + #new_player.set_player_name(player_name) + #new_player.set_multiplayer_authority(peer_id, true) + #new_player.setup_player() diff --git a/splunk/networking/player_spawner.gd.uid b/splunk/networking/player_spawner.gd.uid new file mode 100644 index 0000000..b495f1f --- /dev/null +++ b/splunk/networking/player_spawner.gd.uid @@ -0,0 +1 @@ +uid://bbhx0fwgcgjr4 diff --git a/splunk/networking/steam-manager.gd b/splunk/networking/steam-manager.gd index 9118773..cd5c990 100644 --- a/splunk/networking/steam-manager.gd +++ b/splunk/networking/steam-manager.gd @@ -1,15 +1,14 @@ extends Node -var is_owned: bool = false -var steam_app_id: int = 480 +@onready var player_scene: PackedScene = preload("res://player/Player.tscn") + +var players: Array[int] = [] + var steam_id: int = 0 var steam_username: String = "" - -var lobby_id = 0 -var lobby_max_members = 4 -var lobby_members: Array = [] - +var lobby_id: int = 0 var steam_initialized: bool = false +var steam_app_id: int = 480 var peer: SteamMultiplayerPeer @@ -23,274 +22,148 @@ func _ready() -> void: print("!!! Steam did not initialize. Multiplayer will be disabled.") return - # Connect Steam lobby signals Steam.lobby_created.connect(_on_lobby_created) Steam.lobby_joined.connect(_on_lobby_joined) - #Steam.lobby_match_list.connect(_on_lobby_match_list) Steam.lobby_chat_update.connect(_on_lobby_chat_update) - Steam.lobby_data_update.connect(_on_lobby_data_update) - #Steam.join_requested.connect(_on_lobby_join_requested) - Steam.persona_state_change.connect(_on_persona_change) + Steam.p2p_session_request.connect(_on_p2p_session_request) - # Setup multiplayer signals multiplayer.peer_connected.connect(_on_peer_connected) multiplayer.peer_disconnected.connect(_on_peer_disconnected) multiplayer.connected_to_server.connect(_on_connected_to_server) multiplayer.connection_failed.connect(_on_connection_failed) - multiplayer.server_disconnected.connect(_on_server_disconnected) - Steam.p2p_session_request.connect(_on_p2p_session_request) check_command_line() - - -func _on_p2p_session_request(steam_id_remote: int) -> void: - ## ADDED: More detailed logging to confirm P2P acceptance. - print("[P2P] ==> Session request from: %s. Accepting." % steam_id_remote) - var accepted = Steam.acceptP2PSessionWithUser(steam_id_remote) - if not accepted: - print("[P2P] !!! Failed to accept P2P session with %s." % steam_id_remote) + + multiplayer.server_relay = true + func _process(delta): - ## ADDED: Guard clause in case Steam fails to initialize. if not steam_initialized: return - Steam.run_callbacks() + + +func create_lobby(): + print("[HOST] 1. Attempting to create lobby...") + Steam.createLobby(Steam.LOBBY_TYPE_FRIENDS_ONLY, 4) + + +func _on_lobby_created(connect: int, this_lobby_id: int): + if connect != 1: + print("[HOST] !!! Lobby creation failed.") + return + + lobby_id = this_lobby_id + print("[HOST] 2. Lobby created successfully (ID: %s)." % lobby_id) - if Input.is_action_just_pressed("interact"): - ## ADDED: Replaced simple print with a detailed diagnostic function. - log_multiplayer_info() + Steam.setLobbyJoinable(lobby_id, true) + Steam.setLobbyData(lobby_id, "name", steam_username + "'s Lobby") + + setup_multiplayer_peer(true) + print("[HOST] 3. Multiplayer host started (My Peer ID is always 1).") + + #players.append(peer.get) + GameManager.request_server_to_spawn_player.rpc_id(1, 1, steam_username) -func check_command_line() -> void: - var args: Array = OS.get_cmdline_args() - if args.size() > 0: - if args[0] == "+connect_lobby": - if args.size() > 1 and int(args[1]) > 0: - print("Command line lobby ID: %s" % args[1]) - join_lobby(int(args[1])) +func join_lobby(this_lobby_id: int): + print("[CLIENT] 1. Attempting to join lobby (ID: %s)..." % this_lobby_id) + Steam.joinLobby(this_lobby_id) + + +func _on_lobby_joined(this_lobby_id: int, _p, _l, response: int): + if response != Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS: + print("[CLIENT] !!! Failed to join lobby: %s" % get_join_fail_reason(response)) + return + + lobby_id = this_lobby_id + print("[CLIENT] 2. Successfully joined Steam lobby.") + + if Steam.getLobbyOwner(lobby_id) != steam_id: + print("[CLIENT] 3. I am a client, creating multiplayer peer to connect to host.") + setup_multiplayer_peer(false) + + +func _on_connected_to_server(): + print("[CLIENT] 4. Successfully connected to host's multiplayer peer.") + print("[CLIENT] 5. Sending my info to the server for registration...") + GameManager.request_server_to_spawn_player.rpc_id(1, multiplayer.get_unique_id(), steam_username) + + +func _on_p2p_session_request(steam_id_remote: int) -> void: + print("[P2P] ==> Session request from: %s. Accepting." % steam_id_remote) + Steam.acceptP2PSessionWithUser(steam_id_remote) func init_steam() -> bool: var response: Dictionary = Steam.steamInitEx() - print("Steam init response: %s " % response) - if response['status'] > 0: print("!!! Failed to init steam! Code: %s " % response) return false - - is_owned = Steam.isSubscribed() steam_id = Steam.getSteamID() steam_username = Steam.getPersonaName() - print("Steam initialized successfully for %s (ID: %s)." % [steam_username, steam_id]) - - if !is_owned: - print("!!! WARNING: Steam reports you do not own App ID %s." % steam_app_id) - # You might want to return false here in a real game - # return false - return true func setup_multiplayer_peer(is_host: bool = false) -> void: - ## ADDED: Check if a peer is already active before creating a new one. if multiplayer.multiplayer_peer and multiplayer.multiplayer_peer.get_connection_status() != MultiplayerPeer.CONNECTION_DISCONNECTED: - print("[Multiplayer] Peer already exists. Disconnecting old one.") multiplayer.multiplayer_peer.close() peer = SteamMultiplayerPeer.new() if is_host: - print("[Multiplayer] Creating Host...") - var err = peer.create_host(0) ## REMOVED: Channel is handled by the peer automatically now. - if err != OK: - print("[Multiplayer] !!! Failed to create host. Error: %s" % err) - return - - multiplayer.multiplayer_peer = peer - print("[Multiplayer] Host created successfully. My Peer ID: %s" % multiplayer.get_unique_id()) + peer.create_host(0) else: - if lobby_id == 0: - print("[Multiplayer] !!! Cannot create client, not in a lobby.") - return - var host_id = Steam.getLobbyOwner(lobby_id) - print("[Multiplayer] Creating Client, attempting to connect to host: %s" % host_id) - var err = peer.create_client(host_id, 0) ## REMOVED: Channel is handled by the peer automatically. - if err != OK: - print("[Multiplayer] !!! Failed to create client. Error: %s" % err) - return - - multiplayer.multiplayer_peer = peer - print("[Multiplayer] Client peer created. Waiting for connection...") + peer.create_client(host_id, 0) + + multiplayer.multiplayer_peer = peer -func create_lobby(): - if lobby_id == 0: - print("Creating lobby...") - Steam.createLobby(Steam.LOBBY_TYPE_FRIENDS_ONLY, lobby_max_members) +func _on_peer_connected(id: int): + print("[INFO] Peer %s has established a multiplayer session." % id) + #players.append() + +func _on_peer_disconnected(id: int): + print("[INFO] Peer %s has disconnected." % id) + if players.has(id): + #players[id].queue_free() + players.erase(id) -func _on_lobby_created(connect: int, this_lobby_id: int): - if connect == 1: - lobby_id = this_lobby_id - print("Lobby created with id `%s`" % lobby_id) - - Steam.setLobbyJoinable(lobby_id, true) - Steam.setLobbyData(lobby_id, "name", steam_username + "'s Lobby") - Steam.setLobbyData(lobby_id, "mode", "Splunk") - - Steam.allowP2PPacketRelay(true) - setup_multiplayer_peer(true) # Setup as host - else : - print("!!! Failed to create lobby.") +func _on_connection_failed() -> void: + print("[CLIENT] !!! Connection to the host failed.") -func join_lobby(this_lobby_id: int): - print("Attempting to join lobby: %s" % this_lobby_id) - lobby_members.clear() - Steam.joinLobby(this_lobby_id) - - -func _on_lobby_joined(this_lobby_id: int, permissions: int, locked: bool, response: int): - if response == Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS: - lobby_id = this_lobby_id - print("Successfully joined lobby: %s" % lobby_id) - get_lobby_members() - - # FIXED: Use Steam.getLobbyOwner() to determine if we should be host or client - var lobby_owner_id = Steam.getLobbyOwner(lobby_id) - var am_i_owner = (lobby_owner_id == steam_id) - - print("[Multiplayer] Lobby Owner: %s, My Steam ID: %s, Am I Owner?: %s" % [lobby_owner_id, steam_id, am_i_owner]) - - if not am_i_owner: - print("[Multiplayer] I am not the lobby owner, setting up as client...") - setup_multiplayer_peer(false) # Setup as client - else: - print("[Multiplayer] I am the lobby owner, but multiplayer peer should already be set up as host.") - else: - ## ADDED: Log the specific reason for the join failure. - print("!!! Failed to join lobby. Reason: %s" % get_join_fail_reason(response)) - - -func get_lobby_members() -> void: - lobby_members.clear() - if lobby_id == 0: return - - var num_members = Steam.getNumLobbyMembers(lobby_id) - print("--- Refreshing Lobby Members (%s) ---" % num_members) - for i in range(num_members): - var member_id = Steam.getLobbyMemberByIndex(lobby_id, i) - var member_name = Steam.getFriendPersonaName(member_id) - lobby_members.append({ - "steam_id": member_id, - "steam_name": member_name - }) - print(" - %s (%s)" % [member_name, member_id]) - print("---------------------------------") - - -func _on_lobby_data_update(lobby: int, user: int, success: int) -> void: - if success: - if lobby == user: - print("Lobby data for lobby %s has been updated." % lobby) - var lobby_name = Steam.getLobbyData(lobby, "name") - print(" > New lobby name: %s" % lobby_name) - else: - print("Data for member %s in lobby %s has been updated." % [user, lobby]) - - -func _on_persona_change(steam_id_changed: int, flag: int) -> void: - # This can be spammy, but useful for debugging name changes. - # print("Persona state changed for %s. Refreshing lobby members." % steam_id_changed) - get_lobby_members() - - -func leave_lobby() -> void: - pass - - -func _on_lobby_chat_update(lobby_id_update: int, user_changed_id: int, user_making_change_id: int, chat_state: int): +func _on_lobby_chat_update(_l_id, user_changed_id: int, _u_m_c_id, chat_state: int): var state_string = "UNKNOWN" match chat_state: Steam.CHAT_MEMBER_STATE_CHANGE_ENTERED: state_string = "ENTERED" Steam.CHAT_MEMBER_STATE_CHANGE_LEFT: state_string = "LEFT" Steam.CHAT_MEMBER_STATE_CHANGE_DISCONNECTED: state_string = "DISCONNECTED" - Steam.CHAT_MEMBER_STATE_CHANGE_KICKED: state_string = "KICKED" - Steam.CHAT_MEMBER_STATE_CHANGE_BANNED: state_string = "BANNED" - - print("[Lobby] Chat Update: User %s has %s." % [user_changed_id, state_string]) - - # Any change in lobby membership should trigger a refresh. - get_lobby_members() + print("[LOBBY INFO] User %s has %s the lobby." % [user_changed_id, state_string]) -func _on_peer_connected(id: int) -> void: - print("[Multiplayer] ✅ Peer connected: %s" % id) - # It's good practice to re-check lobby members when a peer connects successfully. - get_lobby_members() - -func _on_peer_disconnected(id: int) -> void: - print("[Multiplayer] ❌ Peer disconnected: %s" % id) - -func _on_connected_to_server() -> void: - print("[Multiplayer] ✅ Successfully connected to the host.") - print("[Multiplayer] - My Peer ID is now: %s" % multiplayer.get_unique_id()) - -func _on_connection_failed() -> void: - print("[Multiplayer] ❌ Connection to the host failed.") - -func _on_server_disconnected() -> void: - print("[Multiplayer] ❌ Disconnected from the host.") - - -## ADDED: New function to log all relevant multiplayer and lobby information. -func log_multiplayer_info(): - print("\n--- DIAGNOSTIC INFO ---") - print("## Multiplayer Status:") - if multiplayer.multiplayer_peer: - print(" - Peer State: Active") - print(" - Connection Status: %s" % get_connection_status_string(multiplayer.multiplayer_peer.get_connection_status())) - print(" - Is Server?: %s" % multiplayer.is_server()) - print(" - My Peer ID: %s" % multiplayer.get_unique_id()) - print(" - Connected Peer IDs: %s" % multiplayer.get_peers()) - else: - print(" - Peer State: Inactive (null)") - - print("\n## Steam Lobby Info:") - print(" - In Lobby?: %s" % (lobby_id != 0)) - print(" - Lobby ID: %s" % lobby_id) - if lobby_id != 0: - print(" - Lobby Owner Steam ID: %s" % Steam.getLobbyOwner(lobby_id)) - print(" - My Steam ID: %s" % steam_id) - print(" - Lobby Members Array (%s):" % lobby_members.size()) - for member in lobby_members: - print(" - %s (%s)" % [member.steam_name, member.steam_id]) - print("-------------------------\n") - - -## ADDED: Helper function to get a human-readable string for connection status. -func get_connection_status_string(status: int) -> String: - match status: - MultiplayerPeer.CONNECTION_DISCONNECTED: return "Disconnected" - MultiplayerPeer.CONNECTION_CONNECTING: return "Connecting" - MultiplayerPeer.CONNECTION_CONNECTED: return "Connected" - _: return "Unknown Status" +func check_command_line() -> void: + var args: Array = OS.get_cmdline_args() + if args.size() > 1 and args[0] == "+connect_lobby": + if int(args[1]) > 0: + print("[CMD] Command line join request for lobby ID: %s" % args[1]) + join_lobby(int(args[1])) func get_join_fail_reason(response: int) -> String: match response: - Steam.CHAT_ROOM_ENTER_RESPONSE_DOESNT_EXIST: return "Lobby no longer exists" - Steam.CHAT_ROOM_ENTER_RESPONSE_NOT_ALLOWED: return "Not allowed to join" - Steam.CHAT_ROOM_ENTER_RESPONSE_FULL: return "Lobby is full" - Steam.CHAT_ROOM_ENTER_RESPONSE_ERROR: return "Unknown error" - Steam.CHAT_ROOM_ENTER_RESPONSE_BANNED: return "You are banned" - Steam.CHAT_ROOM_ENTER_RESPONSE_LIMITED: return "Limited account" - Steam.CHAT_ROOM_ENTER_RESPONSE_CLAN_DISABLED: return "Lobby is locked" - Steam.CHAT_ROOM_ENTER_RESPONSE_COMMUNITY_BAN: return "Community locked" - Steam.CHAT_ROOM_ENTER_RESPONSE_MEMBER_BLOCKED_YOU: return "A member blocked you" - Steam.CHAT_ROOM_ENTER_RESPONSE_YOU_BLOCKED_MEMBER: return "You blocked a member" - _: return "Unknown reason" + 1: return "Doesnt Exist" + 2: return "Not Allowed" + 3: return "Full" + 4: return "Error" + 5: return "Banned" + 6: return "Limited" + 7: return "Clan Disabled" + 8: return "Community Ban" + 9: return "Member Blocked You" + 10: return "You Blocked Member" + _: return "Unknown Reason" diff --git a/splunk/player/Player.tscn b/splunk/player/Player.tscn index df1ce5f..b4ed1ee 100644 --- a/splunk/player/Player.tscn +++ b/splunk/player/Player.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=8 format=3 uid="uid://csmfxg011xisf"] +[gd_scene load_steps=7 format=3 uid="uid://csmfxg011xisf"] [ext_resource type="Script" uid="uid://dopyfulbw2mx5" path="res://player/player.gd" id="1_ulp21"] -[ext_resource type="PackedScene" uid="uid://8phs2e161db1" path="res://ui/multiplayer-debug-ui/multiplayer-debug-ui.tscn" id="2_3c3w1"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ehsmr"] @@ -21,9 +20,6 @@ properties/0/replication_mode = 2 properties/1/path = NodePath(".:rotation") properties/1/spawn = true properties/1/replication_mode = 2 -properties/2/path = NodePath("Label3D:text") -properties/2/spawn = true -properties/2/replication_mode = 1 [node name="Player" type="CharacterBody3D"] collision_layer = 2 @@ -32,8 +28,6 @@ script = ExtResource("1_ulp21") [node name="Camera3D" type="Camera3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.399442, 0.0644827) -cull_mask = 1048573 -current = true [node name="CollisionShape3D" type="CollisionShape3D" parent="."] shape = SubResource("CapsuleShape3D_ehsmr") @@ -65,14 +59,10 @@ layers = 2 mesh = SubResource("SphereMesh_wnvi2") skeleton = NodePath("../..") -[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] -replication_config = SubResource("SceneReplicationConfig_ulp21") - [node name="Label3D" type="Label3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.887858, 0) billboard = 1 text = "Username" -[node name="CanvasLayer" type="CanvasLayer" parent="."] - -[node name="Multiplayer-debug-ui" parent="CanvasLayer" instance=ExtResource("2_3c3w1")] +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_ulp21") diff --git a/splunk/player/player.gd b/splunk/player/player.gd index 4c561a4..d0cca40 100644 --- a/splunk/player/player.gd +++ b/splunk/player/player.gd @@ -1,4 +1,5 @@ extends CharacterBody3D +class_name Player @export var speed = 5.0 @export var jump_velocity = 4.5 @@ -7,54 +8,72 @@ extends CharacterBody3D var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") var camera_node: Camera3D + + + + func _ready(): - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - camera_node = $Camera3D # Assuming Camera3D is a direct child + if is_multiplayer_authority(): + print("-> [%s] Authority granted. Setting up camera and input." % name) + camera_node = $Camera3D + camera_node.make_current() + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) + $Mesh.hide() - $Label3D.text = SteamManager.steam_username -func _physics_process(delta): - # Apply gravity - if not is_on_floor(): - velocity.y -= gravity * delta +func set_player_name(peer_id: String, player_name: String): + name = peer_id + $Label3D.text = player_name - # Handle Jump - if Input.is_action_just_pressed("jump") and is_on_floor(): - velocity.y = jump_velocity - # Get the input direction and apply movement - var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") - var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() +#@rpc("any_peer", "call_local", "unreliable") +#func update_remote_transform(new_transform: Transform3D): + #global_transform = new_transform - if is_on_floor(): - if direction: - velocity.x = direction.x * speed - velocity.z = direction.z * speed + +func _physics_process(delta): + if is_multiplayer_authority(): + # Apply gravity + if not is_on_floor(): + velocity.y -= gravity * delta + + # Handle Jump + if Input.is_action_just_pressed("jump") and is_on_floor(): + velocity.y = jump_velocity + + # Get the input direction and apply movement + var input_dir = Input.get_vector("move_left", "move_right", "move_forward", "move_backward") + var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + + if is_on_floor(): + if direction: + velocity.x = direction.x * speed + velocity.z = direction.z * speed + else: + velocity.x = move_toward(velocity.x, 0, speed) + velocity.z = move_toward(velocity.z, 0, speed) else: - velocity.x = move_toward(velocity.x, 0, speed) - velocity.z = move_toward(velocity.z, 0, speed) - else: - # Air control - velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0) - velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0) - - move_and_slide() + # Air control + velocity.x = lerp(velocity.x, direction.x * speed, delta * 5.0) + velocity.z = lerp(velocity.z, direction.z * speed, delta * 5.0) + move_and_slide() + + #update_remote_transform.rpc(global_transform) + func _input(event): - if event is InputEventMouseMotion: - # Rotate the CharacterBody3D around the Y-axis for horizontal look - rotate_y(-event.relative.x * mouse_sensitivity) + if is_multiplayer_authority(): + if event is InputEventMouseMotion: + # Rotate the CharacterBody3D around the Y-axis for horizontal look + rotate_y(-event.relative.x * mouse_sensitivity) - # Rotate the Camera3D around its local X-axis for vertical look - var change = -event.relative.y * mouse_sensitivity - var new_x_rotation = camera_node.rotation.x + change - camera_node.rotation.x = clamp(new_x_rotation, deg_to_rad(-90), deg_to_rad(90)) + # Rotate the Camera3D around its local X-axis for vertical look + var change = -event.relative.y * mouse_sensitivity + var new_x_rotation = camera_node.rotation.x + change + camera_node.rotation.x = clamp(new_x_rotation, deg_to_rad(-90), deg_to_rad(90)) - if event.is_action_pressed("ui_cancel"): # Typically Escape key - if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: - Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) - else: - Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) - - if event.is_action_pressed("toggle_watch"): - $"CanvasLayer/Multiplayer-debug-ui".visible = !$"CanvasLayer/Multiplayer-debug-ui".visible + if event.is_action_pressed("ui_cancel"): # Typically Escape key + if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED: + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + else: + Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED) diff --git a/splunk/project.godot b/splunk/project.godot index aa31ded..2a11b0e 100644 --- a/splunk/project.godot +++ b/splunk/project.godot @@ -18,6 +18,7 @@ config/icon="res://icon.svg" [autoload] SteamManager="*res://networking/steam-manager.gd" +GameManager="*res://game-logic/game_manager.gd" [editor_plugins]