# Undercooked - a game about cooking # Copyright 2024 nokoe # Copyright 2024 metamuffin # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, version 3 of the License only. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # class_name Game extends Node3D @onready var camera: FollowCamera = $FollowCamera @onready var mp: Multiplayer = $Multiplayer @onready var map: Map = $Map @onready var marker: Marker = $Marker @onready var environment = $WorldEnvironment var player_id: int = -1 var item_names: Array = [] var item_index_by_name: Dictionary = {} var tile_names: Array = [] var tile_index_by_name: Dictionary = {} var tile_collide: Array = [] var tile_interact: Array = [] var marker_target = Vector3(0,0,0) var players := {} func _ready(): if !Global.on_vulkan(): environment.environment.tonemap_exposure = 0.5 environment.environment.sdfgi_enabled = Global.get_setting("sdfgi") mp.connection_closed.connect(func(reason: String): Global.error_message = reason; get_parent().replace_menu("res://menu/error.tscn") ) mp.init.connect(func(player_id_: int): player_id = player_id_) mp.data.connect(func( item_names_: Array, tile_names_: Array, tile_collide_: Array, tile_interact_: Array ): item_names = item_names_ tile_names = tile_names_ tile_collide = tile_collide_ tile_interact = tile_interact_ tile_index_by_name = {} for id in tile_names.size(): tile_index_by_name[tile_names[id]] = id item_index_by_name.clear() for i in range(item_names.size()): item_index_by_name[item_names[i]] = i ) await mp.init if player_id == -1: push_error("multiplayer has not been initialized") mp.add_player.connect(func(player: int, player_name: String, pos: Vector2, character: int): var player_instance: Player if player == player_id: player_instance = ControllablePlayer.new(player, player_name, pos, character, self) camera.target = player_instance else: player_instance = Player.new(player, player_name, pos, character, self) players[player] = player_instance add_child(player_instance) ) mp.set_tile.connect(set_tile) mp.remove_tile.connect(func (pos): map.clear_tile(pos)) mp.position.connect(func(player: int, pos: Vector2, rot: float): var player_instance: Player = players[player] player_instance.update_position(pos, rot) ) mp.remove_player.connect(func(id: int): var player: Player = players.get(id) if id == player_id: camera.target = self if player != null: if player.hand != null: player.hand.queue_free() players.erase(id) player.queue_free() ) mp.set_tile_item.connect(func(tile: Vector2i, item: int): var t: Tile = map.get_tile_instance(tile) var i = ItemFactory.produce(item_names[item], t.item_base) i.position = t.item_base.global_position add_child(i) i.name = item_names[item] t.set_item(i) ) mp.remove_tile_item.connect(func(tile: Vector2i): var t: Tile = map.get_tile_instance(tile) t.take_item().queue_free() ) mp.set_player_item.connect(func(player: int, item: int): var p: Player = players[player] var i = ItemFactory.produce(item_names[item], p.hand_base) add_child(i) i.name = item_names[item] p.set_item(i) ) mp.remove_player_item.connect(func(player: int): var p: Player = players[player] p.remove_item().queue_free() ) mp.take_item.connect(func(tile: Vector2i, player: int): var t: Tile = map.get_tile_instance(tile) var p: Player = players[player] p.take_item(t) ) mp.put_item.connect(func(tile: Vector2i, player: int): var t: Tile = map.get_tile_instance(tile) var p: Player = players[player] p.put_item(t) ) mp.set_progress.connect(func(tile: Vector2i, progress: float, warn: bool): var t: Tile = map.get_tile_instance(tile) t.progress(progress, warn) ) mp.set_finished.connect(func(tile: Vector2i, warn: bool): var t: Tile = map.get_tile_instance(tile) t.finish(warn) ) mp.text_message.connect(func(player: int, text: String, persist: bool): var p: Player = players[player] p.text_message(text, persist) ) mp.item_message.connect(func(player: int, item: int, persist: bool): var p: Player = players[player] p.item_message(item_names[item], persist) ) mp.effect_message.connect(func(player: int, effect: String, persist: bool): var p: Player = players[player] p.effect_message(effect, persist) ) mp.clear_message.connect(func(player: int): var p: Player = players[player] p.clear_message() ) mp.send_join(Global.profile["username"], Global.profile["character"]) mp.set_ingame.connect(func (state): if state: map.gi_bake() await get_parent().menu_anim_open() map.autobake = true else: map.autobake = false await get_parent().menu_anim_exit() ) mp.score.connect($Overlay.update) func _process(delta): marker.position = lerp(marker.position, marker_target, delta * 40.0) func get_tile_collision(pos: Vector2i) -> bool: var t = map.get_tile_name(pos) if t == null: return true else: return tile_collide[tile_index_by_name[t]] func get_tile_interactive(pos: Vector2i) -> bool: var t = map.get_tile_name(pos) if t == null: return false else: return tile_interact[tile_index_by_name[t]] func set_tile(tile: Vector2i, kind = null, neighbors = null): if neighbors != null: neighbors = neighbors.map(func (x): return tile_names[x] if x != null else null) map.set_tile(tile, tile_names[kind], neighbors)