154 lines
5.2 KiB
GDScript
154 lines
5.2 KiB
GDScript
extends Node
|
|
|
|
signal state_changed(state: String)
|
|
signal online_game_ready(player_slot: int)
|
|
signal online_snapshot_updated(snapshot: Dictionary)
|
|
signal online_event_received(event: Dictionary)
|
|
|
|
const PLAYER_COUNT := 2
|
|
const COOP_START_CREDITS := 450
|
|
const COOP_REACTOR_LIVES := 30
|
|
|
|
var matchmaking_state := "idle"
|
|
var matchmaking_mode := ""
|
|
var matchmaking_difficulty := 1
|
|
var online_match = null
|
|
var online_mode := false
|
|
var player_slot := -1
|
|
var latest_snapshot: Dictionary = {}
|
|
var player_credits := [COOP_START_CREDITS, COOP_START_CREDITS]
|
|
var shared_reactor_lives := COOP_REACTOR_LIVES
|
|
|
|
|
|
func reset_coop_session(start_credits := COOP_START_CREDITS, reactor_lives := COOP_REACTOR_LIVES) -> void:
|
|
player_credits = [start_credits, start_credits]
|
|
shared_reactor_lives = reactor_lives
|
|
online_mode = false
|
|
player_slot = -1
|
|
latest_snapshot = {}
|
|
|
|
|
|
func spend_player_credits(player_index: int, amount: int) -> bool:
|
|
if player_index < 0 or player_index >= PLAYER_COUNT or amount < 0:
|
|
return false
|
|
if player_credits[player_index] < amount:
|
|
return false
|
|
player_credits[player_index] -= amount
|
|
return true
|
|
|
|
|
|
func add_player_credits(player_index: int, amount: int) -> void:
|
|
if player_index >= 0 and player_index < PLAYER_COUNT:
|
|
player_credits[player_index] += maxi(0, amount)
|
|
|
|
|
|
func damage_shared_reactor(amount: int) -> void:
|
|
shared_reactor_lives = maxi(0, shared_reactor_lives - maxi(0, amount))
|
|
|
|
|
|
func _ready() -> void:
|
|
call_deferred("_bind_online_manager")
|
|
|
|
|
|
func _bind_online_manager() -> void:
|
|
var online_manager = get_parent().get_node_or_null("OnlineManager")
|
|
if not online_manager:
|
|
return
|
|
if not online_manager.matchmaking_state_changed.is_connected(_on_online_matchmaking_state_changed):
|
|
online_manager.matchmaking_state_changed.connect(_on_online_matchmaking_state_changed)
|
|
if not online_manager.match_found.is_connected(_on_online_match_found):
|
|
online_manager.match_found.connect(_on_online_match_found)
|
|
if not online_manager.match_snapshot_received.is_connected(_on_online_snapshot):
|
|
online_manager.match_snapshot_received.connect(_on_online_snapshot)
|
|
if not online_manager.match_event_received.is_connected(_on_online_event):
|
|
online_manager.match_event_received.connect(_on_online_event)
|
|
|
|
|
|
func begin_search(mode := "quick", difficulty := 1) -> void:
|
|
matchmaking_mode = mode
|
|
matchmaking_difficulty = clampi(difficulty, 0, 2)
|
|
online_match = null
|
|
online_mode = false
|
|
player_slot = -1
|
|
latest_snapshot = {}
|
|
matchmaking_state = "waiting_for_service"
|
|
state_changed.emit(matchmaking_state)
|
|
call_deferred("_begin_online_search", mode)
|
|
|
|
|
|
func cancel_search() -> void:
|
|
var online_manager = get_parent().get_node_or_null("OnlineManager")
|
|
if online_manager:
|
|
online_manager.cancel_matchmaking()
|
|
matchmaking_mode = ""
|
|
matchmaking_state = "idle"
|
|
state_changed.emit(matchmaking_state)
|
|
|
|
|
|
func _begin_online_search(mode: String) -> void:
|
|
if matchmaking_state == "idle" or matchmaking_mode != mode:
|
|
return
|
|
var online_manager = get_parent().get_node_or_null("OnlineManager")
|
|
if not online_manager:
|
|
matchmaking_state = "offline"
|
|
state_changed.emit(matchmaking_state)
|
|
return
|
|
if not online_manager.is_authenticated():
|
|
await online_manager.connect_and_authenticate()
|
|
if matchmaking_state == "idle" or matchmaking_mode != mode:
|
|
return
|
|
var started: bool = await online_manager.begin_matchmaking(mode, matchmaking_difficulty)
|
|
matchmaking_state = "searching" if started else "offline"
|
|
state_changed.emit(matchmaking_state)
|
|
|
|
|
|
func _on_online_matchmaking_state_changed(value: String) -> void:
|
|
if matchmaking_state == "idle":
|
|
return
|
|
matchmaking_state = value
|
|
state_changed.emit(matchmaking_state)
|
|
|
|
|
|
func _on_online_match_found(match_data) -> void:
|
|
online_match = match_data
|
|
online_mode = true
|
|
matchmaking_state = "matched"
|
|
state_changed.emit(matchmaking_state)
|
|
|
|
|
|
func _on_online_snapshot(snapshot: Dictionary) -> void:
|
|
latest_snapshot = snapshot
|
|
var credits = snapshot.get("credits", [])
|
|
if credits is Array and credits.size() >= PLAYER_COUNT:
|
|
player_credits = [int(credits[0]), int(credits[1])]
|
|
shared_reactor_lives = int(snapshot.get("reactor_lives", shared_reactor_lives))
|
|
var online_manager = get_parent().get_node_or_null("OnlineManager")
|
|
if online_manager and online_manager.session:
|
|
var slots: Dictionary = snapshot.get("slots", {})
|
|
var resolved_slot := int(slots.get(online_manager.session.user_id, -1))
|
|
if resolved_slot >= 0 and resolved_slot != player_slot:
|
|
player_slot = resolved_slot
|
|
if bool(snapshot.get("started", false)) and player_slot >= 0 and not online_mode:
|
|
online_mode = true
|
|
online_game_ready.emit(player_slot)
|
|
elif bool(snapshot.get("started", false)) and player_slot >= 0 and matchmaking_state == "matched":
|
|
matchmaking_state = "playing"
|
|
state_changed.emit(matchmaking_state)
|
|
online_game_ready.emit(player_slot)
|
|
online_snapshot_updated.emit(snapshot)
|
|
|
|
|
|
func _on_online_event(event: Dictionary) -> void:
|
|
online_event_received.emit(event)
|
|
|
|
|
|
func mirrored_point(point: Vector2, arena_width := 1600.0) -> Vector2:
|
|
return Vector2(arena_width - point.x, point.y)
|
|
|
|
|
|
func mirrored_path(points: PackedVector2Array, arena_width := 1600.0) -> PackedVector2Array:
|
|
var result := PackedVector2Array()
|
|
for point in points:
|
|
result.append(mirrored_point(point, arena_width))
|
|
return result
|