-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5979e38
Showing
10 changed files
with
584 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Normalize EOL for all files that Git considers text files. | ||
* text=auto eol=lf | ||
|
||
/.gitattributes export-ignore | ||
/.gitignore export-ignore | ||
/README.md export-ignore | ||
/LICENSE.md export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Godot auto generated files | ||
*.import |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# MIT License | ||
|
||
Copyright (c) 2020-2022 Mansur Isaev and contributors | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# Godot-Console | ||
|
||
Simple in-game console for Godot 4.0. | ||
|
||
![](https://user-images.githubusercontent.com/8208165/144989905-6d3eb45d-26e7-4acd-9a53-c31d7e49c400.png) | ||
|
||
# Features | ||
|
||
- Installed as plugin. | ||
- The Console is Singleton. | ||
- History of entered commands. | ||
- Autocomplete commands. | ||
- Static typing. | ||
|
||
# Installation: | ||
|
||
1. Clone this repository to `addons` folder. | ||
2. Enabled `Godot Console` in Plugins. | ||
3. Add `ConsoleContainer` node to the scene. | ||
4. Profit. | ||
|
||
# Usage: | ||
|
||
## Create console command: | ||
|
||
```gdscript | ||
# player.gd | ||
func teleport(x: float, y: float) -> void: | ||
self.position = Vector2(x, y) | ||
func _ready() -> void: | ||
Console.create_command("tp", self.teleport, "Teleport the player.") | ||
``` | ||
|
||
## Static typing: | ||
|
||
With static typing, Console will try to cast arguments to a supported type. | ||
```gdscript | ||
# Arguments is float. | ||
func teleport(x: float, y: float) -> void: | ||
self.position = Vector2(x, y) | ||
``` | ||
|
||
## Dynamic typing: | ||
|
||
With dynamic typing, Console will NOT cast arguments to type, and arguments will be a String. | ||
```gdscript | ||
# Arguments is Strings. | ||
func teleport(x, y): | ||
# Convert arguments to float. | ||
self.position = Vector2(x.to_float(), y.to_float()) | ||
``` | ||
|
||
## Optional return string for print result to the console. | ||
|
||
```gdscript | ||
func add_money(value: int) -> String: | ||
self.money += value | ||
# Prints: Player money:42 | ||
return "Player money:%d" % money | ||
``` | ||
|
||
# License | ||
|
||
Copyright (c) 2020-2022 Mansur Isaev and contributors | ||
|
||
Unless otherwise specified, files in this repository are licensed under the | ||
MIT license. See [LICENSE.md](LICENSE.md) for more information. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
[plugin] | ||
|
||
name="Godot Console" | ||
description="in-Game Console." | ||
author="Mansur Isaev" | ||
version="1.0" | ||
script="plugin.gd" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Copyright (c) 2020-2022 Mansur Isaev and contributors - MIT License | ||
# See `LICENSE.md` included in the source distribution for details. | ||
|
||
@tool | ||
extends EditorPlugin | ||
|
||
|
||
const AUTOLOAD_NAME = "Console" | ||
const AUTOLOAD_PATH = "res://addons/godot-console/scripts/console.gd" | ||
|
||
const CONSOLE_CONTAINER = "ConsoleContainer" | ||
const CONSOLE_CONTAINER_SCRIPT = "res://addons/godot-console/scripts/console_container.gd" | ||
const CONSOLE_CONTAINER_ICON = "res://addons/godot-console/icons/console_container.svg" | ||
|
||
|
||
func _enter_tree() -> void: | ||
add_autoload_singleton(AUTOLOAD_NAME, AUTOLOAD_PATH) | ||
add_custom_type(CONSOLE_CONTAINER, "VBoxContainer", load(CONSOLE_CONTAINER_SCRIPT), load(CONSOLE_CONTAINER_ICON)) | ||
|
||
|
||
func _exit_tree() -> void: | ||
remove_custom_type(CONSOLE_CONTAINER) | ||
remove_autoload_singleton(AUTOLOAD_NAME) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
# Copyright (c) 2020-2022 Mansur Isaev and contributors - MIT License | ||
# See `LICENSE.md` included in the source distribution for details. | ||
|
||
## ConsoleNode class. | ||
## | ||
## By default used as a Singleton. To create a new console command, use [method create_command]. | ||
class_name ConsoleNode | ||
extends Node | ||
|
||
## Emitted when the console prints a string. | ||
signal printed_line(string: String) | ||
## Emitted when the console history is cleared. | ||
signal cleared() | ||
|
||
|
||
var _command_map : Dictionary | ||
var _command_list : PackedStringArray | ||
|
||
var _history : PackedStringArray | ||
var _history_index : int | ||
|
||
|
||
func _init() -> void: | ||
# Built-in methods: | ||
create_command("target_fps", Engine.set_target_fps, "The desired frames per second. A value of 0 means no limit.") | ||
create_command("physics_ticks", Engine.set_physics_ticks_per_second, "Set physic tick per second.") | ||
# Custom methods: | ||
create_command("clear", clear, "Clear the console history.") | ||
create_command("help", _command_help, "Show all console command.") | ||
create_command("version", _command_version, "Show engine version.") | ||
create_command("test", _command_test, "Test console output.") | ||
create_command("quit", _command_quit, "Quit the application.") | ||
|
||
## Return [param true] if the console has a command. | ||
func has_command(command: String) -> bool: | ||
return _command_map.has(command) | ||
|
||
## Return [param true] if command name is valid. | ||
func is_valid_name(command: String) -> bool: | ||
return command.is_valid_identifier() | ||
|
||
## Add a command to the console. | ||
## Can be used to directly add a custom command. | ||
func add_command(command: ConsoleCommand) -> void: | ||
assert(is_instance_valid(command) and command.is_valid(), "Invalid command.") | ||
assert(not has_command(command.get_name()), "Has command.") | ||
|
||
if is_instance_valid(command) and command.is_valid() and not has_command(command.get_name()): | ||
_command_map[command.get_name()] = command | ||
_command_list.clear() # Clear for lazy initialization. | ||
|
||
## Remove a command from the console. | ||
func remove_command(command: String) -> bool: | ||
if _command_map.erase(command): | ||
_command_list.clear() | ||
return true | ||
|
||
return false | ||
|
||
## Return command. | ||
func get_command(command: String) -> ConsoleCommand: | ||
return _command_map[command] as ConsoleCommand | ||
|
||
## Create and add a new console command. | ||
func create_command(command: String, callable: Callable, description := "") -> void: | ||
assert(not has_command(command), "Has command.") | ||
assert(is_valid_name(command), "Invalid command name.") | ||
assert(callable.is_valid(), "Invalid callable.") | ||
|
||
if not has_command(command) and is_valid_name(command) and callable.is_valid(): | ||
self.add_command(ConsoleCommand.new(command, callable, description)) | ||
|
||
## Print string to the console. | ||
func print_line(string: String) -> void: | ||
printed_line.emit(string + "\n") | ||
|
||
## Execute command. First word must be a command name, other is arguments. | ||
func execute(string: String) -> void: | ||
var args : PackedStringArray = string.split(" ", false) | ||
if args.is_empty(): | ||
return | ||
|
||
_history.push_back(string) | ||
_history_index = _history.size() | ||
|
||
print_line("[color=GRAY]> " + string + "[/color]") | ||
|
||
if not has_command(args[0]): | ||
return print_line("[color=RED]Command \"" + string + "\" not found.[/color]") | ||
|
||
var command := get_command(args[0]) | ||
|
||
assert(is_instance_valid(command), "Invalid ConsoleCommand.") | ||
if not is_instance_valid(command): | ||
return | ||
|
||
args.remove_at(0) # Remove name from arguments. | ||
|
||
var result : String = command.execute(args) | ||
if result: | ||
print_line(result) | ||
|
||
## Return the previously entered command. | ||
func get_prev_command() -> String: | ||
_history_index = wrapi(_history_index - 1, 0, _history.size()) | ||
return "" if _history.is_empty() else _history[_history_index] | ||
|
||
## Return the next entered command. | ||
func get_next_command() -> String: | ||
_history_index = wrapi(_history_index + 1, 0, _history.size()) | ||
return "" if _history.is_empty() else _history[_history_index] | ||
|
||
## Return a list of all commands. | ||
func get_command_list() -> PackedStringArray: | ||
if _command_list.is_empty(): # Lazy initialization. | ||
_command_list = _command_map.keys() | ||
_command_list.sort() | ||
|
||
return _command_list | ||
|
||
## Return autocomplete command. | ||
func autocomplete_command(string: String) -> String: | ||
if string.is_empty(): | ||
return string | ||
|
||
for command in get_command_list(): | ||
if command.begins_with(string): | ||
return command | ||
|
||
return string | ||
|
||
## Return a list of autocomplete commands. | ||
func autocomplete_list(string: String) -> PackedStringArray: | ||
var list := PackedStringArray() | ||
if string.is_empty(): | ||
return list | ||
|
||
for command in get_command_list(): | ||
if command.begins_with(string): | ||
list.push_back(command) | ||
|
||
return list | ||
|
||
## Clear the console history. | ||
func clear() -> void: | ||
_history.clear() | ||
_history_index = 0 | ||
|
||
cleared.emit() | ||
|
||
|
||
func _command_help() -> void: | ||
for i in get_command_list(): | ||
print_line(i + "- " + get_command(i).get_description()) | ||
|
||
|
||
func _command_version() -> String: | ||
return "Godot Engine {major}.{minor}.{patch}".format(Engine.get_version_info()) | ||
|
||
|
||
func _command_test() -> String: | ||
return "The quick brown fox jumps over the lazy dog." | ||
|
||
|
||
func _command_quit() -> void: | ||
get_tree().quit() |
Oops, something went wrong.