bugfix, desync, and add UI function
This commit is contained in:
+50
-18
@@ -59,9 +59,14 @@ func _init_managers():
|
||||
screen_shake_manager.initialize($Camera3D)
|
||||
|
||||
# Touch controls for mobile
|
||||
touch_controls = load("res://scripts/managers/touch_controls.gd").new()
|
||||
touch_controls.name = "TouchControls"
|
||||
add_child(touch_controls)
|
||||
# Touch controls for mobile
|
||||
touch_controls = get_node_or_null("TouchControls")
|
||||
if not touch_controls:
|
||||
print("TouchControls node not found in scene, creating instance...")
|
||||
touch_controls = load("res://scripts/managers/touch_controls.gd").new()
|
||||
touch_controls.name = "TouchControls"
|
||||
add_child(touch_controls)
|
||||
|
||||
touch_controls.initialize(self)
|
||||
|
||||
# Connect signals for UI updates
|
||||
@@ -180,8 +185,16 @@ func broadcast_message(player_name: String, message: String):
|
||||
|
||||
func _setup_global_match_timer_ui():
|
||||
"""Create the global match timer display at the top of the screen."""
|
||||
# Check if timer check is enabled in lobby settings
|
||||
if not LobbyManager.enable_cycle_timer:
|
||||
var existing = get_node_or_null("GlobalMatchTimer")
|
||||
if existing:
|
||||
existing.visible = false
|
||||
return
|
||||
|
||||
var existing = get_node_or_null("GlobalMatchTimer")
|
||||
if existing:
|
||||
existing.visible = true
|
||||
return
|
||||
|
||||
# Create timer panel
|
||||
@@ -345,21 +358,40 @@ func _setup_client_game():
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
print("Client setup - my peer ID: ", my_id)
|
||||
|
||||
# Create local player immediately
|
||||
if not has_node(str(my_id)):
|
||||
var player_character = PlayerManager.add_player_character(my_id)
|
||||
add_child(player_character)
|
||||
player_character.add_to_group("Players", true)
|
||||
GameStateManager.add_player(my_id)
|
||||
GameStateManager.local_player_character = player_character
|
||||
ui_manager.set_local_player(player_character)
|
||||
if touch_controls:
|
||||
touch_controls.set_player(player_character)
|
||||
ui_manager.update_button_states()
|
||||
print("Created local player for client: ", my_id)
|
||||
# Pre-spawn ALL players known from LobbyManager (including Host ID 1)
|
||||
# This ensures nodes exist to receive RPCs (like 'set_spawn_position') that might arrive before full sync
|
||||
var lobby_players = LobbyManager.get_players()
|
||||
for player_data in lobby_players:
|
||||
var p_id = player_data.get("id", 0)
|
||||
if p_id != 0:
|
||||
add_player_character(p_id)
|
||||
print("Client: Pre-spawned player ", p_id)
|
||||
|
||||
# Wait for host to be ready, then request full sync
|
||||
await get_tree().create_timer(2.0).timeout
|
||||
# Pre-spawn potential bots (IDs 2 to MaxPlayers) to prevent RPC "Node not found" errors
|
||||
# Bots use small integer IDs (2, 3, 4...) while clients use large unique IDs
|
||||
if GameStateManager.enable_bots:
|
||||
for i in range(2, GameStateManager.max_players + 1):
|
||||
# Only spawn if not already existing (e.g. if a human somehow got this ID, though unlikely)
|
||||
if not has_node(str(i)):
|
||||
add_player_character(i)
|
||||
get_node(str(i)).is_bot = true # Assume bot initially
|
||||
get_node(str(i)).add_to_group("Bots", true)
|
||||
print("Client: Pre-spawned potential bot ", i)
|
||||
|
||||
# Ensure local player setup (UI, controls) is verified
|
||||
var player_character = get_node_or_null(str(my_id))
|
||||
if player_character:
|
||||
# If we just spawned it above, we need to set these locally too
|
||||
if GameStateManager.local_player_character != player_character:
|
||||
GameStateManager.local_player_character = player_character
|
||||
ui_manager.set_local_player(player_character)
|
||||
if touch_controls:
|
||||
touch_controls.set_player(player_character)
|
||||
ui_manager.update_button_states()
|
||||
print("Client: Configured local player ", my_id)
|
||||
|
||||
# Wait shorter time for host to be ready, then request full sync to correct positions/state
|
||||
await get_tree().create_timer(1.0).timeout
|
||||
rpc_id(1, "request_full_player_sync", my_id)
|
||||
|
||||
func _auto_start_from_lobby():
|
||||
@@ -483,7 +515,7 @@ func add_player_character(peer_id: int):
|
||||
|
||||
func _on_peer_connected(new_peer_id: int):
|
||||
if multiplayer.is_server():
|
||||
await get_tree().create_timer(1.5).timeout
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
add_player_character(new_peer_id)
|
||||
rpc("add_newly_connected_player_character", new_peer_id)
|
||||
|
||||
|
||||
+89
-1
@@ -1,4 +1,4 @@
|
||||
[gd_scene load_steps=27 format=3 uid="uid://dxn87yj8qnfpp"]
|
||||
[gd_scene load_steps=29 format=3 uid="uid://dxn87yj8qnfpp"]
|
||||
|
||||
[ext_resource type="MeshLibrary" uid="uid://kcv6ans86ug7" path="res://addons/enhanced_gridmap/meshlibrary/default.tres" id="1_110wo"]
|
||||
[ext_resource type="Script" uid="uid://co1ads72by6na" path="res://scenes/main.gd" id="1_xcpe3"]
|
||||
@@ -22,6 +22,8 @@
|
||||
[ext_resource type="StyleBox" uid="uid://d3ruc8gytoovx" path="res://assets/styles/ribbon_selected_gui.tres" id="18_u5x6e"]
|
||||
[ext_resource type="StyleBox" uid="uid://cdhnwvcklbyl8" path="res://assets/styles/ribbon_hovered_gui.tres" id="19_w1rqq"]
|
||||
[ext_resource type="StyleBox" uid="uid://3yog1weaqhxb" path="res://assets/styles/ribbon_unselected_gui.tres" id="20_q6bc1"]
|
||||
[ext_resource type="Script" uid="uid://b54tfa0n6kogi" path="res://scripts/managers/touch_controls.gd" id="touch_manager"]
|
||||
[ext_resource type="Script" uid="uid://djiml4sh61dc1" path="res://scripts/ui/virtual_joystick.gd" id="virtual_joystick"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_playerboard"]
|
||||
content_margin_left = 8.0
|
||||
@@ -9699,6 +9701,92 @@ custom_minimum_size = Vector2(0, 40)
|
||||
layout_mode = 2
|
||||
text = "Back"
|
||||
|
||||
[node name="TouchControls" type="CanvasLayer" parent="."]
|
||||
layer = 10
|
||||
script = ExtResource("touch_manager")
|
||||
|
||||
[node name="TouchControls" type="Control" parent="TouchControls"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_top = 318.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 1
|
||||
|
||||
[node name="VirtualJoystick" type="Control" parent="TouchControls/TouchControls"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 2
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = 120.0
|
||||
offset_top = -280.0
|
||||
offset_right = 280.0
|
||||
offset_bottom = -120.0
|
||||
grow_vertical = 0
|
||||
script = ExtResource("virtual_joystick")
|
||||
|
||||
[node name="GrabBtn" type="Button" parent="TouchControls/TouchControls"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -232.0
|
||||
offset_top = -286.0
|
||||
offset_right = -162.0
|
||||
offset_bottom = -216.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
text = "👋"
|
||||
|
||||
[node name="PutBtn" type="Button" parent="TouchControls/TouchControls"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -152.0
|
||||
offset_top = -206.0
|
||||
offset_right = -82.0
|
||||
offset_bottom = -136.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
text = "📦"
|
||||
|
||||
[node name="SpecialBtn" type="Button" parent="TouchControls/TouchControls"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -232.0
|
||||
offset_top = -126.0
|
||||
offset_right = -162.0
|
||||
offset_bottom = -56.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
text = "⚡"
|
||||
|
||||
[node name="SettingsBtn" type="Button" parent="TouchControls/TouchControls"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -69.0
|
||||
offset_top = -69.0
|
||||
offset_right = -19.0
|
||||
offset_bottom = -19.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
text = "⚙"
|
||||
|
||||
[connection signal="pressed" from="Menu/Host" to="." method="_on_host_pressed"]
|
||||
[connection signal="pressed" from="Menu/Join" to="." method="_on_join_pressed"]
|
||||
[connection signal="text_submitted" from="MessageInput" to="." method="_on_message_input_text_submitted"]
|
||||
|
||||
+26
-6
@@ -78,6 +78,8 @@ var spawn_locations = [
|
||||
var finish_locations: Array:
|
||||
get: return race_manager.finish_locations if race_manager else []
|
||||
|
||||
var target_visual_position: Vector3 = Vector3.ZERO # For client-side smoothing
|
||||
|
||||
var spawn_point_selected = false
|
||||
|
||||
# Action for hilighter
|
||||
@@ -145,8 +147,8 @@ func _ready():
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_display_name", display_name)
|
||||
|
||||
# Wait briefly to ensure proper scene setup
|
||||
await get_tree().create_timer(0.1).timeout
|
||||
# Wait briefly to ensure proper scene setup and server recognition
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
|
||||
# More robust way to get the main scene
|
||||
var main_scene = get_tree().get_root().get_node_or_null("Main")
|
||||
@@ -226,8 +228,11 @@ func _ready():
|
||||
1.0,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
)
|
||||
target_visual_position = global_position
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_position", current_position)
|
||||
else:
|
||||
target_visual_position = global_position
|
||||
|
||||
func _init_managers():
|
||||
movement_manager = load("res://scripts/managers/player_movement_manager.gd").new()
|
||||
@@ -609,6 +614,11 @@ func _process(delta):
|
||||
if _verify_timer >= 3.0:
|
||||
_verify_timer = 0.0
|
||||
rpc("ping_existence")
|
||||
else:
|
||||
# Client-side visual smoothing
|
||||
# Interpolate towards the target position received from authority
|
||||
if global_position.distance_squared_to(target_visual_position) > 0.001:
|
||||
global_position = global_position.lerp(target_visual_position, delta * 15.0)
|
||||
|
||||
# Delegate rotation to movement manager
|
||||
if movement_manager:
|
||||
@@ -942,7 +952,8 @@ static func reset_race_stats():
|
||||
|
||||
@rpc("any_peer", "call_local", "unreliable")
|
||||
func remote_set_position(authority_position):
|
||||
global_position = authority_position
|
||||
# Don't snap directly, update target for interpolation
|
||||
target_visual_position = authority_position
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func display_message(message, type: int = 0):
|
||||
@@ -1371,11 +1382,14 @@ func bot_arrange_item(from_slot: int, to_slot: int):
|
||||
|
||||
func update_visual_position():
|
||||
# Ensure proper grid-aligned positioning
|
||||
global_position = Vector3(
|
||||
var new_pos = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
1.0,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
)
|
||||
global_position = new_pos
|
||||
target_visual_position = new_pos # Snap target too
|
||||
|
||||
if is_multiplayer_authority():
|
||||
rpc("sync_position", current_position)
|
||||
|
||||
@@ -1383,11 +1397,14 @@ func update_visual_position():
|
||||
func sync_position(pos: Vector2i):
|
||||
current_position = pos
|
||||
# Always update the visual position after position sync
|
||||
global_position = Vector3(
|
||||
var new_pos = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
cell_size.y,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
) + cell_offset
|
||||
|
||||
global_position = new_pos
|
||||
target_visual_position = new_pos # Reset smoothing target to prevent fighting
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
func set_spawn_position(pos: Vector2i):
|
||||
@@ -1397,11 +1414,14 @@ func set_spawn_position(pos: Vector2i):
|
||||
# Clear any spawn highlights
|
||||
clear_spawn_highlights()
|
||||
# Update visual position
|
||||
global_position = Vector3(
|
||||
var new_pos = Vector3(
|
||||
current_position.x * cell_size.x + cell_size.x * 0.5,
|
||||
cell_size.y,
|
||||
current_position.y * cell_size.z + cell_size.z * 0.5
|
||||
) + cell_offset
|
||||
|
||||
global_position = new_pos
|
||||
target_visual_position = new_pos
|
||||
|
||||
|
||||
@rpc("any_peer", "call_local", "reliable")
|
||||
|
||||
Reference in New Issue
Block a user