diff --git a/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd b/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd index c25c50160..296ec4b10 100644 --- a/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd +++ b/addons/escoria-core/game/core-scripts/esc/types/esc_command_argument_descriptor.gd @@ -104,6 +104,7 @@ func validate(command: String, arguments: Array) -> bool: "Arguments didn't match minimum size {num}: Only {args} {verb} found." \ .format({"num":self.min_args,"args":required_args_count,"verb":verb}) ) + return false if arguments.size() > self.max_args and not has_varargs: escoria.logger.error( @@ -113,6 +114,7 @@ func validate(command: String, arguments: Array) -> bool: {"num":self.max_args,"args":arguments} ) ) + return false for index in range(arguments.size()): if arguments[index] == null: @@ -150,6 +152,7 @@ func validate(command: String, arguments: Array) -> bool: allowed_types ] ) + return false return true diff --git a/addons/escoria-core/game/esc_inputs_manager.gd b/addons/escoria-core/game/esc_inputs_manager.gd index b7f270842..ae34714e8 100644 --- a/addons/escoria-core/game/esc_inputs_manager.gd +++ b/addons/escoria-core/game/esc_inputs_manager.gd @@ -412,7 +412,7 @@ func _on_mouse_exited_item(item: ESCItem) -> void: if object and not object.interactive: return - if object and object.node is ESCPlayer and not (object.node as ESCPlayer).selectable: + if object and is_instance_valid(object.node) and object.node is ESCPlayer and not (object.node as ESCPlayer).selectable: hotspot_focused = "" return diff --git a/addons/escoria-core/game/esc_logger.gd b/addons/escoria-core/game/esc_logger.gd index 87fce9c2e..808b93215 100644 --- a/addons/escoria-core/game/esc_logger.gd +++ b/addons/escoria-core/game/esc_logger.gd @@ -1,6 +1,9 @@ class ESCLoggerBase: # Perform emergency savegame signal perform_emergency_savegame + + # Sends the error or warning message in the signal + signal error_message(message) # Valid log levels enum { LOG_ERROR, LOG_WARNING, LOG_INFO, LOG_DEBUG, LOG_TRACE } @@ -20,12 +23,17 @@ class ESCLoggerBase: # Configured log level var _log_level: int + # If true, assert() functions will not be called, thus the program won't exit or error. + # Resets to false after an assert() call was ignored once. + var dont_assert: bool = false + # Constructor func _init(): _log_level = _level_map[ESCProjectSettingsManager.get_setting( ESCProjectSettingsManager.LOG_LEVEL ).to_upper()] + func formatted_message(context: String, msg: String, letter: String) -> String: @@ -72,8 +80,11 @@ class ESCLoggerBase: if ESCProjectSettingsManager.get_setting( ESCProjectSettingsManager.TERMINATE_ON_WARNINGS ): - assert(false) - escoria.get_tree().quit() + if not dont_assert: + assert(false) + escoria.get_tree().quit() + dont_assert = false + emit_signal("error_message", msg) # Error log @@ -88,9 +99,11 @@ class ESCLoggerBase: if ESCProjectSettingsManager.get_setting( ESCProjectSettingsManager.TERMINATE_ON_ERRORS ): - assert(false) - escoria.get_tree().quit() - + if not dont_assert: + assert(false) + escoria.get_tree().quit() + dont_assert = false + emit_signal("error_message", msg) func get_log_level() -> int: return _log_level diff --git a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd index 096bc72b1..a87d1bbff 100644 --- a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd +++ b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.gd @@ -11,9 +11,31 @@ onready var command = $VBoxContainer/command # ESC commands kept around for references to their command names. var _print: PrintCommand +# History of typed commands +var commands_history: PoolStringArray +var commands_history_current_id: int +const COMMANDS_HISTORY_LENGTH: int = 20 + func _ready() -> void: _print = PrintCommand.new() + escoria.logger.connect("error_message", self, "_on_error_message") + + +func _input(event: InputEvent): + if event.is_pressed() and event is InputEventKey: + if (event as InputEventKey).scancode == KEY_UP and not commands_history.empty(): + commands_history_current_id -= 1 + if commands_history_current_id < 0: + commands_history_current_id = 0 + command.text = commands_history[commands_history_current_id] + command.call_deferred("grab_focus") + if (event as InputEventKey).scancode == KEY_DOWN and not commands_history.empty(): + commands_history_current_id += 1 + if commands_history_current_id > commands_history.size() - 1: + commands_history_current_id = commands_history.size() - 1 + command.text = commands_history[commands_history_current_id] + command.call_deferred("grab_focus") # Run a command @@ -29,23 +51,47 @@ func _on_command_text_entered(p_command_str : String): past_actions.text += "\n" past_actions.text += "# " + p_command_str past_actions.text += "\n" + + _historize_command(p_command_str) + + if p_command_str in ["history", "hist"]: + for ch in commands_history: + past_actions.text += ch + "\n" + return var errors = [] + escoria.logger.dont_assert = true var script = escoria.esc_compiler.compile([ - "%s%s" % [ESCEvent.PREFIX, _print.get_command_name()], - p_command_str - ], - get_class() + "%s%s" % [ESCEvent.PREFIX, _print.get_command_name()], + p_command_str + ], + get_class() ) if script: + escoria.logger.dont_assert = true escoria.event_manager.queue_event(script.events[escoria.event_manager.EVENT_PRINT]) var ret = yield(escoria.event_manager, "event_finished") while ret[1] != _print.get_command_name(): ret = yield(escoria.event_manager, "event_finished") past_actions.text += "Returned code: %d" % ret[0] + + past_actions.scroll_vertical = past_actions.get_line_count() # Set the focus to the command func _on_esc_prompt_popup_about_to_show(): command.grab_focus() + +func _on_error_message(message) -> void: + past_actions.text += message + "\n" + past_actions.scroll_vertical = past_actions.get_line_count() + + +func _historize_command(p_command: String) -> void: + commands_history_current_id += 1 + commands_history.append(p_command) + if commands_history.size() + 1 > COMMANDS_HISTORY_LENGTH: + commands_history.remove(0) + commands_history_current_id = COMMANDS_HISTORY_LENGTH - 1 + diff --git a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn index 6bc30c885..ded0af456 100644 --- a/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn +++ b/addons/escoria-core/game/scenes/esc_prompt/esc_prompt_popup.tscn @@ -24,18 +24,19 @@ __meta__ = { [node name="past_actions" type="TextEdit" parent="VBoxContainer"] margin_right = 599.0 -margin_bottom = 240.0 +margin_bottom = 340.0 size_flags_vertical = 3 +wrap_enabled = true [node name="HSeparator" type="HSeparator" parent="VBoxContainer"] -margin_top = 244.0 +margin_top = 344.0 margin_right = 599.0 -margin_bottom = 248.0 +margin_bottom = 348.0 [node name="command" type="LineEdit" parent="VBoxContainer"] -margin_top = 252.0 +margin_top = 352.0 margin_right = 599.0 -margin_bottom = 276.0 +margin_bottom = 376.0 caret_blink = true [connection signal="about_to_show" from="." to="." method="_on_esc_prompt_popup_about_to_show"]