# Hurry Curry! - a game about cooking # Copyright 2024 tpart # Copyright 2024 nokoe # # 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 . # extends MarginContainer class_name PopupMessage var is_ingame := false var is_joined := false @onready var server_msg = $VBox/ServerMessage @onready var server_msg_positional = $ServerMessagePositional @onready var hint_msg = $VBox/HintMessage @onready var server_msg_timer: Timer = $ServerTimer @onready var hint_msg_timer: Timer = $HintTimer @onready var server_msg_label: Label = $VBox/ServerMessage/CenterContainer/Label @onready var server_msg_positional_label: Label = $ServerMessagePositional/ServerMessage/CenterContainer/Label @onready var hint_msg_label: Label = $VBox/HintMessage/CenterContainer/Label @onready var server_msg_positional_panel: PanelContainer = $ServerMessagePositional/ServerMessage @onready var auto_hint_timers: Node = $AutoHintTimers @onready var reset_timer = $Reset @onready var join_while_running_timer = $JoinWhileRunning @onready var game: Game = $"../Game" var server_message_position := Vector2.ZERO var last_server_message_panel_size := Vector2.ZERO func _ready(): game.joined.connect( func player_joined(): is_joined = true update_state() ) game.left.connect( func player_joined(): is_joined = false update_state() ) game.update_tutorial_running.connect( func a(running: bool): if running: stop_game_hints() else: update_state() ) func _process(_delta: float): if server_msg_positional.visible: var pos_3d = Vector3(server_message_position.x + 0.5, 1.5, server_message_position.y + 0.5) var pos_2d = get_viewport().get_camera_3d().unproject_position(pos_3d) var server_message_panel_size = server_msg_positional_panel.size server_msg_positional.position = pos_2d.clamp(Vector2.ZERO + 0.5 * server_message_panel_size, Vector2(get_viewport_rect().size) - 0.5 * server_message_panel_size) if server_message_panel_size != last_server_message_panel_size: last_server_message_panel_size = server_message_panel_size server_msg_positional_panel.position = -0.5 * last_server_message_panel_size func ingame(): is_ingame = true update_state() func lobby(): is_ingame = false update_state() func update_state(): if is_ingame and is_joined: start_game_hints() elif is_ingame: stop_game_hints() join_while_running_timer.start() else: stop_game_hints() func display_server_msg(msg: String, auto_remove := true): clear_server_msg() server_msg.show() server_msg_label.text = msg if auto_remove: server_msg_timer.start() func display_server_msg_positional(msg: String, pos: Vector2, auto_remove := true): clear_server_msg() server_msg_positional.show() server_message_position = pos server_msg_positional_label.text = msg server_msg_positional_panel.size = Vector2.ZERO if auto_remove: server_msg_timer.start() func clear_server_msg(): server_msg_timer.stop() server_msg.hide() server_msg_positional.hide() func _on_server_timer_timeout(): clear_server_msg() func display_hint_msg(msg: String): hint_msg.show() hint_msg_label.text = msg hint_msg_timer.start() func _on_hint_timer_timeout(): hint_msg.hide() func start_game_hints(): for c: Timer in auto_hint_timers.get_children(): c.start() func stop_game_hints(): _on_hint_timer_timeout() for c: Timer in auto_hint_timers.get_children(): c.stop() reset_timer.stop() join_while_running_timer.stop() func _input(_event): if Input.is_action_just_pressed("boost"): Global.set_hint("has_boosted", true) if any_action_just_pressed(["forwards", "backwards", "left", "right"]): Global.set_hint("has_moved", true) if any_action_just_pressed(["rotate_left", "rotate_right", "rotate_up", "rotate_down"]): if not Global.get_hint("has_reset"): reset_timer.start() Global.set_hint("has_rotated", true) if any_action_just_pressed(["zoom_in", "zoom_out"]): Global.set_hint("has_zoomed", true) if Input.is_action_just_pressed("interact"): Global.set_hint("has_interacted", true) if Input.is_action_just_pressed("reset"): Global.set_hint("has_reset", true) func _on_boost_timeout(): if not Global.get_hint("has_boosted") and not Global.using_touch: display_hint_msg(tr("c.hint.boost").format([display_keybind("boost")])) func _on_move_timeout(): if not Global.get_hint("has_moved") and not Global.using_touch: display_hint_msg(tr("c.hint.movement").format([", ".join( [ display_keybind("forwards"), display_keybind("left"), display_keybind("backwards"), display_keybind("right") ] )])) func _on_interact_timeout(): if not Global.get_hint("has_interacted") and not Global.using_touch: display_hint_msg(tr("c.hint.interact").format([display_keybind("interact")])) func _on_reset_timeout(): if not Global.get_hint("has_reset") and not Global.using_touch: display_hint_msg(tr("c.hint.reset_camera").format([display_keybind("reset")])) func _on_zoom_timeout(): if not Global.get_hint("has_zoomed") and not Global.using_touch: display_hint_msg(tr("c.hint.zoom_camera").format([", ".join( [ display_keybind("zoom_in"), display_keybind("zoom_out") ] )])) func display_keybind(action_name: String) -> String: var events := InputManager.get_events(action_name) if events.size() == 0: # There are no events which match the action return tr("c.settings.input.unknown_event") for event: InputEvent in events: # Try to find event which matches input method var type := InputManager.get_event_type(event) if Global.using_joypad and type != InputManager.EventType.JOYPAD: continue if Global.using_touch and type != InputManager.EventType.TOUCH: continue return InputManager.display_input_event(event) # No matching event found. Just show any event. return InputManager.display_input_event(events[0]) func any_action_just_pressed(actions: Array) -> bool: for a: String in actions: if Input.is_action_just_pressed(a): return true return false func _on_rotate_camera_timeout(): if not Global.get_hint("has_rotated") and not Global.using_touch: display_hint_msg(tr("c.hint.rotate").format([", ".join( [ display_keybind("rotate_up"), display_keybind("rotate_left"), display_keybind("rotate_down"), display_keybind("rotate_right") ] )])) func _on_join_while_running_timeout(): if not game.is_joined and not Global.get_hint("has_seen_join_while_running"): Global.set_hint("has_seen_join_while_running", true) display_hint_msg(tr("c.hint.join_while_running").format([display_keybind("menu")])) func _on_performance_timeout() -> void: if not Global.get_hint("has_seen_performance") and Engine.get_frames_per_second() < DisplayServer.screen_get_refresh_rate() * 0.75: Global.set_hint("has_seen_performance", true) display_hint_msg(tr("c.hint.framerate_low"))