Pawn bodies split out, character select redesigned, and started the dreaded process of correcting the netcode. Players can connect to a shared room, character select, and start a match. They appear correctly differentiated with cameras and map icons that follow them independently. Jankiness with trap ownership is present as is stuff connected to animation. Unit tests for all network functionality required.

This commit is contained in:
2026-03-10 01:41:15 -04:00
parent 984567cf96
commit d128501f7c
52 changed files with 1179 additions and 929 deletions

View File

@@ -24,7 +24,7 @@ const camera_offset = Vector3(0, 10, 5.25)
@onready var cameras_node : Node3D = %Cameras
@onready var map_markers_node : Node3D = %MapMarkers
@onready var spawn_points : Array[Node] = $PawnSpawner.get_children()
@onready var multiplayer_level_setup : MultiplayerLevelSetup = %MultiplayerLevelSetup
@export var difficulty : int = 1
@@ -34,6 +34,7 @@ var cameras : Dictionary[int, PawnCamera] = {}
var map_markers : Dictionary[Object, MapMarker] = {}
func _ready() -> void:
process_mode=Node.PROCESS_MODE_DISABLED
Game.level = self
if Game.mode == Game.Modes.STORY:
setup()
@@ -43,20 +44,45 @@ func setup() -> void:
if Multiplayer.is_host():
spawn_players()
@rpc("authority")
func spawn_players() -> void:
if Game.is_multiplayer():
spawn_players_multiplayer()
else:
spawn_players_singleplayer()
func spawn_players_singleplayer() -> void:
var pc : PawnController = pawn_controller.instantiate()
pawns[1] = pc
pawns_node.add_child(pc,true)
var position : Vector3
if(spawn_points == null
or len(spawn_points) <= 1):
position = Vector3(0,0,0)
else:
position = spawn_points[0].global_position
pc.global_position = position
pc.setup(1, Game.pawns_selected[1])
add_pawn_camera(pc)
cameras[1].register_pawn(1)
process_mode=Node.PROCESS_MODE_INHERIT
func spawn_players_multiplayer() -> void:
var count = 0
multiplayer_level_setup.set_players_unready(Multiplayer.players.values())
multiplayer_level_setup.set_pawns_expected.rpc(Game.pawns_selected.size())
for key in Game.pawns_selected:
var pc : PawnController = pawn_controller.instantiate()
var pd = Game.pawns_selected[key]
pawns[key] = pc
pawns_node.add_child(pc,true)
var hacks : Array = []
for hack : HackSet in pd.starting_hacks:
var dict = {
"type":hack.type,
"qty":hack.qty
}
hacks.append(dict)
await multiplayer_level_setup.all_players_ready
for key in pawns:
var pc = pawns[key]
var position : Vector3
if(spawn_points == null
or len(spawn_points) <= count):
@@ -66,10 +92,23 @@ func spawn_players() -> void:
position = Vector3(3,0,0)
else:
position = spawn_points[count].global_position
pc.setup.rpc(key,hacks,position)
add_pawn_camera(pc)
count += 1
pc.global_position = position
pc.setup.rpc(key, Game.pawns_selected[key])
multiplayer_level_setup.set_players_unready(Multiplayer.players.values())
multiplayer_level_setup.set_cameras_expected.rpc(Game.pawns_selected.size())
for pc in pawns.values():
add_pawn_camera(pc)
await multiplayer_level_setup.all_players_ready
setup_cameras()
start_level.rpc()
@rpc("authority", "call_local")
func start_level() -> void:
process_mode=Node.PROCESS_MODE_INHERIT
func is_square_detected(crd) -> bool:
return marker_layer.get_cell_item(crd + Vector3i(0,-1,0)) != GridMap.INVALID_CELL_ITEM
@@ -88,15 +127,21 @@ func detect_square(crd : Vector3i, mark : bool) -> bool:
hack.reveal()
return true
@rpc("any_peer", "call_local", "reliable")
func add_pawn_camera(pawn : PawnController) -> void:
if Multiplayer.is_host():
var camera : PawnCamera = camera_template.instantiate()
camera.position = pawn.global_position + camera_offset
cameras_node.add_child(camera,true)
camera.register_pawn.rpc(pawn.id)
cameras[pawn.id] = camera
func setup_cameras() -> void:
var camera_list = cameras_node.get_children()
var idx = 0
for pawn_id in pawns:
camera_list[idx].register_pawn.rpc(pawn_id)
cameras[pawn_id] = camera_list[idx]
idx += 1
func add_hack(hack : Hack, crd : Vector3i) -> void:
hack.square = crd