Renamed a bunch of player stuff to pawn stuff and implemented extensive work on getting single-address 'netplay' code working. Not sure if I've created issues with single player but in theory it should all transfer across as if the player is simply always the host.

This commit is contained in:
2026-01-08 07:15:20 -05:00
parent 9fe376e27e
commit ec02685065
69 changed files with 1525 additions and 708 deletions

122
scripts/level.gd Normal file
View File

@@ -0,0 +1,122 @@
class_name Level extends Node3D
const pawn_controller = preload("res://templates/pawn_controller.tscn")
const trap_template = preload("res://templates/trap.tscn")
const camera_template = preload("res://templates/camera.tscn")
const camera_offset = Vector3(0, 10, 5.25)
@onready var floor_layer : GridMap = %Floor
@onready var ramp_layer : GridMap = %Ramps
@onready var marker_layer : GridMap = %Markers
@onready var pawns_node : Node3D = %Pawns
@onready var traps_node : Node3D = %Traps
@onready var cameras_node : Node3D = %Cameras
@export var difficulty : int = 1
var traps : Dictionary[Vector3i, Trap] = {}
var pawns : Dictionary[int, PawnController] = {}
var cameras : Dictionary[int, PawnCamera] = {}
func _ready() -> void:
Game.level = self
func setup() -> void:
if Multiplayer.is_host():
spawn_players()
func spawn_players() -> void:
for key in Game.pawns_selected:
var pc : PawnController = pawn_controller.instantiate()
var pd = Game.pawns_selected[key]
pawns_node.add_child(pc,true)
var traps : Array = []
for trap : TrapSet in pd.starting_traps:
var dict = {
"type":trap.type,
"qty":trap.qty
}
traps.append(dict)
var position : Vector3
if key == Multiplayer.id:
position = Vector3(0,0,0)
else:
position = Vector3(3,0,0)
pc.setup.rpc(key,traps,position)
add_pawn_camera(pc)
func is_square_detected(crd) -> bool:
return marker_layer.get_cell_item(crd + Vector3i(0,-1,0)) != GridMap.INVALID_CELL_ITEM
func detect_square(crd : Vector3i, mark : bool) -> bool:
var cell = floor_layer.get_cell_item(crd)
if cell == GridMap.INVALID_CELL_ITEM:
return false
marker_layer.set_cell_item(crd, 0 if mark else GridMap.INVALID_CELL_ITEM)
if mark:
var trap_crd = crd + Vector3i(0,1,0)
if traps.has(trap_crd):
var trap : Trap = traps[trap_crd]
if trap.trap_owner != Multiplayer.id:
trap.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)
func add_trap(trap : Trap, crd : Vector3i) -> void:
trap.square = crd
traps[crd] = trap
trap.position = Vector3(crd) + Vector3(.5, 0, .5)
add_child(trap)
func add_projectile(shot : Projectile) -> void:
add_child(shot)
func remove_trap_square(crd : Vector3i) -> void:
traps.erase(crd)
func get_square_trap(crd : Vector3i) -> Trap:
if traps.has(crd):
return traps[crd]
else:
return null
func is_valid_trap_square(crd : Vector3i) -> bool:
if floor_layer.get_cell_item(crd + Vector3i(0,-1,0)) == GridMap.INVALID_CELL_ITEM:
return false
if traps.has(crd):
return false
return true
func add_vfx(vfx, crd : Vector3i) -> void:
vfx.position = Vector3(crd) #+ Vector3(0.5, 0, 0.5)
add_child(vfx)
func activate_trap(crd : Vector3i) -> void:
if traps.has(crd):
traps[crd].activate()
func generate_trap(type : Trap.Type, dir : Vector3, square : Vector3i):
var trap = trap_template.instantiate()
trap.setup(type, dir, -1)
add_trap(trap, square)
func disarm_trap(crd : Vector3i) -> void:
var trap = traps[crd]
trap.disarm()
traps.erase(crd)