Files
net-gunner/scripts/level.gd

225 lines
6.4 KiB
GDScript

class_name Level extends Node3D
const map_marker_templates : Dictionary[String, PackedScene] = {
"pawn" : preload("res://templates/markers/pawn_marker.tscn"),
"friendly_hack":preload("res://templates/markers/friendly_hack_marker.tscn"),
"enemy_hack": preload("res://templates/markers/enemy_hack_marker.tscn"),
"item": preload("res://templates/markers/item_marker.tscn")
}
const pawn_controller = preload("res://templates/pawn_controller.tscn")
const hack_template = preload("res://templates/hack.tscn")
const camera_template = preload("res://templates/pawn_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 hacks_node : Node3D = %Hacks
@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
var hacks : Dictionary[Vector3i, Hack] = {}
var pawns : Dictionary[int, PawnController] = {}
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()
#add_level_hack.call_deferred(Hack.Type.PURGE, Vector3.ZERO, Vector3i(-2,2,0))
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 pos : Vector3
if(spawn_points == null
or len(spawn_points) <= 1):
pos = Vector3(0,0,0)
else:
pos = spawn_points[0].global_position
pc.global_position = pos
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()
pawns[key] = pc
pawns_node.add_child(pc,true)
await multiplayer_level_setup.all_players_ready
for key in pawns:
var pc = pawns[key]
var pos : Vector3
if(spawn_points == null
or len(spawn_points) <= count):
if key == Multiplayer.id:
pos = Vector3(0,0,0)
else:
pos = Vector3(3,0,0)
else:
pos = spawn_points[count].global_position
count += 1
pc.global_position = pos
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
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 hack_crd = crd + Vector3i(0,1,0)
if hacks.has(hack_crd):
var hack : Hack = hacks[hack_crd]
if hack.hack_owner != Multiplayer.id:
hack.reveal()
return true
func add_pawn_camera(pawn : PawnController) -> void:
var camera : PawnCamera = camera_template.instantiate()
camera.position = pawn.global_position + camera_offset
cameras_node.add_child(camera,true)
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
hacks[crd] = hack
hack.position = Vector3(crd) + Vector3(.5, 0, .5)
add_child(hack, true)
func add_projectile(shot : Projectile) -> void:
add_child(shot, true)
func uninstall_hack_square(crd : Vector3i) -> void:
hacks.erase(crd)
func get_square_hack(crd : Vector3i) -> Hack:
if hacks.has(crd):
return hacks[crd]
else:
return null
func is_valid_hack_square(crd : Vector3i) -> bool:
if floor_layer.get_cell_item(crd + Vector3i(0,-1,0)) == GridMap.INVALID_CELL_ITEM:
return false
if hacks.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, true)
func activate_hack(crd : Vector3i) -> void:
if hacks.has(crd):
hacks[crd].activate()
func generate_hack(type : Hack.Type, dir : Vector3, square : Vector3i):
var hack = hack_template.instantiate()
hack.setup(type, dir, -1)
add_hack(hack, square)
func decompile_hack(crd : Vector3i) -> void:
var hack = hacks[crd]
hack.decompile()
hacks.erase(crd)
func remove_map_marker(target) -> void:
if !map_markers.has(target):
printerr("Tried to remove a map marker for %s but marker does not exist!" % target.name)
else:
map_markers[target].queue_free()
map_markers[target] = null
func add_map_marker(target) -> void:
var marker : MapMarker
var height : float = 0
if target is PawnController:
marker = map_marker_templates.pawn.instantiate()
height += 40
elif target is Hack:
if target.hack_owner == Multiplayer.id:
marker = map_marker_templates.friendly_hack.instantiate()
else:
marker = map_marker_templates.enemy_hack.instantiate()
marker.visible = false
target.revealed.connect(marker._on_hack_revealed)
height += 30
elif target is Item:
marker = map_marker_templates.item.instantiate()
height += 10
marker.register_target(target)
map_markers[target] = marker
map_markers_node.add_child(marker)
marker.position += Vector3(0, height,0)
func add_level_hack(type : Hack.Type, facing : Vector3, crd : Vector3i) -> void:
var hack = hack_template.instantiate()
hack.setup(type, facing, -1)
add_hack(hack, crd)