synced stuff

This commit is contained in:
2026-01-22 02:15:47 +01:00
parent eaf86b39fa
commit 9b4135b175
7 changed files with 518 additions and 120 deletions

View File

@@ -140,17 +140,26 @@ func _detect_trap(detecting_player: Node) -> void:
sprite.modulate.a = 1.0
# Sync detection to all clients (including server with call_local)
if multiplayer.has_multiplayer_peer() and is_inside_tree():
# CRITICAL: Validate trap is still valid before sending RPC
# Use GameWorld RPC to avoid node path issues
if multiplayer.has_multiplayer_peer() and is_inside_tree() and is_instance_valid(self):
if multiplayer.is_server():
_sync_trap_detected.rpc()
# Use GameWorld RPC with trap name instead of path
var game_world = get_tree().get_first_node_in_group("game_world")
if game_world and game_world.has_method("_sync_trap_state_by_name"):
game_world._sync_trap_state_by_name.rpc(name, true, false) # detected=true, disarmed=false
print(detecting_player.name, " detected trap at ", global_position)
@rpc("authority", "call_local", "reliable")
func _sync_trap_detected() -> void:
# Client receives trap detection notification
# CRITICAL: Validate trap is still valid before processing
if not is_instance_valid(self) or not is_inside_tree():
return
is_detected = true
sprite.modulate.a = 1.0
if sprite:
sprite.modulate.a = 1.0
func _on_disarm_area_body_entered(body: Node) -> void:
# Show "DISARM" text if player is Dwarf and trap is detected
@@ -160,9 +169,23 @@ func _on_disarm_area_body_entered(body: Node) -> void:
if not is_detected or is_disarmed:
return
# Check if player is Dwarf
if body.character_stats and body.character_stats.race == "Dwarf":
_show_disarm_text(body)
# CRITICAL: Only show disarm text for LOCAL players who are Dwarves
# Check if this player is the local player (has authority matching local peer ID)
var is_local = false
if body.has_method("is_multiplayer_authority") and body.is_multiplayer_authority():
# This player is controlled by the local client
is_local = true
elif multiplayer.has_multiplayer_peer():
# Check if this player's authority matches our local peer ID
var player_authority = body.get_multiplayer_authority()
var local_peer_id = multiplayer.get_unique_id()
if player_authority == local_peer_id:
is_local = true
if is_local:
# Check if player is Dwarf
if body.character_stats and body.character_stats.race == "Dwarf":
_show_disarm_text(body)
func _on_disarm_area_body_exited(body: Node) -> void:
# Hide disarm text when player leaves area
@@ -234,17 +257,26 @@ func _complete_disarm() -> void:
sprite.modulate = Color(0.5, 0.5, 0.5, 0.5)
# Sync disarm to all clients
if multiplayer.has_multiplayer_peer() and is_inside_tree():
# CRITICAL: Validate trap is still valid before sending RPC
# Use GameWorld RPC to avoid node path issues
if multiplayer.has_multiplayer_peer() and is_inside_tree() and is_instance_valid(self):
if multiplayer.is_server():
_sync_trap_disarmed.rpc()
# Use GameWorld RPC with trap name instead of path
var game_world = get_tree().get_first_node_in_group("game_world")
if game_world and game_world.has_method("_sync_trap_state_by_name"):
game_world._sync_trap_state_by_name.rpc(name, true, true) # detected=true, disarmed=true
print("Trap disarmed!")
@rpc("authority", "call_local", "reliable")
func _sync_trap_disarmed() -> void:
# Client receives trap disarm notification
# CRITICAL: Validate trap is still valid before processing
if not is_instance_valid(self) or not is_inside_tree():
return
is_disarmed = true
sprite.modulate = Color(0.5, 0.5, 0.5, 0.5)
if sprite:
sprite.modulate = Color(0.5, 0.5, 0.5, 0.5)
if activation_area:
activation_area.monitoring = false
@@ -278,9 +310,14 @@ func _on_activation_area_body_shape_entered(_body_rid: RID, body: Node2D, _body_
if not is_detected:
is_detected = true
sprite.modulate.a = 1.0
if multiplayer.has_multiplayer_peer() and is_inside_tree():
# CRITICAL: Validate trap is still valid before sending RPC
# Use GameWorld RPC to avoid node path issues
if multiplayer.has_multiplayer_peer() and is_inside_tree() and is_instance_valid(self):
if multiplayer.is_server():
_sync_trap_detected.rpc()
# Use GameWorld RPC with trap name instead of path
var game_world = get_tree().get_first_node_in_group("game_world")
if game_world and game_world.has_method("_sync_trap_state_by_name"):
game_world._sync_trap_state_by_name.rpc(name, true, false) # detected=true, disarmed=false
# Deal damage to player (with luck-based avoidance)
_deal_trap_damage(body)