75 lines
2.6 KiB
GDScript
75 lines
2.6 KiB
GDScript
extends Node3D
|
|
|
|
const PLAYER_SCENE: PackedScene = preload("res://scenes/entities/player/player.tscn")
|
|
|
|
@onready var players_root: Node3D = $EntityRoot/Players
|
|
@onready var ground_shape: CollisionShape3D = $Ground/GroundShape
|
|
@onready var npc_system: Node = $Systems/NpcSystem
|
|
@onready var wave_system: Node = $Systems/WaveSystem
|
|
|
|
func _ready() -> void:
|
|
add_to_group("world")
|
|
_setup_ground_collision()
|
|
Net.world_ready.connect(_on_world_ready)
|
|
Net.peer_world_loaded.connect(_on_peer_world_loaded)
|
|
if Net.is_host():
|
|
multiplayer.peer_connected.connect(_on_peer_connected)
|
|
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
|
Net.reset_world_ready()
|
|
Net.mark_world_loaded()
|
|
|
|
func _exit_tree() -> void:
|
|
if Net.is_host():
|
|
if multiplayer.peer_connected.is_connected(_on_peer_connected):
|
|
multiplayer.peer_connected.disconnect(_on_peer_connected)
|
|
if multiplayer.peer_disconnected.is_connected(_on_peer_disconnected):
|
|
multiplayer.peer_disconnected.disconnect(_on_peer_disconnected)
|
|
if Net.world_ready.is_connected(_on_world_ready):
|
|
Net.world_ready.disconnect(_on_world_ready)
|
|
if Net.peer_world_loaded.is_connected(_on_peer_world_loaded):
|
|
Net.peer_world_loaded.disconnect(_on_peer_world_loaded)
|
|
|
|
func _setup_ground_collision() -> void:
|
|
var shape := WorldBoundaryShape3D.new()
|
|
shape.plane = Plane(Vector3.UP, 0.0)
|
|
ground_shape.shape = shape
|
|
|
|
func _on_world_ready() -> void:
|
|
if not Net.is_host():
|
|
return
|
|
_spawn_player(1)
|
|
for id in multiplayer.get_peers():
|
|
_spawn_player(id)
|
|
npc_system.spawn_default_npcs()
|
|
if wave_system and wave_system.has_method("start_wave"):
|
|
wave_system.start_wave(GameState.current_wave)
|
|
|
|
func _on_peer_connected(id: int) -> void:
|
|
Net.tell_peer_to_load_scene(id, GameState.SCENE_WORLD)
|
|
|
|
func _on_peer_world_loaded(peer_id: int) -> void:
|
|
if not Net.is_host():
|
|
return
|
|
_spawn_player(peer_id)
|
|
|
|
func _on_peer_disconnected(id: int) -> void:
|
|
var node := players_root.get_node_or_null(str(id))
|
|
if node:
|
|
node.queue_free()
|
|
|
|
func _spawn_player(peer_id: int) -> void:
|
|
if players_root.get_node_or_null(str(peer_id)) != null:
|
|
return
|
|
var p: CharacterBody3D = PLAYER_SCENE.instantiate()
|
|
p.name = str(peer_id)
|
|
var spawn := _spawn_position_for(peer_id)
|
|
players_root.add_child(p, true)
|
|
p.global_position = spawn
|
|
|
|
func _spawn_position_for(peer_id: int) -> Vector3:
|
|
if GameState.portal_return_position != Vector3.ZERO:
|
|
var off: float = float(peer_id) * 0.7
|
|
return GameState.portal_return_position + Vector3(cos(off) * 1.2, 1.5, sin(off) * 1.2)
|
|
var angle: float = wrapf(float(peer_id) * 1.7, 0.0, TAU)
|
|
return Vector3(cos(angle) * 5.0, 1.5, sin(angle) * 5.0)
|