class_name Game extends Node signal players_changed(players: Array[Player]) const MAIN_MENU_SCENE = preload("uid://dpuwsqorot65h") const BOARD_GAME_SCENE = preload("uid://dmqvnr7uev0i6") const WEB_TUBE_CONTEXT = preload("uid://berd4vlwkh1no") const LOCAL_TUBE_CONTEXT = preload("uid://c4wgewmmuj74g") var this_player: Player #var players: Dictionary[int, Player] = {} var players: Array[Player] = [] @onready var tube_client: TubeClient = %TubeClient func _ready() -> void: if ProjectSettings.get_setting_with_override("game/config/use_web_tube_context"): tube_client.context = WEB_TUBE_CONTEXT else: tube_client.context = LOCAL_TUBE_CONTEXT func _init() -> void: Globals.game = self @rpc("any_peer", "call_local", "reliable") func add_player(player_data: Dictionary) -> void: if !players.any(func(p: Player) -> bool: return p.name == player_data["name"]): players.push_back(Player.deserialize(player_data)) players_changed.emit(players) @rpc("any_peer", "call_remote", "reliable") func sync_players() -> void: for player in players: add_player.rpc(player.serialize()) @rpc("any_peer", "call_local", "reliable") func add_player_money(player_id: int, money: int) -> void: find_player_by_id(player_id).money += money func find_player_by_id(id: int) -> Player: var player_idx = players.find_custom(func(p: Player) -> bool: return p.id == id) return players[player_idx] func get_next_player(player: Player) -> Player: var player_idx = players.find_custom(func(p: Player) -> bool: return p.id == player.id) return players[(player_idx + 1) % players.size()] func get_this_player_turn_index() -> int: return players.find_custom(func(p: Player) -> bool: return p.id == this_player.id) func get_player_turn_index(player: Player) -> int: return players.find_custom(func(p: Player) -> bool: return p.id == player.id) func start_game() -> void: if is_instance_valid(Globals.main_menu): Globals.main_menu.queue_free() add_child(BOARD_GAME_SCENE.instantiate()) if Globals.game.tube_client.is_server: Globals.game.create_initial_board_state() func create_initial_board_state() -> void: Globals.board_game.board.initialize() var board_state := BoardState.new() players.shuffle() board_state.turn = -(players.size() * 2) board_state.players = players board_state.current_player = players[0] board_state.tiles = Globals.board_game.board.tiles.values() for building in Globals.board_game.board.buildings.values(): if !board_state.buildings.has(building): board_state.buildings.append(building) Globals.board_game.advance_board_state.rpc(board_state.serialize()) Globals.board_game.setup_building_deck.rpc() func shuffle_turn_order() -> void: var idx_arr: Array[int] = [] for i in range(players.size()): idx_arr.push_back(i) seed(sum_player_ids()) var new_order: Array[Player] = [] idx_arr.shuffle() players.sort_custom(func(a: Player, b: Player) -> bool: return a.id > b.id) for idx in idx_arr: new_order.push_back(players[idx]) players = new_order func sum_player_ids() -> int: var ids: Array = players.map(func(p: Player) -> int: return p.id) return ids.reduce(func(acc: int, id: int) -> int: return acc + id, 0)