first commit
This commit is contained in:
commit
263a787c14
56 changed files with 84620 additions and 0 deletions
2
.gitattributes
vendored
Normal file
2
.gitattributes
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
/android/
|
||||
node_modules/
|
||||
*.js
|
||||
**/*.js
|
43
addons/dev_console/autocomplete_line.ts
Normal file
43
addons/dev_console/autocomplete_line.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import { Callable, Callable1, LineEdit, Variant } from 'godot'
|
||||
import { export_, onready } from 'godot.annotations'
|
||||
|
||||
export default class AutocompleteLine extends LineEdit {
|
||||
@export_(Variant.Type.TYPE_BOOL)
|
||||
private auto_suggest: boolean = true
|
||||
|
||||
@onready("SuggestionLine")
|
||||
private suggestion!: LineEdit
|
||||
|
||||
autocomplete_list: string[] = []
|
||||
last_autocomplete: number = -1
|
||||
|
||||
_on_text_changed!: Callable1<string>
|
||||
|
||||
_ready(): void {
|
||||
this._on_text_changed = Callable.create(this, this.suggest)
|
||||
|
||||
if (this.auto_suggest) {
|
||||
this.text_changed.connect(this._on_text_changed)
|
||||
}
|
||||
}
|
||||
|
||||
suggest(value: string): boolean {
|
||||
const item = this.fuzzy_find(value)
|
||||
|
||||
if (item > -1) {
|
||||
this.suggestion.text = this.autocomplete_list[item]
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
autocomplete(value?: string) {
|
||||
this.text = value || this.suggestion.text
|
||||
this.suggestion.clear()
|
||||
}
|
||||
|
||||
fuzzy_find(value: string): number {
|
||||
return this.autocomplete_list.findIndex(text => text.startsWith(value))
|
||||
}
|
||||
}
|
62
addons/dev_console/console.tscn
Normal file
62
addons/dev_console/console.tscn
Normal file
|
@ -0,0 +1,62 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://b8xytvsmqsf55"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/dev_console/dev_console.ts" id="1_3ukun"]
|
||||
[ext_resource type="Script" path="res://addons/dev_console/autocomplete_line.ts" id="2_fq41p"]
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer"]
|
||||
script = ExtResource("1_3ukun")
|
||||
|
||||
[node name="Container" type="Control" parent="."]
|
||||
custom_minimum_size = Vector2(0, 250)
|
||||
layout_mode = 3
|
||||
anchors_preset = 10
|
||||
anchor_right = 1.0
|
||||
grow_horizontal = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="Container"]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0.784314)
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="Container"]
|
||||
layout_mode = 1
|
||||
anchors_preset = -1
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
pivot_offset = Vector2(0, 250)
|
||||
|
||||
[node name="Output" type="RichTextLabel" parent="Container/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
focus_mode = 2
|
||||
fit_content = true
|
||||
scroll_following = true
|
||||
context_menu_enabled = true
|
||||
threaded = true
|
||||
selection_enabled = true
|
||||
|
||||
[node name="Input" type="LineEdit" parent="Container/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
caret_blink = true
|
||||
script = ExtResource("2_fq41p")
|
||||
|
||||
[node name="Input2" type="LineEdit" parent="Container/VBoxContainer/Input"]
|
||||
layout_mode = 2
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 31.0
|
||||
editable = false
|
||||
context_menu_enabled = false
|
||||
virtual_keyboard_enabled = false
|
||||
shortcut_keys_enabled = false
|
||||
middle_mouse_paste_enabled = false
|
||||
selecting_enabled = false
|
||||
deselect_on_focus_loss_enabled = false
|
||||
drag_and_drop_selection_enabled = false
|
143
addons/dev_console/dev_console.ts
Normal file
143
addons/dev_console/dev_console.ts
Normal file
|
@ -0,0 +1,143 @@
|
|||
import { Callable, Callable1, CanvasLayer, Expression, GArray, GDictionary, GError, InputEvent, LineEdit, RichTextLabel } from 'godot'
|
||||
import { onready } from 'godot.annotations'
|
||||
import AutocompleteLine from './autocomplete_line'
|
||||
|
||||
const Action = {
|
||||
Toggle: '_dev_console_toggle',
|
||||
Cancel: 'ui_cancel',
|
||||
Up: 'ui_up',
|
||||
Down: 'ui_down',
|
||||
TextComplete: 'ui_text_completion_replace'
|
||||
} as const
|
||||
|
||||
export default class DevConsole extends CanvasLayer {
|
||||
|
||||
@onready("Container/VBoxContainer/Output")
|
||||
private output!: RichTextLabel
|
||||
|
||||
@onready("Container/VBoxContainer/Input")
|
||||
private input!: AutocompleteLine
|
||||
|
||||
private history: string[] = []
|
||||
private expression = new Expression()
|
||||
private parse_callable!: Callable1<string>
|
||||
private history_index: number = -1
|
||||
|
||||
_ready(): void {
|
||||
this._toggle()
|
||||
const method_names = this.get_method_list().map(Callable.create((x: GDictionary) => x.get('name')))
|
||||
this.input.autocomplete_list = method_names
|
||||
this.parse_callable = Callable.create(
|
||||
this,
|
||||
this.submit_command
|
||||
)
|
||||
}
|
||||
|
||||
_input(event: InputEvent): void {
|
||||
|
||||
if (event.is_action_pressed(Action.Toggle)) {
|
||||
this._toggle()
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.visible) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.is_action_pressed(Action.Cancel)) {
|
||||
this._cancel()
|
||||
} else if (event.is_action_pressed(Action.Up)) {
|
||||
this._previous_command()
|
||||
} else if (event.is_action_pressed(Action.TextComplete)) {
|
||||
//this._try_autocomplete()
|
||||
}
|
||||
}
|
||||
|
||||
_reset() {
|
||||
this.history_index = -1
|
||||
}
|
||||
|
||||
_cancel() {
|
||||
this._reset()
|
||||
|
||||
if (this.input.has_focus()) {
|
||||
this.input.release_focus()
|
||||
} else {
|
||||
this._hide()
|
||||
}
|
||||
}
|
||||
|
||||
_previous_command() {
|
||||
if (this.history_index < 0) {
|
||||
this.history_index = this.history.length
|
||||
}
|
||||
|
||||
this.history_index -= 1
|
||||
this.input.text = this.history[this.history_index]
|
||||
}
|
||||
|
||||
async _show() {
|
||||
await this.get_tree().process_frame.as_promise()
|
||||
|
||||
this.input.text_submitted.connect(this.parse_callable)
|
||||
this.input.grab_focus()
|
||||
}
|
||||
|
||||
_hide() {
|
||||
this.input.text_submitted.disconnect(this.parse_callable)
|
||||
this.input.release_focus()
|
||||
}
|
||||
|
||||
async _toggle() {
|
||||
this._reset()
|
||||
|
||||
this.visible = !this.visible
|
||||
|
||||
if (this.visible) {
|
||||
this._show()
|
||||
} else {
|
||||
this._hide()
|
||||
}
|
||||
}
|
||||
|
||||
print(value: string) {
|
||||
this.output.append_text(value)
|
||||
this.output.append_text('\n')
|
||||
}
|
||||
|
||||
wrap_in_tag(text: string, tag: [string, string]): string {
|
||||
return `[${tag[0]}=${tag[1]}]${text}[/${tag[0]}]`
|
||||
}
|
||||
|
||||
format(text: string, tags: Record<string, string>): string {
|
||||
return Object.entries(tags).reduce(this.wrap_in_tag, text)
|
||||
}
|
||||
|
||||
print_error(error: string) {
|
||||
this.print(this.format(error, { color: 'red' }))
|
||||
}
|
||||
|
||||
echo(command: string) {
|
||||
this.print(this.format(`> ${command}`, { color: 'white' }))
|
||||
}
|
||||
|
||||
submit_command(command: string) {
|
||||
this.input.clear()
|
||||
this.history.push(command)
|
||||
this.echo(command)
|
||||
const error = this.expression.parse(command)
|
||||
|
||||
if (error !== GError.OK) {
|
||||
this.print_error(this.expression.get_error_text())
|
||||
return
|
||||
}
|
||||
|
||||
const result = this.expression.execute(new GArray(), this)
|
||||
|
||||
if (this.expression.has_execute_failed()) {
|
||||
this.print_error(this.expression.get_error_text())
|
||||
} else {
|
||||
this.print(result.toString())
|
||||
}
|
||||
}
|
||||
}
|
10
addons/dev_console/output_line.tscn
Normal file
10
addons/dev_console/output_line.tscn
Normal file
|
@ -0,0 +1,10 @@
|
|||
[gd_scene format=3 uid="uid://b681p7bhdvmv0"]
|
||||
|
||||
[node name="OutputLine" type="RichTextLabel"]
|
||||
anchors_preset = 12
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
fit_content = true
|
BIN
assets/level.glb
Normal file
BIN
assets/level.glb
Normal file
Binary file not shown.
36
assets/level.glb.import
Normal file
36
assets/level.glb.import
Normal file
|
@ -0,0 +1,36 @@
|
|||
[remap]
|
||||
|
||||
importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://cwrgvwx3lfwf6"
|
||||
path="res://.godot/imported/level.glb-dadcc56a2e5f0c7946f5dd2ed4295803.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/level.glb"
|
||||
dest_files=["res://.godot/imported/level.glb-dadcc56a2e5f0c7946f5dd2ed4295803.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
nodes/root_type=""
|
||||
nodes/root_name=""
|
||||
nodes/apply_root_scale=true
|
||||
nodes/root_scale=1.0
|
||||
nodes/import_as_skeleton_bones=false
|
||||
meshes/ensure_tangents=true
|
||||
meshes/generate_lods=true
|
||||
meshes/create_shadow_meshes=true
|
||||
meshes/light_baking=1
|
||||
meshes/lightmap_texel_size=0.2
|
||||
meshes/force_disable_compression=false
|
||||
skins/use_named_skins=true
|
||||
animation/import=true
|
||||
animation/fps=30
|
||||
animation/trimming=false
|
||||
animation/remove_immutable_tracks=true
|
||||
animation/import_rest_as_RESET=false
|
||||
import_script/path=""
|
||||
_subresources={}
|
||||
gltf/naming_version=1
|
||||
gltf/embedded_image_handling=1
|
BIN
assets/player.glb
Normal file
BIN
assets/player.glb
Normal file
Binary file not shown.
5436
assets/player.glb.import
Normal file
5436
assets/player.glb.import
Normal file
File diff suppressed because it is too large
Load diff
1
icon.svg
Normal file
1
icon.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>
|
After Width: | Height: | Size: 994 B |
37
icon.svg.import
Normal file
37
icon.svg.import
Normal file
|
@ -0,0 +1,37 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bhk5p6mhm3vug"
|
||||
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.svg"
|
||||
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
44
package-lock.json
generated
Normal file
44
package-lock.json
generated
Normal file
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"name": "signalis",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.30",
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.17.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.32.tgz",
|
||||
"integrity": "sha512-zeMXFn8zQ+UkjK4ws0RiOC9EWByyW1CcVmLe+2rQocXRsGEDxUCwPEIVgpsGcLHS/P8JkT0oa3839BRABS0oPw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.8.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
|
||||
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.19.8",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
6
package.json
Normal file
6
package.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.30",
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
}
|
25
player.tscn
Normal file
25
player.tscn
Normal file
|
@ -0,0 +1,25 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://dg82oi74wjpen"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/player.ts" id="1_f7s2q"]
|
||||
[ext_resource type="PackedScene" uid="uid://cyfbte21rykqr" path="res://scenes/player_mesh.tscn" id="2_0bcjn"]
|
||||
[ext_resource type="Script" path="res://src/player_input.ts" id="3_mrw4e"]
|
||||
[ext_resource type="Script" path="res://src/player_animation.ts" id="4_64fm5"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_ruj8e"]
|
||||
|
||||
[node name="Player" type="CharacterBody3D"]
|
||||
script = ExtResource("1_f7s2q")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1.25, 0, 0, 0, 1.25, 0, 0, 0, 1.25, 0, 1.4, 0)
|
||||
shape = SubResource("CapsuleShape3D_ruj8e")
|
||||
|
||||
[node name="player" parent="." instance=ExtResource("2_0bcjn")]
|
||||
|
||||
[node name="Input" type="Node" parent="."]
|
||||
script = ExtResource("3_mrw4e")
|
||||
|
||||
[node name="Animation" type="Node" parent="."]
|
||||
script = ExtResource("4_64fm5")
|
||||
|
||||
[editable path="player"]
|
73
project.godot
Normal file
73
project.godot
Normal file
|
@ -0,0 +1,73 @@
|
|||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=5
|
||||
|
||||
[application]
|
||||
|
||||
config/name="signalis"
|
||||
run/main_scene="res://scenes/node_3d.tscn"
|
||||
config/features=PackedStringArray("4.3", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
||||
MessageBus="*res://src/message_bus.ts"
|
||||
DebugDraw="*res://src/debug_draw.ts"
|
||||
|
||||
[input]
|
||||
|
||||
move_left={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
move_right={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
move_up={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null)
|
||||
]
|
||||
}
|
||||
move_down={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null)
|
||||
]
|
||||
}
|
||||
interact={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
run={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":1,"pressure":0.0,"pressed":true,"script":null)
|
||||
]
|
||||
}
|
||||
_dev_console_submit={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
_dev_console_toggle={
|
||||
"deadzone": 0.5,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":96,"key_label":0,"unicode":96,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[layer_names]
|
||||
|
||||
3d_physics/layer_1="interactable"
|
44
scenes/node_3d.tscn
Normal file
44
scenes/node_3d.tscn
Normal file
|
@ -0,0 +1,44 @@
|
|||
[gd_scene load_steps=7 format=3 uid="uid://dl8pjf2esflbr"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cersx8w4ps2sr" path="res://scenes/player.tscn" id="1_uum5p"]
|
||||
[ext_resource type="PackedScene" uid="uid://cwrgvwx3lfwf6" path="res://assets/level.glb" id="2_i3oty"]
|
||||
[ext_resource type="Script" path="res://src/interactable.ts" id="3_dt0nx"]
|
||||
|
||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_y41n8"]
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_crnh0"]
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_y1mmm"]
|
||||
|
||||
[node name="Node3D" type="Node3D"]
|
||||
|
||||
[node name="level" parent="." instance=ExtResource("2_i3oty")]
|
||||
|
||||
[node name="StaticBody3D" type="StaticBody3D" parent="level"]
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="level/StaticBody3D"]
|
||||
shape = SubResource("WorldBoundaryShape3D_y41n8")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 8, 7)
|
||||
projection = 1
|
||||
size = 15.0
|
||||
far = 50.0
|
||||
|
||||
[node name="Player" parent="." instance=ExtResource("1_uum5p")]
|
||||
|
||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.707107, 0.707107, 0, -0.707107, 0.707107, 0, 9, 0)
|
||||
|
||||
[node name="Node3D" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -10, 1, 0)
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Node3D"]
|
||||
mesh = SubResource("BoxMesh_crnh0")
|
||||
|
||||
[node name="Interactable" type="Area3D" parent="Node3D"]
|
||||
monitoring = false
|
||||
script = ExtResource("3_dt0nx")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Node3D/Interactable"]
|
||||
shape = SubResource("BoxShape3D_y1mmm")
|
220
scenes/player.tscn
Normal file
220
scenes/player.tscn
Normal file
|
@ -0,0 +1,220 @@
|
|||
[gd_scene load_steps=17 format=3 uid="uid://cersx8w4ps2sr"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cyfbte21rykqr" path="res://scenes/player_mesh.tscn" id="2_0u3o5"]
|
||||
[ext_resource type="Script" path="res://src/player.ts" id="2_pdrhn"]
|
||||
[ext_resource type="Script" path="res://src/player_animation.ts" id="3_26yay"]
|
||||
[ext_resource type="Script" path="res://src/player_input.ts" id="3_x6527"]
|
||||
[ext_resource type="Script" path="res://src/interactor.ts" id="5_uk7c1"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1kx10"]
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_vilbe"]
|
||||
animation = &"Idle"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_d7cro"]
|
||||
animation = &"SlowRun"
|
||||
|
||||
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_w5ck1"]
|
||||
animation = &"Walking"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_twhp3"]
|
||||
advance_mode = 2
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_p6dv3"]
|
||||
xfade_time = 0.25
|
||||
reset = false
|
||||
switch_mode = 1
|
||||
advance_mode = 2
|
||||
advance_expression = "velocity"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_xh0w6"]
|
||||
xfade_time = 0.25
|
||||
reset = false
|
||||
switch_mode = 1
|
||||
advance_mode = 2
|
||||
advance_expression = "is_running()"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_vse2m"]
|
||||
xfade_time = 0.25
|
||||
reset = false
|
||||
switch_mode = 1
|
||||
advance_mode = 2
|
||||
advance_expression = "not is_running()"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_yh7m2"]
|
||||
xfade_time = 0.25
|
||||
reset = false
|
||||
switch_mode = 1
|
||||
advance_mode = 2
|
||||
advance_expression = "not velocity"
|
||||
|
||||
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_8s3qg"]
|
||||
states/Idle/node = SubResource("AnimationNodeAnimation_vilbe")
|
||||
states/Idle/position = Vector2(311, 100)
|
||||
states/SlowRun/node = SubResource("AnimationNodeAnimation_d7cro")
|
||||
states/SlowRun/position = Vector2(572, 100)
|
||||
states/Walking/node = SubResource("AnimationNodeAnimation_w5ck1")
|
||||
states/Walking/position = Vector2(434, 100)
|
||||
transitions = ["Start", "Idle", SubResource("AnimationNodeStateMachineTransition_twhp3"), "Idle", "Walking", SubResource("AnimationNodeStateMachineTransition_p6dv3"), "Walking", "SlowRun", SubResource("AnimationNodeStateMachineTransition_xh0w6"), "SlowRun", "Walking", SubResource("AnimationNodeStateMachineTransition_vse2m"), "Walking", "Idle", SubResource("AnimationNodeStateMachineTransition_yh7m2")]
|
||||
graph_offset = Vector2(155, -1)
|
||||
|
||||
[sub_resource type="SphereShape3D" id="SphereShape3D_64co4"]
|
||||
|
||||
[node name="Player" type="CharacterBody3D"]
|
||||
script = ExtResource("2_pdrhn")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1.25, 0, 0, 0, 1.25, 0, 0, 0, 1.25, 0, 1.25, 0)
|
||||
shape = SubResource("CapsuleShape3D_1kx10")
|
||||
|
||||
[node name="Mesh" parent="." instance=ExtResource("2_0u3o5")]
|
||||
|
||||
[node name="Skeleton3D" parent="Mesh/Armature" index="0"]
|
||||
bones/0/position = Vector3(0.00289948, 100.861, 1.26735)
|
||||
bones/0/rotation = Quaternion(-0.0244499, -0.0264677, -0.0879678, 0.995471)
|
||||
bones/1/position = Vector3(-1.08778e-06, 8.00974e-08, -5.45755e-07)
|
||||
bones/2/rotation = Quaternion(-0.109938, -0.0139449, 0.0898347, 0.989772)
|
||||
bones/3/position = Vector3(1.2666e-07, 1.38208e-06, 4.63426e-06)
|
||||
bones/4/rotation = Quaternion(0.018758, -0.00338616, 0.0225337, 0.999564)
|
||||
bones/5/position = Vector3(-8.19564e-07, -1.46851e-05, 4.30644e-06)
|
||||
bones/6/rotation = Quaternion(0.0319564, -0.00485405, 0.0217667, 0.99924)
|
||||
bones/7/position = Vector3(3.57632e-07, -2.42144e-05, -3.53158e-06)
|
||||
bones/8/rotation = Quaternion(-0.580392, 0.491768, -0.548909, -0.346422)
|
||||
bones/9/position = Vector3(1.93715e-07, -8.76188e-06, -1.82156e-05)
|
||||
bones/10/position = Vector3(-2.22259e-06, 10.8382, 6.657e-05)
|
||||
bones/10/rotation = Quaternion(0.45809, -0.121747, -0.0824416, 0.876661)
|
||||
bones/11/position = Vector3(1.66958e-06, -2.30764e-05, 5.90135e-07)
|
||||
bones/12/rotation = Quaternion(8.23363e-08, -4.68609e-08, -0.245739, 0.969336)
|
||||
bones/13/position = Vector3(7.10815e-06, 2.49848e-06, -3.67706e-07)
|
||||
bones/14/position = Vector3(1.00884e-05, 28.3289, 1.42043e-06)
|
||||
bones/14/rotation = Quaternion(0.014645, -0.137758, -0.00643952, 0.990337)
|
||||
bones/15/position = Vector3(1.43223e-06, -9.47448e-06, -3.04991e-06)
|
||||
bones/16/rotation = Quaternion(0.160255, 0.000143802, 0.0186451, 0.9869)
|
||||
bones/17/position = Vector3(2.78027e-07, -1.63051e-05, 2.7709e-07)
|
||||
bones/18/position = Vector3(-7.17311e-07, 3.6, -4.46059e-05)
|
||||
bones/18/rotation = Quaternion(0.155034, -1.66765e-07, 0.0188948, 0.987729)
|
||||
bones/19/position = Vector3(-1.09796e-06, -1.6639e-05, -1.30592e-05)
|
||||
bones/20/rotation = Quaternion(0.220887, 2.16033e-08, 0.0269202, 0.974928)
|
||||
bones/21/position = Vector3(-3.42208e-06, -3.57069e-06, -7.88492e-06)
|
||||
bones/22/position = Vector3(-2.66578e-06, 2.11579, -6.80612e-06)
|
||||
bones/23/position = Vector3(1.99676e-06, 2.3176e-06, 1.13522e-06)
|
||||
bones/24/position = Vector3(-2.81929e-05, 9.5325, 4.46934e-05)
|
||||
bones/24/rotation = Quaternion(0.14289, 0.00156384, 0.00648316, 0.989716)
|
||||
bones/25/position = Vector3(-2.64221e-06, 1.33002e-05, 9.27813e-06)
|
||||
bones/26/position = Vector3(-3.12982e-06, 3.70001, -1.88553e-05)
|
||||
bones/26/rotation = Quaternion(0.156567, -1.04364e-07, 0.0190816, 0.987483)
|
||||
bones/27/position = Vector3(4.8121e-06, -1.06792e-05, -1.50226e-05)
|
||||
bones/28/position = Vector3(3.86115e-06, 2.95001, -1.38305e-05)
|
||||
bones/28/rotation = Quaternion(0.271732, 0.0239403, 0.0400047, 0.961243)
|
||||
bones/31/position = Vector3(1.86637e-06, 5.9802e-06, -1.467e-05)
|
||||
bones/32/rotation = Quaternion(0.203925, 0.00114676, 0.0193327, 0.978795)
|
||||
bones/33/position = Vector3(-2.25109e-06, -9.16777e-06, 1.35742e-05)
|
||||
bones/34/position = Vector3(-1.61634e-06, 3.37927, -2.16157e-06)
|
||||
bones/34/rotation = Quaternion(0.123071, -4.23026e-08, 0.0149991, 0.992285)
|
||||
bones/36/position = Vector3(-1.34902e-06, 2.88968, 1.45266e-05)
|
||||
bones/36/rotation = Quaternion(0.193011, 0.101139, 0.0441025, 0.974973)
|
||||
bones/37/position = Vector3(7.45909e-07, -8.48482e-06, 1.51202e-05)
|
||||
bones/38/position = Vector3(-7.0702e-07, 2.63882, -1.46823e-05)
|
||||
bones/39/position = Vector3(-4.24683e-07, -3.16713e-06, -1.23643e-05)
|
||||
bones/40/position = Vector3(2.25983, 9.10828, 0.517866)
|
||||
bones/40/rotation = Quaternion(0.208794, -0.00164783, 0.0331266, 0.977397)
|
||||
bones/41/position = Vector3(5.8333e-07, 6.3235e-07, 1.57826e-05)
|
||||
bones/42/rotation = Quaternion(0.10675, -1.37934e-07, 0.0130101, 0.994201)
|
||||
bones/43/position = Vector3(-1.30539e-06, 1.28774e-05, 4.90486e-08)
|
||||
bones/44/rotation = Quaternion(0.181155, 2.82432e-08, 0.022078, 0.983207)
|
||||
bones/45/position = Vector3(-2.28086e-07, -1.45823e-06, -4.29744e-07)
|
||||
bones/48/position = Vector3(2.68185, 2.4648, 1.57399)
|
||||
bones/48/rotation = Quaternion(0.123855, 0.0615792, -0.158218, 0.977668)
|
||||
bones/49/position = Vector3(-3.57628e-06, -1.16825e-05, 6.73833e-06)
|
||||
bones/50/position = Vector3(-7.17277e-06, 4.18897, 1.07578e-06)
|
||||
bones/50/rotation = Quaternion(-0.0658568, 0.0352429, 0.20427, 0.976061)
|
||||
bones/52/position = Vector3(-8.77766e-06, 3.41628, -4.79003e-06)
|
||||
bones/52/rotation = Quaternion(0.020006, -0.00218171, -0.0319489, 0.999287)
|
||||
bones/53/position = Vector3(-3.03984e-06, 2.01762e-05, -1.93187e-06)
|
||||
bones/56/rotation = Quaternion(0.0426809, 0.00409768, -0.0515628, 0.997749)
|
||||
bones/57/position = Vector3(1.19211e-07, -2.28947e-05, -3.36394e-06)
|
||||
bones/58/rotation = Quaternion(-0.0950997, -0.0140778, 0.00690302, 0.995344)
|
||||
bones/59/position = Vector3(-1.0431e-07, -1.54506e-05, -1.49384e-06)
|
||||
bones/61/rotation = Quaternion(0.580092, 0.493797, -0.538984, 0.35938)
|
||||
bones/62/position = Vector3(5.96046e-08, -6.10948e-07, -7.88433e-06)
|
||||
bones/63/position = Vector3(3.42725e-07, 10.8377, 3.26269e-05)
|
||||
bones/63/rotation = Quaternion(0.575548, 0.0681971, 0.0612369, 0.812616)
|
||||
bones/64/position = Vector3(2.4772e-06, 1.24322e-06, 3.17702e-06)
|
||||
bones/65/position = Vector3(7.81477e-06, 27.8415, 3.26074e-05)
|
||||
bones/65/rotation = Quaternion(1.45869e-07, -1.74771e-07, 0.187347, 0.982294)
|
||||
bones/66/position = Vector3(-3.25318e-06, -4.67625e-06, -1.50252e-06)
|
||||
bones/67/rotation = Quaternion(0.0649669, 0.17139, 0.0446918, 0.982042)
|
||||
bones/68/position = Vector3(7.47968e-08, -6.91227e-07, -2.51579e-06)
|
||||
bones/69/rotation = Quaternion(0.124716, -0.0706003, 0.12224, 0.982099)
|
||||
bones/70/position = Vector3(1.18017e-05, 1.18017e-05, 1.03254e-05)
|
||||
bones/71/position = Vector3(-7.12144e-07, 4.18709, 2.40078e-06)
|
||||
bones/71/rotation = Quaternion(-0.0113373, 0.00316211, -0.0953233, 0.995377)
|
||||
bones/72/position = Vector3(5.48363e-06, -9.44734e-06, -1.48937e-05)
|
||||
bones/73/position = Vector3(-6.19066e-06, 3.41839, -3.25305e-05)
|
||||
bones/73/rotation = Quaternion(-0.0550551, -0.0920655, -0.0310965, 0.993743)
|
||||
bones/74/position = Vector3(3.75509e-06, 1.69277e-05, 9.12723e-07)
|
||||
bones/75/position = Vector3(2.59013e-06, 2.5806, 1.43079e-06)
|
||||
bones/77/rotation = Quaternion(0.137069, -0.00188298, -0.00277138, 0.990556)
|
||||
bones/78/position = Vector3(2.34035e-07, 6.61208e-07, -1.22018e-06)
|
||||
bones/79/position = Vector3(-2.66701e-07, 3.7, -4.303e-07)
|
||||
bones/79/rotation = Quaternion(0.166772, -2.34506e-07, -0.0201262, 0.98579)
|
||||
bones/80/position = Vector3(-3.04282e-06, -2.24161e-06, -1.52532e-05)
|
||||
bones/81/rotation = Quaternion(0.22072, -2.87607e-07, -0.0266367, 0.974973)
|
||||
bones/84/position = Vector3(-1.56742e-06, -5.37828e-06, 1.60567e-05)
|
||||
bones/85/rotation = Quaternion(0.0854835, -0.000807518, -0.000812654, 0.996339)
|
||||
bones/86/position = Vector3(-2.09158e-07, 7.10476e-06, -1.37234e-05)
|
||||
bones/87/rotation = Quaternion(0.174826, -2.14469e-07, -0.021098, 0.984373)
|
||||
bones/88/position = Vector3(-1.44259e-06, -2.81852e-06, -1.08586e-06)
|
||||
bones/89/rotation = Quaternion(0.217704, -3.39905e-07, -0.0262725, 0.975661)
|
||||
bones/90/position = Vector3(-1.67251e-06, -5.69229e-06, 4.16067e-06)
|
||||
bones/92/position = Vector3(-2.07638e-06, -8.50701e-06, 1.83102e-06)
|
||||
bones/93/rotation = Quaternion(0.143233, -0.000851651, -0.0113733, 0.989623)
|
||||
bones/94/position = Vector3(-1.24702e-06, -4.42364e-06, 5.52884e-07)
|
||||
bones/95/rotation = Quaternion(0.17102, -2.88582e-07, -0.0206387, 0.985051)
|
||||
bones/96/position = Vector3(-2.19045e-06, -7.68091e-06, -2.55365e-06)
|
||||
bones/97/position = Vector3(1.62425e-06, 2.95, 1.38972e-05)
|
||||
bones/97/rotation = Quaternion(0.260024, -3.83975e-07, -0.0313798, 0.965092)
|
||||
bones/98/position = Vector3(-2.69965e-06, -1.43062e-07, 1.26105e-06)
|
||||
bones/99/position = Vector3(-2.845e-05, 2.64431, 1.98053e-06)
|
||||
bones/100/position = Vector3(6.57979e-07, -4.74934e-06, 1.44472e-05)
|
||||
bones/101/position = Vector3(3.80627, 8.07779, 0.486894)
|
||||
bones/101/rotation = Quaternion(0.149406, 0.00473882, -0.0485855, 0.98757)
|
||||
bones/102/position = Vector3(-2.33662e-06, 1.08604e-05, 1.6658e-05)
|
||||
bones/103/rotation = Quaternion(0.185388, 0.00650348, 0.0129359, 0.982559)
|
||||
bones/104/position = Vector3(1.84285e-06, 5.76279e-06, -1.71906e-05)
|
||||
bones/105/rotation = Quaternion(0.191951, -2.77327e-07, -0.0231645, 0.981131)
|
||||
bones/106/position = Vector3(1.48522e-06, -3.60209e-06, 1.44012e-05)
|
||||
bones/107/position = Vector3(4.3816e-06, 2.12554, -2.07618e-05)
|
||||
bones/108/position = Vector3(-4.91738e-07, 8.79425e-06, -1.38031e-06)
|
||||
bones/109/rotation = Quaternion(-0.0738114, 0.0489804, 0.991878, -0.0912707)
|
||||
bones/110/position = Vector3(-1.06222e-06, 3.19319e-05, -1.56533e-06)
|
||||
bones/111/rotation = Quaternion(-0.207644, 0.0479112, 0.00270132, 0.977027)
|
||||
bones/112/position = Vector3(2.91388e-07, 4.25241e-06, -2.20301e-06)
|
||||
bones/113/rotation = Quaternion(0.540425, -0.0295423, -0.00350192, 0.840866)
|
||||
bones/115/rotation = Quaternion(0.340084, 3.45659e-05, 1.22099e-05, 0.940395)
|
||||
bones/119/rotation = Quaternion(0.0580127, 0.138334, 0.982759, -0.108092)
|
||||
bones/120/position = Vector3(-8.23132e-07, -4.34501e-06, -1.59527e-06)
|
||||
bones/121/rotation = Quaternion(-0.3299, -0.0711539, 0.0134173, 0.941235)
|
||||
bones/122/position = Vector3(-6.62286e-07, 6.482e-06, 2.36121e-07)
|
||||
bones/123/rotation = Quaternion(0.582538, -0.0190267, -0.0186471, 0.812367)
|
||||
bones/125/rotation = Quaternion(0.323212, 3.84905e-05, 1.41309e-05, 0.946327)
|
||||
|
||||
[node name="Input" type="Node3D" parent="."]
|
||||
script = ExtResource("3_x6527")
|
||||
min_range = 0.5
|
||||
|
||||
[node name="AnimationTree" type="AnimationTree" parent="."]
|
||||
root_node = NodePath("../Mesh")
|
||||
tree_root = SubResource("AnimationNodeStateMachine_8s3qg")
|
||||
advance_expression_base_node = NodePath("..")
|
||||
anim_player = NodePath("../Mesh/AnimationPlayer")
|
||||
script = ExtResource("3_26yay")
|
||||
|
||||
[node name="Interactor" type="Area3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 1)
|
||||
script = ExtResource("5_uk7c1")
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Interactor"]
|
||||
shape = SubResource("SphereShape3D_64co4")
|
||||
|
||||
[editable path="Mesh"]
|
165
scenes/player_mesh.tscn
Normal file
165
scenes/player_mesh.tscn
Normal file
|
@ -0,0 +1,165 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cyfbte21rykqr"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://fanrf571h0gn" path="res://assets/player.glb" id="1_7ymxt"]
|
||||
|
||||
[node name="player" instance=ExtResource("1_7ymxt")]
|
||||
|
||||
[node name="Skeleton3D" parent="Armature" index="0"]
|
||||
bones/0/position = Vector3(0.17945, 104.41, 0.110052)
|
||||
bones/0/rotation = Quaternion(-0.0406521, -0.0416971, -0.0129259, 0.998219)
|
||||
bones/0/scale = Vector3(1, 1, 1)
|
||||
bones/1/position = Vector3(5.96109e-08, -7.79423e-06, 8.06525e-07)
|
||||
bones/2/rotation = Quaternion(-0.0597369, 0.00111039, 0.00642272, 0.998193)
|
||||
bones/3/position = Vector3(-2.98023e-07, -1.34446e-05, 2.14577e-06)
|
||||
bones/4/rotation = Quaternion(0.0409263, 0.00151155, 0.0114956, 0.999095)
|
||||
bones/5/position = Vector3(1.63912e-07, 2.08151e-07, 3.01749e-07)
|
||||
bones/6/rotation = Quaternion(0.0537973, 0.00165954, 0.0114752, 0.998485)
|
||||
bones/7/position = Vector3(-5.96042e-07, -2.79844e-05, -6.33299e-07)
|
||||
bones/8/rotation = Quaternion(-0.561827, 0.587188, -0.4308, -0.392392)
|
||||
bones/8/scale = Vector3(1, 1, 1)
|
||||
bones/9/position = Vector3(1.63913e-06, -1.72853e-06, 2.13917e-05)
|
||||
bones/10/position = Vector3(2.77566e-06, 10.8382, 6.21936e-05)
|
||||
bones/10/rotation = Quaternion(0.546062, -0.128743, -0.247847, 0.789819)
|
||||
bones/10/scale = Vector3(1, 1, 1)
|
||||
bones/11/position = Vector3(-3.33721e-06, -2.59971e-05, -4.23144e-07)
|
||||
bones/12/rotation = Quaternion(-1.44917e-07, 1.29291e-07, -0.269901, 0.962888)
|
||||
bones/13/position = Vector3(4.32435e-07, 3.89919e-06, 7.05178e-07)
|
||||
bones/14/position = Vector3(7.82341e-06, 28.3288, -1.32138e-06)
|
||||
bones/14/rotation = Quaternion(-0.111071, -0.0606597, 0.117823, 0.984937)
|
||||
bones/15/position = Vector3(1.78986e-06, 7.87047e-06, 1.65885e-06)
|
||||
bones/16/rotation = Quaternion(0.410799, 0.0410545, -0.0191872, 0.910599)
|
||||
bones/17/position = Vector3(5.01544e-07, -6.299e-06, 3.963e-07)
|
||||
bones/18/position = Vector3(-4.8526e-07, 3.60001, -4.86888e-05)
|
||||
bones/18/rotation = Quaternion(0.53131, 0.0228324, -0.106782, 0.840111)
|
||||
bones/19/position = Vector3(3.32548e-07, -8.41357e-06, -2.27747e-05)
|
||||
bones/20/rotation = Quaternion(-4.9514e-08, 5.57123e-08, -1.76427e-07, 1)
|
||||
bones/21/position = Vector3(-1.54454e-06, -7.68341e-06, -8.74918e-06)
|
||||
bones/22/position = Vector3(-8.60441e-07, 2.11579, -1.07681e-05)
|
||||
bones/22/rotation = Quaternion(6.43738e-08, 0.00156918, -4.10172e-05, 0.999999)
|
||||
bones/22/scale = Vector3(1, 1, 1)
|
||||
bones/23/position = Vector3(-2.92063e-06, 7.30623e-07, -3.37238e-06)
|
||||
bones/24/position = Vector3(-2.72793e-05, 9.53252, 4.71968e-05)
|
||||
bones/24/rotation = Quaternion(0.339953, 0.0300464, 0.0273285, 0.939565)
|
||||
bones/25/position = Vector3(-9.73276e-07, 9.30667e-06, 1.7444e-05)
|
||||
bones/26/position = Vector3(-2.40773e-06, 3.70001, -1.51598e-05)
|
||||
bones/26/rotation = Quaternion(0.430758, 0.165335, 0.0714135, 0.884314)
|
||||
bones/27/position = Vector3(2.42792e-06, -5.07634e-06, -1.79432e-05)
|
||||
bones/28/position = Vector3(5.23295e-07, 2.95001, -1.36814e-05)
|
||||
bones/28/rotation = Quaternion(3.76456e-09, -9.34081e-09, -3.21888e-08, 1)
|
||||
bones/30/rotation = Quaternion(-1.54606e-07, 0.000928791, 0.000166436, 1)
|
||||
bones/31/position = Vector3(6.74278e-07, 1.0987e-05, -1.06914e-05)
|
||||
bones/32/rotation = Quaternion(0.367356, 0.012829, -0.0137641, 0.92989)
|
||||
bones/33/position = Vector3(-2.16168e-06, -9.28698e-06, 1.61968e-05)
|
||||
bones/34/position = Vector3(-2.08148e-06, 3.37928, -2.75762e-06)
|
||||
bones/34/rotation = Quaternion(0.435237, 0.0202325, -0.0616527, 0.897975)
|
||||
bones/34/scale = Vector3(1, 1, 1)
|
||||
bones/36/position = Vector3(5.32687e-06, 2.88968, 1.89373e-05)
|
||||
bones/36/rotation = Quaternion(6.7077e-08, 6.14505e-08, -1.0756e-07, 1)
|
||||
bones/37/position = Vector3(1.10354e-06, -4.4019e-06, 1.37493e-05)
|
||||
bones/38/position = Vector3(-1.83442e-06, 2.63883, -1.48906e-05)
|
||||
bones/38/rotation = Quaternion(1.16653e-07, 0.000145825, -0.00079924, 1)
|
||||
bones/38/scale = Vector3(1, 1, 1)
|
||||
bones/39/position = Vector3(-4.24683e-07, 1.03333e-05, -2.27057e-05)
|
||||
bones/40/position = Vector3(2.25983, 9.1083, 0.517871)
|
||||
bones/40/rotation = Quaternion(0.230758, 0.0232, 0.0553016, 0.971161)
|
||||
bones/41/position = Vector3(-1.50283e-06, -3.18235e-06, 1.64979e-05)
|
||||
bones/42/rotation = Quaternion(0.345931, -0.0275399, 0.00615904, 0.937835)
|
||||
bones/43/position = Vector3(2.44329e-07, 8.88386e-06, -6.62667e-06)
|
||||
bones/44/rotation = Quaternion(7.46085e-09, -1.39777e-08, -2.75613e-08, 1)
|
||||
bones/45/position = Vector3(-4.96307e-07, 1.11183e-05, 2.6697e-06)
|
||||
bones/46/rotation = Quaternion(-8.72723e-08, 0.00100258, 8.70361e-05, 0.999999)
|
||||
bones/46/scale = Vector3(1, 1, 1)
|
||||
bones/48/position = Vector3(2.68185, 2.4648, 1.57399)
|
||||
bones/48/rotation = Quaternion(0.253233, 0.0269746, -0.19885, 0.946364)
|
||||
bones/48/scale = Vector3(1, 1, 1)
|
||||
bones/49/position = Vector3(-4.76836e-07, -4.29153e-06, 8.58607e-06)
|
||||
bones/50/position = Vector3(-5.36506e-06, 4.18898, 1.80082e-06)
|
||||
bones/50/rotation = Quaternion(-0.0236439, 0.0331235, 0.0393129, 0.998398)
|
||||
bones/50/scale = Vector3(1, 1, 1)
|
||||
bones/52/position = Vector3(-8.58953e-06, 3.41627, -3.79061e-06)
|
||||
bones/52/rotation = Quaternion(1.62173e-06, -0.000806941, 3.60858e-07, 1)
|
||||
bones/52/scale = Vector3(1, 1, 1)
|
||||
bones/53/position = Vector3(-7.33137e-06, 1.96993e-05, -3.36238e-06)
|
||||
bones/54/rotation = Quaternion(0.00577409, -0.11751, -0.0487441, 0.991858)
|
||||
bones/56/rotation = Quaternion(-0.168671, 0.00146632, -0.00322634, 0.985666)
|
||||
bones/57/position = Vector3(-1.48998e-08, -1.55101e-05, -2.81259e-07)
|
||||
bones/58/rotation = Quaternion(0.116994, 0.0330545, -0.00432665, 0.992573)
|
||||
bones/59/position = Vector3(4.47016e-08, -3.2247e-05, -2.96597e-06)
|
||||
bones/60/rotation = Quaternion(3.91155e-08, 3.7787e-08, 2.9976e-15, 1)
|
||||
bones/61/rotation = Quaternion(0.506672, 0.632248, -0.512417, 0.28456)
|
||||
bones/62/position = Vector3(-2.02656e-06, -3.57628e-07, -4.18441e-05)
|
||||
bones/63/position = Vector3(7.15469e-08, 10.8377, 1.51746e-05)
|
||||
bones/63/rotation = Quaternion(0.502967, 0.244286, 0.329047, 0.76097)
|
||||
bones/63/scale = Vector3(1, 1, 1)
|
||||
bones/64/position = Vector3(3.60969e-06, 1.52503e-05, 4.33931e-06)
|
||||
bones/65/position = Vector3(6.08624e-06, 27.8415, 3.61837e-05)
|
||||
bones/65/rotation = Quaternion(9.9965e-08, -9.43294e-08, 0.240972, 0.970532)
|
||||
bones/66/position = Vector3(1.5152e-06, 5.09353e-07, 1.06806e-07)
|
||||
bones/67/rotation = Quaternion(-0.124955, -0.15428, -0.118697, 0.97288)
|
||||
bones/68/position = Vector3(-1.47492e-06, 9.18099e-07, 8.22066e-07)
|
||||
bones/69/rotation = Quaternion(0.223335, 0.00464231, 0.100994, 0.969485)
|
||||
bones/69/scale = Vector3(1, 1, 1)
|
||||
bones/70/position = Vector3(3.93391e-06, -3.12924e-06, 1.2352e-05)
|
||||
bones/71/position = Vector3(-7.3569e-06, 4.18708, 3.80831e-06)
|
||||
bones/71/rotation = Quaternion(-0.017028, -0.0337403, -0.0322282, 0.998766)
|
||||
bones/72/position = Vector3(5.96047e-08, -1.01924e-05, -1.82316e-05)
|
||||
bones/73/position = Vector3(-7.20031e-06, 3.41838, -3.40019e-05)
|
||||
bones/73/rotation = Quaternion(-2.43776e-06, 0.000745857, 5.49245e-07, 1)
|
||||
bones/73/scale = Vector3(1, 1, 1)
|
||||
bones/74/position = Vector3(-3.96371e-06, -8.34465e-06, 1.30411e-07)
|
||||
bones/75/position = Vector3(-3.2532e-06, 2.58059, 3.56767e-06)
|
||||
bones/75/rotation = Quaternion(0.0051477, 0.122682, 0.041651, 0.991558)
|
||||
bones/75/scale = Vector3(1, 1, 1)
|
||||
bones/77/rotation = Quaternion(0.329022, -0.00440169, -0.0369186, 0.94359)
|
||||
bones/78/position = Vector3(4.72453e-07, -1.04497e-06, 3.59342e-07)
|
||||
bones/79/position = Vector3(-2.66038e-07, 3.7, 8.95903e-07)
|
||||
bones/79/rotation = Quaternion(0.28229, 0.0283846, 0.000264906, 0.958909)
|
||||
bones/80/position = Vector3(-1.96994e-06, 1.6327e-06, -1.63261e-05)
|
||||
bones/81/rotation = Quaternion(-3.65055e-07, -4.16772e-09, -6.83649e-08, 1)
|
||||
bones/83/rotation = Quaternion(-4.89366e-09, -0.000377568, -1.2974e-05, 1)
|
||||
bones/84/position = Vector3(-4.94532e-07, -1.87893e-05, 1.52819e-05)
|
||||
bones/85/rotation = Quaternion(0.331909, -0.0198019, -0.0105555, 0.943044)
|
||||
bones/86/position = Vector3(-2.09158e-07, -2.31277e-06, -1.46174e-05)
|
||||
bones/87/rotation = Quaternion(0.403888, -0.00181236, 0.0290873, 0.914344)
|
||||
bones/88/position = Vector3(2.26344e-07, -5.1729e-06, -4.39392e-06)
|
||||
bones/89/rotation = Quaternion(4.04652e-07, 8.72496e-12, 6.58802e-08, 1)
|
||||
bones/90/position = Vector3(-2.41998e-07, -4.32138e-06, -4.24358e-06)
|
||||
bones/91/rotation = Quaternion(2.85187e-08, -0.00102416, 2.78559e-05, 0.999999)
|
||||
bones/92/position = Vector3(3.67407e-07, 1.44696e-06, -5.79837e-06)
|
||||
bones/93/rotation = Quaternion(0.331827, -0.0487858, 0.034802, 0.941435)
|
||||
bones/94/position = Vector3(1.83496e-07, -1.69704e-05, -3.62689e-06)
|
||||
bones/95/rotation = Quaternion(0.547972, -0.0207689, 0.058348, 0.834201)
|
||||
bones/96/position = Vector3(-6.40724e-07, 1.08097e-06, 1.03508e-05)
|
||||
bones/97/position = Vector3(1.86266e-06, 2.95, 2.9305e-05)
|
||||
bones/97/rotation = Quaternion(1.02781e-16, 1.80445e-09, -3.60028e-08, 1)
|
||||
bones/98/position = Vector3(7.57416e-07, -2.73586e-06, -1.18274e-06)
|
||||
bones/99/position = Vector3(-2.38102e-05, 2.64431, -7.72471e-06)
|
||||
bones/100/position = Vector3(-1.36858e-06, -8.86206e-06, 9.053e-06)
|
||||
bones/101/position = Vector3(3.80626, 8.0778, 0.486895)
|
||||
bones/101/rotation = Quaternion(0.379958, -0.0550092, 0.0382487, 0.922574)
|
||||
bones/102/position = Vector3(-1.08492e-06, 2.92186e-05, 1.50487e-05)
|
||||
bones/103/rotation = Quaternion(0.582059, -0.0103286, 0.0735094, 0.809751)
|
||||
bones/104/position = Vector3(-1.73342e-06, -1.47918e-06, -2.0886e-05)
|
||||
bones/105/rotation = Quaternion(-5.4723e-08, -3.14058e-09, 1.77999e-07, 1)
|
||||
bones/106/position = Vector3(8.89177e-07, -7.90852e-06, 1.76198e-05)
|
||||
bones/107/position = Vector3(2.5899e-06, 2.12554, 9.70504e-08)
|
||||
bones/107/rotation = Quaternion(-2.31341e-07, -0.000782879, -0.000295457, 1)
|
||||
bones/107/scale = Vector3(1, 1, 1)
|
||||
bones/108/position = Vector3(8.49366e-07, 5.665e-06, 3.62648e-06)
|
||||
bones/109/rotation = Quaternion(-0.036333, 0.0217706, 0.999101, 0.00199951)
|
||||
bones/109/scale = Vector3(1, 1, 1)
|
||||
bones/110/position = Vector3(-1.3528e-06, 3.43757e-05, -4.54129e-08)
|
||||
bones/111/rotation = Quaternion(-0.143928, 0.000177422, 0.00374932, 0.989581)
|
||||
bones/112/position = Vector3(-4.23869e-07, 1.24792e-07, 6.58015e-07)
|
||||
bones/113/rotation = Quaternion(0.495013, 0.131615, -0.0439781, 0.857732)
|
||||
bones/115/rotation = Quaternion(0.335413, 0.00425432, -0.000217396, 0.942062)
|
||||
bones/117/rotation = Quaternion(2.98097e-08, 0.0115715, 3.46601e-10, 0.999933)
|
||||
bones/119/rotation = Quaternion(0.119178, 0.0314785, 0.992322, -0.0101509)
|
||||
bones/119/scale = Vector3(1, 1, 1)
|
||||
bones/120/position = Vector3(8.86776e-07, -4.30776e-06, 1.57868e-06)
|
||||
bones/121/rotation = Quaternion(-0.0940526, 0.000144511, -0.0022175, 0.995565)
|
||||
bones/122/position = Vector3(-8.41099e-07, -1.2368e-06, 3.5533e-07)
|
||||
bones/123/rotation = Quaternion(0.451014, 0.0010166, 0.0176655, 0.892342)
|
||||
bones/123/scale = Vector3(1, 1, 1)
|
||||
bones/125/rotation = Quaternion(0.335216, 0.000625836, -1.98777e-05, 0.942141)
|
||||
bones/127/rotation = Quaternion(1.4904e-08, -0.0119058, -1.76878e-10, 0.999929)
|
39
src/camera_cache.ts
Normal file
39
src/camera_cache.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Camera3D, float64, Vector3 } from 'godot'
|
||||
|
||||
export class CameraCache extends Object {
|
||||
private _camera: Camera3D
|
||||
get camera() { return this._camera }
|
||||
|
||||
private _angle: float64
|
||||
|
||||
get angle() {
|
||||
return this._camera.rotation.y
|
||||
}
|
||||
|
||||
private _dirty: boolean = true
|
||||
|
||||
constructor(initial_camera: Camera3D) {
|
||||
super()
|
||||
this._camera = initial_camera
|
||||
this._angle = this._camera.rotation.y
|
||||
}
|
||||
|
||||
update_camera(camera: Camera3D) {
|
||||
this._camera = camera
|
||||
this._dirty = true
|
||||
}
|
||||
|
||||
recalculate() {
|
||||
if (this._dirty) {
|
||||
this._angle = this._camera.rotation.y
|
||||
this._dirty = false
|
||||
}
|
||||
}
|
||||
|
||||
transform_vec(vec: Vector3): Vector3 {
|
||||
return vec.rotated(Vector3.UP, this._angle)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
33
src/camera_trigger.js
Normal file
33
src/camera_trigger.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
const godot_annotations_1 = require("godot.annotations");
|
||||
const player_1 = __importDefault(require("./player"));
|
||||
const message_bus_1 = __importDefault(require("./message_bus"));
|
||||
class CameraTrigger extends godot_1.Area3D {
|
||||
_ready() {
|
||||
this._camera = this.get_node(this.camera);
|
||||
}
|
||||
_on_body_entered(body) {
|
||||
var _a;
|
||||
if (body instanceof player_1.default) {
|
||||
(_a = this._camera) === null || _a === void 0 ? void 0 : _a.make_current();
|
||||
console.log(message_bus_1.default.instance.active_camera_changed);
|
||||
message_bus_1.default.instance.active_camera_changed.emit(this._camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.default = CameraTrigger;
|
||||
__decorate([
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_NODE_PATH)
|
||||
], CameraTrigger.prototype, "camera", void 0);
|
||||
//# sourceMappingURL=camera_trigger.js.map
|
1
src/camera_trigger.js.map
Normal file
1
src/camera_trigger.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"camera_trigger.js","sourceRoot":"../../../","sources":["src/camera_trigger.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,iCAA0E;AAC1E,yDAA2C;AAC3C,sDAA6B;AAC7B,gEAAsC;AAEtC,MAAqB,aAAc,SAAQ,cAAM;IAK/C,MAAM;QACJ,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAa,CAAA;IACvD,CAAC;IAED,gBAAgB,CAAC,IAAmB;;QAClC,IAAI,IAAI,YAAY,gBAAM,EAAE,CAAC;YAC3B,MAAA,IAAI,CAAC,OAAO,0CAAE,YAAY,EAAE,CAAA;YAC5B,OAAO,CAAC,GAAG,CAAC,qBAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAA;YACtD,qBAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC9D,CAAC;IACH,CAAC;CACF;AAhBD,gCAgBC;AAdC;IADC,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,cAAc,CAAC;6CACpB"}
|
22
src/camera_trigger.ts
Normal file
22
src/camera_trigger.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { Area3D, Camera3D, NodePath, PhysicsBody3D, Variant } from 'godot'
|
||||
import { export_ } from 'godot.annotations'
|
||||
import Player from './player'
|
||||
import MessageBus from './message_bus'
|
||||
|
||||
export default class CameraTrigger extends Area3D {
|
||||
@export_(Variant.Type.TYPE_NODE_PATH)
|
||||
camera!: NodePath
|
||||
_camera!: Camera3D
|
||||
|
||||
_ready(): void {
|
||||
this._camera = this.get_node(this.camera) as Camera3D
|
||||
}
|
||||
|
||||
_on_body_entered(body: PhysicsBody3D) {
|
||||
if (body instanceof Player) {
|
||||
this._camera?.make_current()
|
||||
console.log(MessageBus.instance.active_camera_changed)
|
||||
MessageBus.instance.active_camera_changed.emit(this._camera)
|
||||
}
|
||||
}
|
||||
}
|
23
src/debug_draw.js
Normal file
23
src/debug_draw.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
class DebugDraw extends godot_1.Node {
|
||||
static get instance() {
|
||||
return DebugDraw._inst;
|
||||
}
|
||||
_ready() {
|
||||
DebugDraw._inst = this;
|
||||
}
|
||||
draw_line(begin, end, color = godot_1.Color.CYAN) {
|
||||
const instance = new godot_1.GeometryInstance3D();
|
||||
this.add_child(instance);
|
||||
const geom = new godot_1.ImmediateMesh();
|
||||
geom.surface_begin(godot_1.ImmediateMesh.PrimitiveType.PRIMITIVE_LINES);
|
||||
geom.surface_add_vertex(begin);
|
||||
geom.surface_add_vertex(end);
|
||||
geom.surface_set_color(color);
|
||||
geom.surface_end();
|
||||
}
|
||||
}
|
||||
exports.default = DebugDraw;
|
||||
//# sourceMappingURL=debug_draw.js.map
|
1
src/debug_draw.js.map
Normal file
1
src/debug_draw.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"debug_draw.js","sourceRoot":"../../../","sources":["src/debug_draw.ts"],"names":[],"mappings":";;AAAA,iCAA+E;AAE/E,MAAqB,SAAU,SAAQ,YAAI;IAGzC,MAAM,KAAK,QAAQ;QACjB,OAAO,SAAS,CAAC,KAAK,CAAA;IACxB,CAAC;IAED,MAAM;QACJ,SAAS,CAAC,KAAK,GAAG,IAAI,CAAA;IACxB,CAAC;IAED,SAAS,CAAC,KAAc,EAAE,GAAY,EAAE,QAAe,aAAK,CAAC,IAAI;QAC/D,MAAM,QAAQ,GAAG,IAAI,0BAAkB,EAAE,CAAA;QACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAExB,MAAM,IAAI,GAAG,IAAI,qBAAa,EAAE,CAAA;QAChC,IAAI,CAAC,aAAa,CAAC,qBAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;QAC/D,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAA;QAC9B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAC5B,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAA;QAC7B,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;CACF;AAtBD,4BAsBC"}
|
104
src/debug_draw.ts
Normal file
104
src/debug_draw.ts
Normal file
|
@ -0,0 +1,104 @@
|
|||
import { BaseMaterial3D, Color, ImmediateMesh, Mesh, MeshInstance3D, Node, Node3D, PackedVector3Array, StandardMaterial3D, Vector3 } from 'godot'
|
||||
|
||||
function createDefaultMaterial(): StandardMaterial3D {
|
||||
const material = new StandardMaterial3D()
|
||||
|
||||
material.shading_mode = BaseMaterial3D.ShadingMode.SHADING_MODE_UNSHADED
|
||||
material.no_depth_test = true
|
||||
material.vertex_color_use_as_albedo = true
|
||||
material.transparency = BaseMaterial3D.Transparency.TRANSPARENCY_DISABLED
|
||||
material.cull_mode = BaseMaterial3D.CullMode.CULL_DISABLED
|
||||
|
||||
return material
|
||||
}
|
||||
|
||||
class PooledMeshInstance {
|
||||
in_use: boolean = false
|
||||
instance: MeshInstance3D
|
||||
|
||||
constructor(material: StandardMaterial3D) {
|
||||
this.instance = new MeshInstance3D()
|
||||
this.instance.material_override = material
|
||||
}
|
||||
}
|
||||
|
||||
class MeshPool {
|
||||
target: Node
|
||||
pool: PooledMeshInstance[]
|
||||
default_material: StandardMaterial3D
|
||||
|
||||
constructor(target: Node, initial: number = 10) {
|
||||
this.pool = []
|
||||
this.target = target
|
||||
this.default_material = createDefaultMaterial()
|
||||
|
||||
for (let i = 0; i < initial; i++) {
|
||||
this.create()
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
const instance = new PooledMeshInstance(this.default_material)
|
||||
instance.instance.mesh = new ImmediateMesh()
|
||||
this.pool.push(instance)
|
||||
this.target.add_child(instance.instance)
|
||||
return instance
|
||||
}
|
||||
|
||||
get() {
|
||||
const next = this.pool.find(x => !x.in_use)
|
||||
if (next) {
|
||||
next.in_use = true
|
||||
return next
|
||||
} else {
|
||||
const instance = this.create()
|
||||
instance.in_use = true
|
||||
return instance
|
||||
}
|
||||
}
|
||||
|
||||
release(instance: PooledMeshInstance) {
|
||||
instance.in_use = false
|
||||
}
|
||||
}
|
||||
|
||||
export default class DebugDraw extends Node {
|
||||
private static _inst: DebugDraw
|
||||
|
||||
static get instance() {
|
||||
return DebugDraw._inst
|
||||
}
|
||||
|
||||
pool!: MeshPool
|
||||
|
||||
_ready(): void {
|
||||
DebugDraw._inst = this
|
||||
this.pool = new MeshPool(this as Node)
|
||||
}
|
||||
|
||||
static draw_line(begin: Vector3, end: Vector3, color: Color = Color.CYAN) {
|
||||
DebugDraw.draw_lines(new PackedVector3Array([begin, end]), color)
|
||||
}
|
||||
|
||||
static draw_lines(points: PackedVector3Array, color: Color = Color.CYAN) {
|
||||
DebugDraw.instance._draw_lines(points, color)
|
||||
}
|
||||
|
||||
_draw_lines(points: PackedVector3Array, color: Color = Color.CYAN) {
|
||||
const instance = this.pool.get()
|
||||
const mesh = instance.instance.mesh as ImmediateMesh
|
||||
|
||||
mesh.clear_surfaces()
|
||||
mesh.surface_begin(Mesh.PrimitiveType.PRIMITIVE_LINES)
|
||||
mesh.surface_set_color(color)
|
||||
|
||||
const len = points.size()
|
||||
for (let i = 0; i < len; i++) {
|
||||
mesh.surface_add_vertex(points.get_indexed(i))
|
||||
}
|
||||
|
||||
mesh.surface_end()
|
||||
this.pool.release(instance)
|
||||
}
|
||||
}
|
||||
|
552
src/enumerable.ts
Normal file
552
src/enumerable.ts
Normal file
|
@ -0,0 +1,552 @@
|
|||
import { GArray } from 'godot'
|
||||
|
||||
const DoneIteratorResult = Object.freeze({ value: undefined, done: true })
|
||||
|
||||
type Nullable<T> = T | null | undefined
|
||||
|
||||
export interface Predicate<T> {
|
||||
(value: Nullable<T>, index: number): boolean
|
||||
}
|
||||
|
||||
export interface Reducer<T, U = T> {
|
||||
(accumulator: U, value: Nullable<T>, index: number): U
|
||||
}
|
||||
|
||||
export interface Morphism<T, U = T> {
|
||||
(value: Nullable<T>, index: number): U
|
||||
}
|
||||
|
||||
interface IEnumeratorFactory<T> {
|
||||
(iterator: Iterator<T>): IEnumerator<T>
|
||||
}
|
||||
|
||||
export interface IEnumerator<T> {
|
||||
get current(): Nullable<T>
|
||||
moveNext(): boolean
|
||||
reset(): void
|
||||
toIterator<T>(): Iterator<T>
|
||||
}
|
||||
|
||||
export interface IEnumerable<T> {
|
||||
enumerator(): IEnumerator<T>
|
||||
}
|
||||
|
||||
export function isIterable(value: any): value is Iterable<any> {
|
||||
return typeof value[Symbol.iterator] === 'function'
|
||||
}
|
||||
|
||||
export function isIterator(value: any): value is Iterator<any> {
|
||||
return typeof value.next === 'function'
|
||||
}
|
||||
|
||||
export function isBuffer(value: any): value is ArrayBufferLike {
|
||||
return ArrayBuffer.isView(value)
|
||||
}
|
||||
|
||||
export function isGArray(value: any): value is GArray {
|
||||
return typeof value.get_indexed === 'function'
|
||||
}
|
||||
|
||||
export function isArrayLike(value: any): value is ArrayLike<any> {
|
||||
return typeof value.length === 'number'
|
||||
}
|
||||
|
||||
class IteratorEnumerator<T> implements IEnumerator<T>, Iterator<T> {
|
||||
private _iterator: Iterator<T>
|
||||
private _consumed: boolean = false
|
||||
private _current: Nullable<T>
|
||||
|
||||
get current(): Nullable<T> {
|
||||
return this._current
|
||||
}
|
||||
|
||||
constructor(iterator: Iterator<T>) {
|
||||
this._iterator = iterator
|
||||
}
|
||||
|
||||
static from<T>(iterator: Iterator<T>): IteratorEnumerator<T> {
|
||||
return new IteratorEnumerator(iterator)
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
if (!this._consumed) {
|
||||
const { value, done } = this._iterator.next()
|
||||
|
||||
this._current = value
|
||||
if (done) {
|
||||
this._consumed = true
|
||||
}
|
||||
|
||||
return !done
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
reset(): void { }
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return this as Iterator<T>
|
||||
}
|
||||
|
||||
next(...[_value]: [] | [any]): IteratorResult<T> {
|
||||
const done = this.moveNext()
|
||||
return { value: this.current, done } as IteratorResult<T>
|
||||
}
|
||||
|
||||
return(value?: any): IteratorResult<T, any> {
|
||||
return this._iterator.return?.(value) ?? DoneIteratorResult
|
||||
}
|
||||
|
||||
throw(e?: any): IteratorResult<T, any> {
|
||||
return this._iterator.throw?.(e) ?? DoneIteratorResult
|
||||
}
|
||||
}
|
||||
|
||||
class CachedIteratorEnumerator<T> implements IEnumerator<T>, Iterator<T> {
|
||||
private _iterator: IteratorEnumerator<T>
|
||||
private _cache: Nullable<T>[] = []
|
||||
private _index: number = -1
|
||||
|
||||
get current(): Nullable<T> {
|
||||
return this._cache[this._index]
|
||||
}
|
||||
|
||||
constructor(iterator: Iterator<T>) {
|
||||
this._iterator = new IteratorEnumerator(iterator)
|
||||
}
|
||||
|
||||
static from<T>(iterator: Iterator<T>): CachedIteratorEnumerator<T> {
|
||||
return new CachedIteratorEnumerator(iterator)
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
this._index += 1
|
||||
|
||||
if (this._cache.length > this._index) {
|
||||
return true
|
||||
} else if (!this._iterator.moveNext()) {
|
||||
this._cache.push(this._iterator.current)
|
||||
|
||||
return !true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._index = -1
|
||||
}
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return this as Iterator<T>
|
||||
}
|
||||
|
||||
next(...[_value]: [] | [any]): IteratorResult<T> {
|
||||
const done = this.moveNext()
|
||||
return { value: this.current, done } as IteratorResult<T>
|
||||
}
|
||||
|
||||
return?(value?: any): IteratorResult<T, any> {
|
||||
return this._iterator.return(value)
|
||||
}
|
||||
|
||||
throw(e?: any): IteratorResult<T, any> {
|
||||
return this._iterator.throw(e)
|
||||
}
|
||||
}
|
||||
|
||||
export class IterableEnumerator<T> implements IEnumerator<T>, Iterator<T> {
|
||||
private _iterable: Iterable<T>
|
||||
private _factory: IEnumeratorFactory<T>
|
||||
private _enumerator: Nullable<IEnumerator<T>>
|
||||
|
||||
get current(): Nullable<T> {
|
||||
return this._enumerator?.current
|
||||
}
|
||||
|
||||
constructor(iterable: Iterable<T>, factory: IEnumeratorFactory<T> = IteratorEnumerator.from) {
|
||||
this._iterable = iterable
|
||||
this._factory = factory
|
||||
}
|
||||
|
||||
static fromIterable<T>(iterable: Iterable<T>, factory?: IEnumeratorFactory<T>): IEnumerator<T> {
|
||||
return new this(iterable, factory)
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
return this._enumerator?.moveNext() ?? false
|
||||
}
|
||||
|
||||
_createIterator(): Iterator<T> {
|
||||
return this._iterable[Symbol.iterator]()
|
||||
}
|
||||
|
||||
_createEnumerator(): IEnumerator<T> {
|
||||
return this._factory(this._createIterator())
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._enumerator = this._createEnumerator()
|
||||
}
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return this._createIterator() as Iterator<T>
|
||||
}
|
||||
|
||||
next(...[_value]: [] | [any]): IteratorResult<T, any> {
|
||||
const done = !this.moveNext()
|
||||
return { value: this.current, done } as IteratorResult<T, any>
|
||||
}
|
||||
|
||||
return?(value?: any): IteratorResult<T, any> {
|
||||
if (isIterator(this._enumerator)) {
|
||||
return this._enumerator?.return?.(value) || DoneIteratorResult
|
||||
} else {
|
||||
return DoneIteratorResult
|
||||
}
|
||||
}
|
||||
|
||||
throw?(e?: any): IteratorResult<T, any> {
|
||||
if (isIterator(this._enumerator)) {
|
||||
return this._enumerator?.throw?.(e) || DoneIteratorResult
|
||||
} else {
|
||||
return DoneIteratorResult
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Enumerator<T> implements IEnumerator<T>, Iterator<T> {
|
||||
protected _enumerator: IEnumerator<T>
|
||||
protected _index: number = 0
|
||||
|
||||
get current(): Nullable<T> {
|
||||
return this._enumerator.current
|
||||
}
|
||||
|
||||
constructor(enumerator: IEnumerator<T>) {
|
||||
this._enumerator = enumerator
|
||||
}
|
||||
|
||||
static fromIterable<T>(iterable: Iterable<T>): IEnumerator<T> {
|
||||
return new this(new IterableEnumerator(iterable))
|
||||
}
|
||||
|
||||
static fromIterator<T>(iterator: Iterator<T>, cache: boolean = true): IEnumerator<T> {
|
||||
if (cache) {
|
||||
return new CachedIteratorEnumerator(iterator)
|
||||
} else {
|
||||
return new IteratorEnumerator(iterator)
|
||||
}
|
||||
}
|
||||
|
||||
static toIterator<T>(enumerator: IEnumerator<T>): Iterator<T> {
|
||||
return new this(enumerator)
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.toIterator()
|
||||
}
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return Enumerator.toIterator(this) as Iterator<T>
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
this._index += 1
|
||||
return this._enumerator.moveNext()
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._enumerator.reset()
|
||||
}
|
||||
|
||||
next(...[_value]: [] | [any]): IteratorResult<T, any> {
|
||||
const done = this.moveNext()
|
||||
|
||||
return { value: this.current, done } as IteratorResult<T>
|
||||
}
|
||||
|
||||
return?(_value?: any): IteratorResult<T, any> {
|
||||
return DoneIteratorResult
|
||||
}
|
||||
|
||||
throw?(_e?: any): IteratorResult<T, any> {
|
||||
return DoneIteratorResult
|
||||
}
|
||||
}
|
||||
|
||||
class DropEnumerator<T> extends Enumerator<T> {
|
||||
private _limit: number
|
||||
|
||||
constructor(enumerator: IEnumerator<T>, limit: number) {
|
||||
super(enumerator)
|
||||
this._limit = limit
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
for (let i = 0; i < this._limit; i++) {
|
||||
if (!super.moveNext()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class FilterEnumerator<T> extends Enumerator<T> {
|
||||
private _filter: Predicate<T>
|
||||
|
||||
constructor(enumerator: IEnumerator<T>, filter: Predicate<T>) {
|
||||
super(enumerator)
|
||||
this._filter = filter
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
let done = super.moveNext()
|
||||
|
||||
while (!done && !this._filter(this.current, this._index)) {
|
||||
done = super.moveNext()
|
||||
}
|
||||
|
||||
return done
|
||||
}
|
||||
}
|
||||
|
||||
class FlatMapEnumerator<T, U = T> implements IEnumerator<U> {
|
||||
private _enumerator: IEnumerator<T>
|
||||
private _flatMap: Morphism<T, IEnumerator<U>>
|
||||
private _inner?: IEnumerator<U>
|
||||
private _index: number = -1
|
||||
|
||||
constructor(enumerator: IEnumerator<T>, flatMap: Morphism<T, IEnumerator<U>>) {
|
||||
this._enumerator = enumerator
|
||||
this._flatMap = flatMap
|
||||
}
|
||||
|
||||
get current(): Nullable<U> {
|
||||
return this._inner?.current
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
if (this._inner && this._inner.moveNext()) {
|
||||
return true
|
||||
}
|
||||
|
||||
const done = this._enumerator.moveNext()
|
||||
|
||||
if (done) {
|
||||
return false
|
||||
}
|
||||
|
||||
this._index += 1
|
||||
this._inner = this._flatMap(this._enumerator.current, this._index)
|
||||
return this._inner.moveNext()
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._index = -1
|
||||
this._inner = undefined
|
||||
this._enumerator.reset()
|
||||
}
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return Enumerator.toIterator(this) as Iterator<T>
|
||||
}
|
||||
}
|
||||
|
||||
class MapEnumerator<T, U = T> implements IEnumerator<U> {
|
||||
private _enumerator: IEnumerator<T>
|
||||
private _map: Morphism<T, U>
|
||||
private _current!: U
|
||||
private _index: number = -1
|
||||
|
||||
get current(): U {
|
||||
return this._current
|
||||
}
|
||||
|
||||
constructor(enumerator: IEnumerator<T>, map: Morphism<T, U>) {
|
||||
this._enumerator = enumerator
|
||||
this._map = map
|
||||
}
|
||||
|
||||
toIterator<U>(): Iterator<U> {
|
||||
return Enumerator.toIterator(this) as Iterator<U>
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
this._index += 1
|
||||
const done = this._enumerator.moveNext()
|
||||
|
||||
if (!done) {
|
||||
this._current = this._map(this._enumerator.current, this._index)
|
||||
}
|
||||
|
||||
return done
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this._enumerator.reset()
|
||||
}
|
||||
}
|
||||
|
||||
class TakeEnumerator<T> extends Enumerator<T> {
|
||||
private _limit: number
|
||||
|
||||
constructor(enumerator: IEnumerator<T>, limit: number) {
|
||||
super(enumerator)
|
||||
this._limit = limit
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
if (this._limit < 0) {
|
||||
return false
|
||||
} else {
|
||||
this._limit -= 1
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class FusedEnumerator<T> implements IEnumerator<T> {
|
||||
private _enumerators: IEnumerator<T>[]
|
||||
private _index: number = 0
|
||||
|
||||
private _cur() {
|
||||
return this._enumerators[this._index]
|
||||
}
|
||||
|
||||
private _done() {
|
||||
return this._index < this._enumerators.length
|
||||
}
|
||||
|
||||
get current(): Nullable<T> {
|
||||
return this._cur().current
|
||||
}
|
||||
|
||||
constructor(enumerators: IEnumerator<T>[]) {
|
||||
this._enumerators = enumerators
|
||||
}
|
||||
|
||||
toIterator<T>(): Iterator<T> {
|
||||
return Enumerator.toIterator(this) as Iterator<T>
|
||||
}
|
||||
|
||||
moveNext(): boolean {
|
||||
while (!this._done()) {
|
||||
if (this._cur().moveNext()) {
|
||||
return true
|
||||
}
|
||||
|
||||
this._index += 1
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
const len = this._enumerators.length
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
this._enumerators[i].reset()
|
||||
}
|
||||
|
||||
this._index = 0
|
||||
}
|
||||
}
|
||||
|
||||
export class Enumerable<T> implements IEnumerable<T>, Iterable<T> {
|
||||
private _enumerator: IEnumerator<T>
|
||||
|
||||
constructor(enumerator: IEnumerator<T>) {
|
||||
this._enumerator = enumerator
|
||||
}
|
||||
|
||||
static from<T>(enumerator: IEnumerator<T>) {
|
||||
return new this(enumerator)
|
||||
}
|
||||
|
||||
[Symbol.iterator](): Iterator<T> {
|
||||
return this._enumerator.toIterator()
|
||||
}
|
||||
|
||||
at(index: number): Nullable<T> {
|
||||
for (let i = 0; i < index; i++) {
|
||||
if (!this._enumerator.moveNext()) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const value = this._enumerator.current
|
||||
this._enumerator.reset()
|
||||
return value
|
||||
}
|
||||
|
||||
atOrDefault(index: number, defaultValue: T) {
|
||||
const value = this.at(index)
|
||||
return value || defaultValue
|
||||
}
|
||||
|
||||
atOrElse(index: number, defaultValue: () => T) {
|
||||
const value = this.at(index)
|
||||
return value || defaultValue()
|
||||
}
|
||||
|
||||
concat(other: IEnumerator<T>): FusedEnumerator<T> {
|
||||
return new FusedEnumerator([this._enumerator, other])
|
||||
}
|
||||
|
||||
|
||||
drop(limit: number) {
|
||||
return new Enumerable(new DropEnumerator(this._enumerator, limit))
|
||||
}
|
||||
|
||||
enumerator(): IEnumerator<T> {
|
||||
return this._enumerator
|
||||
}
|
||||
|
||||
every(predicate: Predicate<T>): boolean {
|
||||
let index = 0
|
||||
while (this._enumerator.moveNext()) {
|
||||
if (!predicate(this._enumerator.current, index)) {
|
||||
return false
|
||||
}
|
||||
|
||||
index += 1
|
||||
}
|
||||
|
||||
this._enumerator.reset()
|
||||
return true
|
||||
}
|
||||
|
||||
filter(predicate: Predicate<T>): IEnumerable<T> {
|
||||
return new Enumerable(new FilterEnumerator(this._enumerator, predicate))
|
||||
}
|
||||
|
||||
flatMap<U>(fn: Morphism<T, IEnumerator<U>>): IEnumerable<U> {
|
||||
return new Enumerable(new FlatMapEnumerator(this._enumerator, fn))
|
||||
}
|
||||
|
||||
map<U>(fn: Morphism<T, U>): IEnumerable<U> {
|
||||
return new Enumerable(new MapEnumerator(this._enumerator, fn))
|
||||
}
|
||||
|
||||
some(predicate: Predicate<T>): boolean {
|
||||
let index = 0
|
||||
while (this._enumerator.moveNext()) {
|
||||
if (predicate(this._enumerator.current, index)) {
|
||||
return true
|
||||
}
|
||||
|
||||
index += 1
|
||||
}
|
||||
|
||||
this._enumerator.reset()
|
||||
return false
|
||||
}
|
||||
|
||||
take(limit: number): IEnumerable<T> {
|
||||
return new Enumerable(new TakeEnumerator(this._enumerator, limit))
|
||||
}
|
||||
}
|
||||
|
92
src/input_buffer.ts
Normal file
92
src/input_buffer.ts
Normal file
|
@ -0,0 +1,92 @@
|
|||
import { int32, int64, PackedVector2Array, Vector2 } from 'godot'
|
||||
|
||||
export class InputBufferError extends Error {
|
||||
constructor(message: string) {
|
||||
super(`InputBufferError: ${message}`)
|
||||
}
|
||||
|
||||
static empty() {
|
||||
return new InputBufferError('cannot perform operation, buffer is empty')
|
||||
}
|
||||
|
||||
static outOfBounds(index: int64) {
|
||||
return new InputBufferError(`cannot access ${index}: index out of bounds`)
|
||||
}
|
||||
}
|
||||
|
||||
export default class InputBuffer {
|
||||
readonly capacity: int32
|
||||
private _buffer: PackedVector2Array
|
||||
private _head: int32 = 0
|
||||
private _tail: int32 = 0
|
||||
private _size: int32 = 0
|
||||
|
||||
constructor(capacity: int32) {
|
||||
this.capacity = capacity
|
||||
this._buffer = new PackedVector2Array()
|
||||
this._buffer.resize(capacity)
|
||||
this._buffer.fill(Vector2.ZERO)
|
||||
}
|
||||
|
||||
is_empty() {
|
||||
return this._size === 0
|
||||
}
|
||||
|
||||
is_full() {
|
||||
return this._size === this.capacity
|
||||
}
|
||||
|
||||
push(value: Vector2) {
|
||||
this._buffer.set_indexed(this._head, value)
|
||||
this._head = (this._head + 1) % this.capacity
|
||||
|
||||
if (this.is_full()) {
|
||||
this._tail = this._head
|
||||
} else {
|
||||
this._size += 1
|
||||
}
|
||||
}
|
||||
|
||||
pop(): Vector2 {
|
||||
if (this.is_empty()) {
|
||||
throw InputBufferError.empty()
|
||||
}
|
||||
|
||||
const value = this.tail()
|
||||
this._tail = (this._tail + 1) % this.capacity
|
||||
this._size += 1
|
||||
return value
|
||||
}
|
||||
|
||||
at(index: int64) {
|
||||
if (index >= this._size) {
|
||||
throw InputBufferError.outOfBounds(index)
|
||||
}
|
||||
|
||||
const n = index < 0 ? this._head - index : this._tail + index
|
||||
const idx = n % this.capacity
|
||||
return this._buffer.get_indexed(idx)
|
||||
}
|
||||
|
||||
size() {
|
||||
return this._size
|
||||
}
|
||||
|
||||
head() {
|
||||
return this._buffer.get_indexed(this._head)
|
||||
}
|
||||
|
||||
tail() {
|
||||
return this._buffer.get_indexed(this._tail)
|
||||
}
|
||||
|
||||
slice(begin: int64, end?: int64) {
|
||||
return this._buffer.slice(begin, end)
|
||||
}
|
||||
|
||||
clear() {
|
||||
this._size = 0
|
||||
this._head = 0
|
||||
this._tail = 0
|
||||
}
|
||||
}
|
8
src/interactable.ts
Normal file
8
src/interactable.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { Area3D } from 'godot'
|
||||
import Interactor from './interactor'
|
||||
|
||||
export default class Interactable extends Area3D {
|
||||
interact(interactor: Interactor) {
|
||||
console.log('awawawawawa', interactor)
|
||||
}
|
||||
}
|
62
src/interactor.ts
Normal file
62
src/interactor.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { Area3D, Callable } from 'godot'
|
||||
import Interactable from './interactable'
|
||||
|
||||
class InteractableDistance {
|
||||
static Empty = new InteractableDistance(Infinity)
|
||||
|
||||
interactable?: Interactable
|
||||
distance: number
|
||||
|
||||
constructor(distance: number, interactable?: Interactable) {
|
||||
this.distance = distance
|
||||
this.interactable = interactable
|
||||
}
|
||||
}
|
||||
|
||||
export default class Interactor extends Area3D {
|
||||
_interactables: Array<Interactable> = []
|
||||
|
||||
_ready(): void {
|
||||
this.area_entered.connect(Callable.create(
|
||||
this,
|
||||
this._on_area_entered
|
||||
))
|
||||
|
||||
this.area_exited.connect(Callable.create(
|
||||
this,
|
||||
this._on_area_exited
|
||||
))
|
||||
}
|
||||
|
||||
_on_area_entered(area: Area3D) {
|
||||
if (area instanceof Interactable) {
|
||||
this._interactables.push(area)
|
||||
}
|
||||
}
|
||||
|
||||
_on_area_exited(area: Area3D) {
|
||||
const index = this._interactables.indexOf(area as Interactable)
|
||||
|
||||
if (index >= 0) {
|
||||
this._interactables.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
try_interact_nearest() {
|
||||
// @ts-ignore
|
||||
const nearest = this._interactables.reduce(this.find_nearest.bind(this), InteractableDistance.Empty)
|
||||
|
||||
if (nearest !== InteractableDistance.Empty && nearest.interactable != null) {
|
||||
nearest.interactable.interact(this)
|
||||
}
|
||||
}
|
||||
|
||||
find_nearest(nearest: InteractableDistance, target: Interactable): InteractableDistance {
|
||||
const distance = this.global_position.distance_to(target.global_position)
|
||||
if (distance < nearest.distance) {
|
||||
return new InteractableDistance(distance, target)
|
||||
} else {
|
||||
return nearest
|
||||
}
|
||||
}
|
||||
}
|
23
src/message_bus.js
Normal file
23
src/message_bus.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
const godot_annotations_1 = require("godot.annotations");
|
||||
class MessageBus extends godot_1.Node {
|
||||
static get instance() {
|
||||
return MessageBus._inst;
|
||||
}
|
||||
_ready() {
|
||||
MessageBus._inst = this;
|
||||
}
|
||||
}
|
||||
exports.default = MessageBus;
|
||||
__decorate([
|
||||
(0, godot_annotations_1.signal)()
|
||||
], MessageBus.prototype, "active_camera_changed", void 0);
|
||||
//# sourceMappingURL=message_bus.js.map
|
1
src/message_bus.js.map
Normal file
1
src/message_bus.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"message_bus.js","sourceRoot":"../../../","sources":["src/message_bus.ts"],"names":[],"mappings":";;;;;;;;AAAA,iCAA+C;AAC/C,yDAA0C;AAE1C,MAAqB,UAAW,SAAQ,YAAI;IAG1C,MAAM,KAAK,QAAQ;QACjB,OAAO,UAAU,CAAC,KAAK,CAAA;IACzB,CAAC;IAKD,MAAM;QACJ,UAAU,CAAC,KAAK,GAAG,IAAI,CAAA;IACzB,CAAC;CACF;AAbD,6BAaC;AALC;IADC,IAAA,0BAAM,GAAE;yDACgC"}
|
17
src/message_bus.ts
Normal file
17
src/message_bus.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Camera3D, Node, Signal1 } from 'godot'
|
||||
import { signal } from 'godot.annotations'
|
||||
|
||||
export default class MessageBus extends Node {
|
||||
private static _inst: MessageBus
|
||||
|
||||
static get instance() {
|
||||
return MessageBus._inst
|
||||
}
|
||||
|
||||
@signal()
|
||||
active_camera_changed!: Signal1<Camera3D>
|
||||
|
||||
_ready(): void {
|
||||
MessageBus._inst = this
|
||||
}
|
||||
}
|
77
src/player.js
Normal file
77
src/player.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
"use strict";
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
const godot_annotations_1 = require("godot.annotations");
|
||||
const message_bus_1 = __importDefault(require("./message_bus"));
|
||||
class Player extends godot_1.CharacterBody3D {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.gravity = godot_1.ProjectSettings.get_setting('physics/3d/default_gravity');
|
||||
this.walk_speed = 3;
|
||||
this.walk_backward_speed = 2;
|
||||
this.run_speed = 6;
|
||||
this.turn_speed = 1;
|
||||
this._rotation_speed = 2 * Math.PI;
|
||||
}
|
||||
_ready() {
|
||||
this._rotation_speed = this.turn_speed * 2 * Math.PI;
|
||||
this._player_input = this.get_node(this.player_input);
|
||||
this._camera = this.get_viewport().get_camera_3d();
|
||||
message_bus_1.default.instance.active_camera_changed.connect(godot_1.Callable.create(this, this.on_camera_changed));
|
||||
}
|
||||
get_movement(delta) {
|
||||
const input = this._player_input.movement_input;
|
||||
return godot_1.Vector3.MULTIPLY(this.walk_speed, new godot_1.Vector3(input.x, 0, input.y));
|
||||
}
|
||||
//get_translation(_delta: float64): Vector3 {
|
||||
// const forward = Vector3.MULTIPLY(-1, this.transform.basis.z)
|
||||
// return Vector3.MULTIPLY(forward, this.get_movement())
|
||||
//}
|
||||
get_gravitational_force(delta) {
|
||||
return -this.gravity * delta;
|
||||
}
|
||||
relative_to(target, vec) {
|
||||
return vec.rotated(godot_1.Vector3.UP, target.rotation.y);
|
||||
}
|
||||
on_camera_changed(camera) {
|
||||
this._camera = camera;
|
||||
}
|
||||
_physics_process(delta) {
|
||||
const movement = this.relative_to(this._camera, this.get_movement(delta));
|
||||
if (!movement.is_zero_approx()) {
|
||||
this.look_at(godot_1.Vector3.NEGATE(godot_1.Vector3.ADD(this.position, movement)), godot_1.Vector3.UP);
|
||||
}
|
||||
this.velocity = new godot_1.Vector3(movement.x, this.velocity.y + this.get_gravitational_force(delta), movement.z);
|
||||
this.move_and_slide();
|
||||
}
|
||||
}
|
||||
exports.default = Player;
|
||||
__decorate([
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_NODE_PATH)
|
||||
], Player.prototype, "player_input", void 0);
|
||||
__decorate([
|
||||
(0, godot_annotations_1.help)('Forward walk speed in units per second'),
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_FLOAT)
|
||||
], Player.prototype, "walk_speed", void 0);
|
||||
__decorate([
|
||||
(0, godot_annotations_1.help)('Backward walk speed in units per second'),
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_FLOAT)
|
||||
], Player.prototype, "walk_backward_speed", void 0);
|
||||
__decorate([
|
||||
(0, godot_annotations_1.help)('Run speed in units per second'),
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_FLOAT)
|
||||
], Player.prototype, "run_speed", void 0);
|
||||
__decorate([
|
||||
(0, godot_annotations_1.help)('Turn speed in rotations per second'),
|
||||
(0, godot_annotations_1.export_)(godot_1.Variant.Type.TYPE_FLOAT)
|
||||
], Player.prototype, "turn_speed", void 0);
|
||||
//# sourceMappingURL=player.js.map
|
1
src/player.js.map
Normal file
1
src/player.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"player.js","sourceRoot":"../../../","sources":["src/player.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,iCAAkI;AAClI,yDAAiD;AAEjD,gEAAsC;AAEtC,MAAqB,MAAO,SAAQ,uBAAe;IAAnD;;QACE,YAAO,GAAG,uBAAe,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAA;QAQnE,eAAU,GAAG,CAAC,CAAA;QAId,wBAAmB,GAAG,CAAC,CAAA;QAIvB,cAAS,GAAG,CAAC,CAAA;QAIb,eAAU,GAAG,CAAC,CAAA;QACd,oBAAe,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;IA+D/B,CAAC;IA3DC,MAAM;QACJ,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;QACpD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAgB,CAAA;QACpE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC,aAAa,EAAE,CAAA;QAElD,qBAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,OAAO,CAC/C,gBAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAC9C,CAAA;IACH,CAAC;IAED,YAAY,CAAC,KAAc;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,cAAc,CAAA;QAC/C,OAAO,eAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,eAAO,CAClD,KAAK,CAAC,CAAC,EACP,CAAC,EACD,KAAK,CAAC,CAAC,CACR,CAAC,CAAA;IACJ,CAAC;IAED,6CAA6C;IAC7C,gEAAgE;IAChE,yDAAyD;IACzD,GAAG;IAEH,uBAAuB,CAAC,KAAc;QACpC,OAAO,CAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAA;IAC9B,CAAC;IAED,WAAW,CAAC,MAAc,EAAE,GAAY;QACtC,OAAO,GAAG,CAAC,OAAO,CAAC,eAAO,CAAC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,iBAAiB,CAAC,MAAgB;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAED,gBAAgB,CAAC,KAAc;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAC/B,IAAI,CAAC,OAAO,EACZ,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CACzB,CAAA;QAED,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC;YAC/B,IAAI,CAAC,OAAO,CACV,eAAO,CAAC,MAAM,CACZ,eAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CACrC,EACD,eAAO,CAAC,EAAE,CACX,CAAA;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAO,CACzB,QAAQ,CAAC,CAAC,EACV,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,uBAAuB,CAAC,KAAK,CAAC,EACrD,QAAQ,CAAC,CAAC,CACX,CAAA;QAED,IAAI,CAAC,cAAc,EAAE,CAAA;IACvB,CAAC;CACF;AArFD,yBAqFC;AAjFC;IADC,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,cAAc,CAAC;4CACd;AAKvB;IAFC,IAAA,wBAAI,EAAC,wCAAwC,CAAC;IAC9C,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,UAAU,CAAC;0CACnB;AAId;IAFC,IAAA,wBAAI,EAAC,yCAAyC,CAAC;IAC/C,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,UAAU,CAAC;mDACV;AAIvB;IAFC,IAAA,wBAAI,EAAC,+BAA+B,CAAC;IACrC,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,UAAU,CAAC;yCACpB;AAIb;IAFC,IAAA,wBAAI,EAAC,oCAAoC,CAAC;IAC1C,IAAA,2BAAO,EAAC,eAAO,CAAC,IAAI,CAAC,UAAU,CAAC;0CACnB"}
|
117
src/player.ts
Normal file
117
src/player.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
import { Callable, CharacterBody3D, Color, float64, ProjectSettings, Variant, Vector2, Vector3 } from 'godot'
|
||||
import { export_, help, onready } from 'godot.annotations'
|
||||
import PlayerInput from './player_input'
|
||||
import DebugDraw from './debug_draw'
|
||||
import Interactor from './interactor'
|
||||
|
||||
export default class Player extends CharacterBody3D {
|
||||
gravity = ProjectSettings.get_setting('physics/3d/default_gravity')
|
||||
|
||||
@onready("Input")
|
||||
player_input!: PlayerInput
|
||||
|
||||
@onready("Interactor")
|
||||
interactor!: Interactor
|
||||
|
||||
@help('Forward walk speed in units per second')
|
||||
@export_(Variant.Type.TYPE_FLOAT)
|
||||
walk_speed = 3
|
||||
|
||||
@help('Run speed in units per second')
|
||||
@export_(Variant.Type.TYPE_FLOAT)
|
||||
run_speed = 6
|
||||
|
||||
@help('Turn speed in rotations per second')
|
||||
@export_(Variant.Type.TYPE_FLOAT)
|
||||
turn_speed = 1
|
||||
_rotation_speed = 2 * Math.PI
|
||||
|
||||
|
||||
is_running() {
|
||||
return this.player_input.is_running && !this.velocity.is_zero_approx()
|
||||
}
|
||||
|
||||
_ready(): void {
|
||||
this._rotation_speed = this.turn_speed * 2 * Math.PI
|
||||
|
||||
this.player_input.interact.connect(
|
||||
Callable.create(
|
||||
this,
|
||||
this.try_interact
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
try_interact() {
|
||||
this.interactor.try_interact_nearest()
|
||||
}
|
||||
|
||||
get_movement(input: Vector2): Vector3 {
|
||||
let speed = this.walk_speed
|
||||
|
||||
if (this.is_running()) {
|
||||
input = input.normalized()
|
||||
speed = this.run_speed
|
||||
}
|
||||
|
||||
return Vector3.MULTIPLY(speed, new Vector3(
|
||||
input.x,
|
||||
0,
|
||||
input.y
|
||||
))
|
||||
}
|
||||
|
||||
get_gravitational_force(delta: float64): float64 {
|
||||
return -this.gravity * delta
|
||||
}
|
||||
|
||||
is_kinda_equal(a: Vector2, b: Vector2, e: float64 = 0.1) {
|
||||
return a.distance_to(b) <= e
|
||||
}
|
||||
|
||||
_draw_movement(movement: Vector3) {
|
||||
DebugDraw.draw_line(
|
||||
Vector3.ADD(
|
||||
Vector3.UP,
|
||||
this.position,
|
||||
),
|
||||
Vector3.ADD(
|
||||
Vector3.UP,
|
||||
Vector3.ADD(this.position, movement)
|
||||
),
|
||||
Color.GREEN
|
||||
)
|
||||
}
|
||||
|
||||
rotate_toward(direction: Vector3, _delta: float64) {
|
||||
if (!direction.is_zero_approx()) {
|
||||
this.look_at(
|
||||
Vector3.ADD(this.global_position, direction),
|
||||
Vector3.UP,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
move_toward(movement: Vector3, delta: float64) {
|
||||
this.velocity = new Vector3(
|
||||
movement.x,
|
||||
this.velocity.y + this.get_gravitational_force(delta),
|
||||
movement.z
|
||||
)
|
||||
|
||||
this.move_and_slide()
|
||||
}
|
||||
|
||||
_physics_process(delta: float64): void {
|
||||
const input = this.player_input.movement_input
|
||||
|
||||
const movement = this.get_movement(input)
|
||||
|
||||
this._draw_movement(movement)
|
||||
|
||||
this.rotate_toward(movement, delta)
|
||||
this.move_toward(movement, delta)
|
||||
}
|
||||
}
|
||||
|
13
src/player_animation.js
Normal file
13
src/player_animation.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
class PlayerAnimation extends godot_1.AnimationTree {
|
||||
_ready() {
|
||||
this.player = this.get_parent();
|
||||
this.player_input = this.player.get_node(this.player.player_input);
|
||||
}
|
||||
}
|
||||
PlayerAnimation.Interact = 'parameters/interact';
|
||||
PlayerAnimation.WalkSpeed = 'parameters/Walk/blend_position';
|
||||
exports.default = PlayerAnimation;
|
||||
//# sourceMappingURL=player_animation.js.map
|
1
src/player_animation.js.map
Normal file
1
src/player_animation.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"player_animation.js","sourceRoot":"../../../","sources":["src/player_animation.ts"],"names":[],"mappings":";;AAAA,iCAAqC;AAIrC,MAAqB,eAAgB,SAAQ,qBAAa;IAOxD,MAAM;QACJ,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAY,CAAA;QACzC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,YAAa,CAAgB,CAAA;IACpF,CAAC;;AATc,wBAAQ,GAAG,qBAAqB,CAAA;AAChC,yBAAS,GAAG,gCAAgC,CAAA;kBAFxC,eAAe"}
|
18
src/player_animation.ts
Normal file
18
src/player_animation.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { AnimationTree, float64 } from 'godot'
|
||||
import Player from './player'
|
||||
import PlayerInput from './player_input'
|
||||
import { onready } from 'godot.annotations'
|
||||
|
||||
export default class PlayerAnimation extends AnimationTree {
|
||||
private static Interact = 'parameters/conditions/interact'
|
||||
private static Movement = 'parameters/Movement/blend_position'
|
||||
|
||||
@onready("../")
|
||||
player!: Player
|
||||
@onready("../Input")
|
||||
player_input!: PlayerInput
|
||||
|
||||
_process(delta: float64): void {
|
||||
this.set(PlayerAnimation.Movement, this.player.velocity.length_squared())
|
||||
}
|
||||
}
|
30
src/player_input.js
Normal file
30
src/player_input.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const godot_1 = require("godot");
|
||||
var Device;
|
||||
(function (Device) {
|
||||
Device[Device["KeyboardMouse"] = 0] = "KeyboardMouse";
|
||||
Device[Device["Gamepad"] = 1] = "Gamepad";
|
||||
})(Device || (Device = {}));
|
||||
class PlayerInput extends godot_1.Node3D {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this._last_known_device = Device.KeyboardMouse;
|
||||
this._movement_input = godot_1.Vector2.ZERO;
|
||||
}
|
||||
get last_known_device() { return this._last_known_device; }
|
||||
get movement_input() { return this._movement_input; }
|
||||
_process(delta) {
|
||||
this._movement_input = godot_1.Input.get_vector('move_left', 'move_right', 'move_forward', 'move_back');
|
||||
}
|
||||
_input(event) {
|
||||
if (event instanceof godot_1.InputEventKey || event instanceof godot_1.InputEventMouse) {
|
||||
this._last_known_device = Device.KeyboardMouse;
|
||||
}
|
||||
else if (event instanceof godot_1.InputEventJoypadButton || event instanceof godot_1.InputEventJoypadMotion) {
|
||||
this._last_known_device = Device.Gamepad;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.default = PlayerInput;
|
||||
//# sourceMappingURL=player_input.js.map
|
1
src/player_input.js.map
Normal file
1
src/player_input.js.map
Normal file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"player_input.js","sourceRoot":"../../../","sources":["src/player_input.ts"],"names":[],"mappings":";;AAAA,iCAAmJ;AAEnJ,IAAK,MAGJ;AAHD,WAAK,MAAM;IACT,qDAAiB,CAAA;IACjB,yCAAW,CAAA;AACb,CAAC,EAHI,MAAM,KAAN,MAAM,QAGV;AAED,MAAqB,WAAY,SAAQ,cAAM;IAA/C;;QACE,uBAAkB,GAAG,MAAM,CAAC,aAAa,CAAA;QAGzC,oBAAe,GAAY,eAAO,CAAC,IAAI,CAAA;IAczC,CAAC;IAhBC,IAAI,iBAAiB,KAAK,OAAO,IAAI,CAAC,kBAAkB,CAAA,CAAC,CAAC;IAG1D,IAAI,cAAc,KAAK,OAAO,IAAI,CAAC,eAAe,CAAA,CAAC,CAAC;IAEpD,QAAQ,CAAC,KAAc;QACrB,IAAI,CAAC,eAAe,GAAG,aAAK,CAAC,UAAU,CAAC,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,CAAC,CAAA;IACjG,CAAC;IAED,MAAM,CAAC,KAAiB;QACtB,IAAI,KAAK,YAAY,qBAAa,IAAI,KAAK,YAAY,uBAAe,EAAE,CAAC;YACvE,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,aAAa,CAAA;QAChD,CAAC;aAAM,IAAI,KAAK,YAAY,8BAAsB,IAAI,KAAK,YAAY,8BAAsB,EAAE,CAAC;YAC9F,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,OAAO,CAAA;QAC1C,CAAC;IACH,CAAC;CACF;AAlBD,8BAkBC"}
|
116
src/player_input.ts
Normal file
116
src/player_input.ts
Normal file
|
@ -0,0 +1,116 @@
|
|||
import { float64, Input, InputEvent, InputEventJoypadButton, InputEventJoypadMotion, InputEventKey, InputEventMouse, int32, Node3D, Signal0, Signal1, Variant, Vector2 } from 'godot'
|
||||
import { export_, signal } from 'godot.annotations'
|
||||
import InputBuffer from './input_buffer'
|
||||
|
||||
enum Device {
|
||||
KeyboardMouse = 0,
|
||||
Gamepad = 1
|
||||
}
|
||||
|
||||
export default class PlayerInput extends Node3D {
|
||||
@export_(Variant.Type.TYPE_INT)
|
||||
private input_buffer_size: int32 = 8
|
||||
|
||||
@export_(Variant.Type.TYPE_FLOAT)
|
||||
private min_range: float64 = 0.1
|
||||
private _min_range_sqr: float64 = 0.01
|
||||
|
||||
@export_(Variant.Type.TYPE_FLOAT)
|
||||
private max_range: float64 = 1
|
||||
private _max_range_sqr: float64 = 1
|
||||
|
||||
private _last_known_device = Device.KeyboardMouse
|
||||
|
||||
get last_known_device() { return this._last_known_device }
|
||||
|
||||
private _input_buffer!: InputBuffer
|
||||
|
||||
get input_buffer() {
|
||||
return this._input_buffer
|
||||
}
|
||||
|
||||
get movement_input() {
|
||||
const dir = this._input_buffer.head()
|
||||
if (dir.is_zero_approx()) {
|
||||
return Vector2.ZERO
|
||||
} else {
|
||||
const len = dir.length_squared()
|
||||
|
||||
if (len < this._min_range_sqr) {
|
||||
return Vector2.MULTIPLY(dir.normalized(), this.min_range)
|
||||
} else if (len > this._max_range_sqr) {
|
||||
return Vector2.MULTIPLY(dir.normalized(), this.max_range)
|
||||
} else {
|
||||
return dir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_running: boolean = false
|
||||
|
||||
get is_running() {
|
||||
return this._running
|
||||
}
|
||||
|
||||
@signal()
|
||||
readonly run!: Signal1<boolean>
|
||||
|
||||
_interacting: boolean = false
|
||||
|
||||
get is_interacting() {
|
||||
return this._interacting
|
||||
}
|
||||
|
||||
@signal()
|
||||
readonly interact!: Signal0
|
||||
|
||||
private _changed_since_last_frame = false
|
||||
|
||||
get changed_since_last_frame() {
|
||||
return this._changed_since_last_frame
|
||||
}
|
||||
|
||||
_sqr(n: number) {
|
||||
return n * n
|
||||
}
|
||||
|
||||
_ready(): void {
|
||||
this._min_range_sqr = this._sqr(this.min_range)
|
||||
this._max_range_sqr = this._sqr(this.max_range)
|
||||
|
||||
this._input_buffer = new InputBuffer(this.input_buffer_size)
|
||||
}
|
||||
|
||||
_process(_delta: float64): void {
|
||||
const next_input = Input.get_vector('move_left', 'move_right', 'move_up', 'move_down')
|
||||
|
||||
this._changed_since_last_frame = !next_input.is_equal_approx(this.movement_input)
|
||||
|
||||
this._input_buffer.push(next_input)
|
||||
|
||||
const running = Input.is_action_pressed('run')
|
||||
|
||||
if (running !== this._running) {
|
||||
this._running = running
|
||||
this.run.emit(running)
|
||||
}
|
||||
|
||||
const interacting = Input.is_action_pressed('interact')
|
||||
|
||||
if (interacting !== this._interacting) {
|
||||
this._interacting = interacting
|
||||
if (interacting) {
|
||||
this.interact.emit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_input(event: InputEvent): void {
|
||||
if (event instanceof InputEventKey || event instanceof InputEventMouse) {
|
||||
this._last_known_device = Device.KeyboardMouse
|
||||
} else if (event instanceof InputEventJoypadButton || event instanceof InputEventJoypadMotion) {
|
||||
this._last_known_device = Device.Gamepad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
113
tsconfig.json
Normal file
113
tsconfig.json
Normal file
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
"incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
"tsBuildInfoFile": ".godot/.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
||||
"experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "CommonJS", /* Specify what module code is generated. */
|
||||
"rootDir": "./", /* Specify the root folder within your source files. */
|
||||
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
||||
"typeRoots": [ /* Specify multiple folders that act like './node_modules/@types'. */
|
||||
"./node_modules/@types","./typings"
|
||||
],
|
||||
"types": [
|
||||
"node"
|
||||
], /* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
// "resolveJsonModule": true, /* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": ".godot/GodotJS", /* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
"sourceRoot": "../../../", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
"newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
"noEmitOnError": false, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
1
typings/.gdignore
Normal file
1
typings/.gdignore
Normal file
|
@ -0,0 +1 @@
|
|||
|
282
typings/godot.minimal.d.ts
vendored
Normal file
282
typings/godot.minimal.d.ts
vendored
Normal file
|
@ -0,0 +1,282 @@
|
|||
|
||||
declare module "godot-jsb" {
|
||||
import { Object as GDObject, PackedByteArray, PropertyUsageFlags, PropertyHint, MethodFlags, Variant, Callable0, Callable1, Callable2, Callable3, Callable4, Callable5, StringName, MultiplayerAPI, MultiplayerPeer } from "godot";
|
||||
|
||||
const DEV_ENABLED: boolean;
|
||||
const TOOLS_ENABLED: boolean;
|
||||
|
||||
/** version of GodotJS */
|
||||
const version: string;
|
||||
|
||||
/** impl currently used */
|
||||
const impl: string;
|
||||
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<R = void>(self: GDObject, fn: () => R): Callable0<R>;
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, R = void>(self: GDObject, fn: (v1: T1) => R): Callable1<T1, R>;
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, R = void>(self: GDObject, fn: (v1: T1, v2: T2) => R): Callable2<T1, T2, R>;
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, R = void>(self: GDObject, fn: (v1: T1, v2: T2, v3: T3) => R): Callable3<T1, T2, T3, R>;
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, T4, R = void>(self: GDObject, fn: (v1: T1, v2: T2, v3: T3, v4: T4) => R): Callable4<T1, T2, T3, T4, R>;
|
||||
/**
|
||||
* Create godot Callable with a bound object `self`.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, T4, T5, R = void>(self: GDObject, fn: (v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => R): Callable5<T1, T2, T3, T4, T5, R>;
|
||||
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<R = void>(fn: () => R): Callable0<R>;
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, R = void>(fn: (v1: T1) => R): Callable1<T1, R>;
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, R = void>(fn: (v1: T1, v2: T2) => R): Callable2<T1, T2, R>;
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, R = void>(fn: (v1: T1, v2: T2, v3: T3) => R): Callable3<T1, T2, T3, R>;
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, T4, R = void>(fn: (v1: T1, v2: T2, v3: T3, v4: T4) => R): Callable4<T1, T2, T3, T4, R>;
|
||||
/**
|
||||
* Create godot Callable without a bound object.
|
||||
* @deprecated [WARNING] avoid using this function directly, use `Callable.create` instead.
|
||||
*/
|
||||
function callable<T1, T2, T3, T4, T5, R = void>(fn: (v1: T1, v2: T2, v3: T3, v4: T4, v5: T5) => R): Callable5<T1, T2, T3, T4, T5, R>;
|
||||
|
||||
/**
|
||||
* Explicitly convert a `PackedByteArray`(aka `Vector<uint8_t>`) into a javascript `ArrayBuffer`
|
||||
* @deprecated [WARNING] This free function '_to_array_buffer' is deprecated and will be removed in a future version, use 'PackedByteArray.to_array_buffer()' instead.
|
||||
*/
|
||||
function to_array_buffer(packed: PackedByteArray): ArrayBuffer;
|
||||
|
||||
interface ScriptPropertyInfo {
|
||||
name: string;
|
||||
type: Variant.Type;
|
||||
class_?: Function;
|
||||
hint?: number;
|
||||
hint_string?: string;
|
||||
usage?: number;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
type OnReadyEvaluatorFunc = (self: any) => any;
|
||||
|
||||
interface RPCConfig {
|
||||
mode?: MultiplayerAPI.RPCMode,
|
||||
sync?: boolean,
|
||||
transfer_mode?: MultiplayerPeer.TransferMode,
|
||||
transfer_channel?: number,
|
||||
}
|
||||
|
||||
function add_script_signal(target: any, name: string): void;
|
||||
function add_script_property(target: any, details: ScriptPropertyInfo): void;
|
||||
function add_script_ready(target: any, details: { name: string, evaluator: string | OnReadyEvaluatorFunc }): void;
|
||||
function add_script_tool(target: any): void;
|
||||
function add_script_icon(target: any, path: string): void;
|
||||
function add_script_rpc(target: any, propertyKey: string, config: RPCConfig): void;
|
||||
|
||||
// 0: deprecated, 1: experimental, 2: help
|
||||
function set_script_doc(target: any, propertyKey?: string, field: 0 | 1 | 2, message: string): void;
|
||||
|
||||
function add_module(id: string, obj: any): void;
|
||||
function find_module(id: string): any;
|
||||
function notify_microtasks_run(): void;
|
||||
|
||||
/**
|
||||
* Get the transformed type name of a Variant.Type
|
||||
*/
|
||||
function get_type_name(type: Variant.Type): StringName;
|
||||
}
|
||||
|
||||
namespace editor {
|
||||
interface PrimitiveConstantInfo {
|
||||
name: string;
|
||||
type: Variant.Type;
|
||||
value: number; /* only if type is literal */
|
||||
}
|
||||
|
||||
interface ConstantInfo {
|
||||
name: string;
|
||||
value: number; /** int64_t */
|
||||
}
|
||||
|
||||
interface EnumInfo {
|
||||
name: string;
|
||||
|
||||
literals: Array<string>;
|
||||
is_bitfield: boolean;
|
||||
}
|
||||
|
||||
interface DefaultArgumentInfo {
|
||||
type: Variant.Type;
|
||||
value: any;
|
||||
}
|
||||
|
||||
// we treat godot MethodInfo/MethodBind as the same thing here for simplicity
|
||||
//NOTE some fields will not be set if it's actually a MethodInfo struct
|
||||
interface MethodBind {
|
||||
id: number;
|
||||
name: string;
|
||||
|
||||
hint_flags: MethodFlags;
|
||||
is_static: boolean;
|
||||
is_const: boolean;
|
||||
is_vararg: boolean;
|
||||
argument_count: number; /** int32_t */
|
||||
|
||||
args_: Array<PropertyInfo>;
|
||||
default_arguments?: Array<DefaultArgumentInfo>;
|
||||
return_: PropertyInfo | undefined;
|
||||
}
|
||||
|
||||
interface PropertyInfo {
|
||||
name: string;
|
||||
type: Variant.Type;
|
||||
class_name: string;
|
||||
hint: PropertyHint;
|
||||
hint_string: string;
|
||||
usage: PropertyUsageFlags;
|
||||
}
|
||||
|
||||
interface PropertySetGetInfo {
|
||||
name: string;
|
||||
|
||||
type: Variant.Type;
|
||||
index: number;
|
||||
setter: string;
|
||||
getter: string;
|
||||
|
||||
info: PropertyInfo;
|
||||
}
|
||||
|
||||
interface PrimitiveGetSetInfo {
|
||||
name: string;
|
||||
type: Variant.Type;
|
||||
}
|
||||
|
||||
interface SignalInfo {
|
||||
name: string;
|
||||
method_: MethodBind;
|
||||
}
|
||||
|
||||
interface ArgumentInfo {
|
||||
name: string;
|
||||
type: Variant.Type;
|
||||
}
|
||||
|
||||
interface ConstructorInfo {
|
||||
arguments: Array<ArgumentInfo>
|
||||
}
|
||||
|
||||
interface OperatorInfo {
|
||||
name: string;
|
||||
return_type: Variant.Type;
|
||||
left_type: Variant.Type;
|
||||
right_type: Variant.Type;
|
||||
}
|
||||
|
||||
interface BasicClassInfo {
|
||||
name: string;
|
||||
methods: Array<MethodBind>;
|
||||
enums?: Array<EnumInfo>;
|
||||
}
|
||||
|
||||
// godot class
|
||||
interface ClassInfo extends BasicClassInfo {
|
||||
super: string;
|
||||
|
||||
properties: Array<PropertySetGetInfo>;
|
||||
virtual_methods: Array<MethodBind>;
|
||||
signals: Array<SignalInfo>;
|
||||
constants?: Array<ConstantInfo>;
|
||||
}
|
||||
|
||||
// variant class
|
||||
interface PrimitiveClassInfo extends BasicClassInfo {
|
||||
// self type
|
||||
type: Variant.Type;
|
||||
|
||||
// valid only if has_indexing
|
||||
element_type?: Variant.Type;
|
||||
|
||||
// true only if is_keyed
|
||||
is_keyed: boolean;
|
||||
|
||||
constructors: Array<ConstructorInfo>;
|
||||
operators: Array<OperatorInfo>;
|
||||
properties: Array<PrimitiveGetSetInfo>;
|
||||
constants?: Array<PrimitiveConstantInfo>;
|
||||
}
|
||||
|
||||
interface SingletonInfo {
|
||||
name: string;
|
||||
class_name: string;
|
||||
user_created: boolean;
|
||||
editor_only: boolean;
|
||||
}
|
||||
|
||||
interface GlobalConstantInfo {
|
||||
name: string;
|
||||
values: { [name: string]: number /** int64_t */ };
|
||||
}
|
||||
|
||||
interface ClassDoc {
|
||||
brief_description: string;
|
||||
|
||||
constants: { [name: string]: { description: string } };
|
||||
methods: { [name: string]: { description: string } };
|
||||
properties: { [name: string]: { description: string } };
|
||||
signals: { [name: string]: { description: string } };
|
||||
}
|
||||
|
||||
function get_class_doc(class_name: string): ClassDoc | undefined;
|
||||
|
||||
/**
|
||||
* get a list of all classes registered in ClassDB
|
||||
*/
|
||||
function get_classes(): Array<ClassInfo>;
|
||||
|
||||
function get_primitive_types(): Array<PrimitiveClassInfo>;
|
||||
|
||||
function get_singletons(): Array<SingletonInfo>;
|
||||
|
||||
function get_global_constants(): Array<GlobalConstantInfo>;
|
||||
|
||||
function get_utility_functions(): Array<MethodBind>;
|
||||
|
||||
function delete_file(filepath: string): void;
|
||||
|
||||
const VERSION_DOCS_URL: string;
|
||||
}
|
||||
}
|
||||
|
186
typings/godot.mix.d.ts
vendored
Normal file
186
typings/godot.mix.d.ts
vendored
Normal file
|
@ -0,0 +1,186 @@
|
|||
/// <reference no-default-lib="true"/>
|
||||
declare module "godot" {
|
||||
/** A built-in type representing a method or a standalone function.
|
||||
*
|
||||
* @link https://docs.godotengine.org/en/4.2/classes/class_callable.html
|
||||
*/
|
||||
interface AnyCallable {
|
||||
/** Returns `true` if this [Callable] has no target to call the method on. */
|
||||
is_null(): boolean
|
||||
|
||||
/** Returns `true` if this [Callable] is a custom callable. Custom callables are created from [method bind] or [method unbind]. In GDScript, lambda functions are also custom callables. */
|
||||
is_custom(): boolean
|
||||
|
||||
/** Returns `true` if this [Callable] is a standard callable. This method is the opposite of [method is_custom]. Returns `false` if this callable is a lambda function. */
|
||||
is_standard(): boolean
|
||||
|
||||
/** Returns `true` if the callable's object exists and has a valid method name assigned, or is a custom callable. */
|
||||
is_valid(): boolean
|
||||
|
||||
/** Returns the object on which this [Callable] is called. */
|
||||
get_object(): Object
|
||||
|
||||
/** Returns the ID of this [Callable]'s object (see [method Object.get_instance_id]). */
|
||||
get_object_id(): int64
|
||||
|
||||
/** Returns the name of the method represented by this [Callable]. If the callable is a GDScript lambda function, returns the function's name or `"<anonymous lambda>"`. */
|
||||
get_method(): StringName
|
||||
|
||||
/** Returns the total amount of arguments bound (or unbound) via successive [method bind] or [method unbind] calls. If the amount of arguments unbound is greater than the ones bound, this function returns a value less than zero. */
|
||||
get_bound_arguments_count(): int64
|
||||
|
||||
/** Return the bound arguments (as long as [method get_bound_arguments_count] is greater than zero), or empty (if [method get_bound_arguments_count] is less than or equal to zero). */
|
||||
get_bound_arguments(): Array
|
||||
|
||||
/** Returns the 32-bit hash value of this [Callable]'s object.
|
||||
*
|
||||
* **Note:** [Callable]s with equal content will always produce identical hash values. However, the reverse is not true. Returning identical hash values does *not* imply the callables are equal, because different callables can have identical hash values due to hash collisions. The engine uses a 32-bit hash algorithm for [method hash].
|
||||
*/
|
||||
hash(): int64
|
||||
|
||||
/** Returns a copy of this [Callable] with one or more arguments bound. When called, the bound arguments are passed *after* the arguments supplied by [method call]. See also [method unbind].
|
||||
*
|
||||
* **Note:** When this method is chained with other similar methods, the order in which the argument list is modified is read from right to left.
|
||||
*/
|
||||
bind(...vargargs: any[]): AnyCallable
|
||||
|
||||
/** Returns a copy of this [Callable] with one or more arguments bound, reading them from an array. When called, the bound arguments are passed *after* the arguments supplied by [method call]. See also [method unbind].
|
||||
*
|
||||
* **Note:** When this method is chained with other similar methods, the order in which the argument list is modified is read from right to left.
|
||||
*/
|
||||
bindv(arguments_: GArray): AnyCallable
|
||||
|
||||
/** Returns a copy of this [Callable] with a number of arguments unbound. In other words, when the new callable is called the last few arguments supplied by the user are ignored, according to [param argcount]. The remaining arguments are passed to the callable. This allows to use the original callable in a context that attempts to pass more arguments than this callable can handle, e.g. a signal with a fixed number of arguments. See also [method bind].
|
||||
*
|
||||
* **Note:** When this method is chained with other similar methods, the order in which the argument list is modified is read from right to left.
|
||||
*
|
||||
*/
|
||||
unbind(argcount: int64): AnyCallable
|
||||
|
||||
/** Calls the method represented by this [Callable]. Arguments can be passed and should match the method's signature. */
|
||||
call(...vargargs: any[]): any
|
||||
|
||||
/** Calls the method represented by this [Callable]. Unlike [method call], this method expects all arguments to be contained inside the [param arguments] [Array]. */
|
||||
callv(arguments_: GArray): any
|
||||
|
||||
/** Calls the method represented by this [Callable] in deferred mode, i.e. at the end of the current frame. Arguments can be passed and should match the method's signature.
|
||||
*
|
||||
*
|
||||
* **Note:** Deferred calls are processed at idle time. Idle time happens mainly at the end of process and physics frames. In it, deferred calls will be run until there are none left, which means you can defer calls from other deferred calls and they'll still be run in the current idle time cycle. This means you should not call a method deferred from itself (or from a method called by it), as this causes infinite recursion the same way as if you had called the method directly.
|
||||
* See also [method Object.call_deferred].
|
||||
*/
|
||||
call_deferred(...vargargs: any[]): void
|
||||
}
|
||||
|
||||
/** A built-in type representing a signal of an [Object].
|
||||
*
|
||||
* @link https://docs.godotengine.org/en/4.2/classes/class_signal.html
|
||||
*/
|
||||
interface AnySignal {
|
||||
/** Returns `true` if the signal's name does not exist in its object, or the object is not valid. */
|
||||
is_null(): boolean
|
||||
|
||||
/** Returns the object emitting this signal. */
|
||||
get_object(): Object
|
||||
|
||||
/** Returns the ID of the object emitting this signal (see [method Object.get_instance_id]). */
|
||||
get_object_id(): int64
|
||||
|
||||
/** Returns the name of this signal. */
|
||||
get_name(): StringName
|
||||
|
||||
/** Returns `true` if the specified [Callable] is connected to this signal. */
|
||||
is_connected(callable: AnyCallable): boolean
|
||||
|
||||
/** Returns an [Array] of connections for this signal. Each connection is represented as a [Dictionary] that contains three entries:
|
||||
* - `signal` is a reference to this signal;
|
||||
* - `callable` is a reference to the connected [Callable];
|
||||
* - `flags` is a combination of [enum Object.ConnectFlags].
|
||||
*/
|
||||
get_connections(): Array
|
||||
}
|
||||
|
||||
interface Callable0<R = void> extends AnyCallable {
|
||||
call(): R;
|
||||
}
|
||||
|
||||
interface Callable1<T1, R = void> extends AnyCallable {
|
||||
call(v1: T1): R;
|
||||
}
|
||||
|
||||
interface Callable2<T1, T2, R = void> extends AnyCallable {
|
||||
call(v1: T1, v2, T2): R;
|
||||
}
|
||||
|
||||
interface Callable3<T1, T2, T3, R = void> extends AnyCallable {
|
||||
call(v1: T1, v2: T2, v3: T3): R;
|
||||
}
|
||||
|
||||
interface Callable4<T1, T2, T3, T4, R = void> extends AnyCallable {
|
||||
call(v1: T1, v2: T2, v3: T3, v4: T4): R;
|
||||
}
|
||||
|
||||
interface Callable5<T1, T2, T3, T4, T5, R = void> extends AnyCallable {
|
||||
call(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5): R;
|
||||
}
|
||||
|
||||
interface Signal0 extends AnySignal {
|
||||
connect(callable: Callable0, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable0): void;
|
||||
is_connected(callable: Callable0): boolean;
|
||||
emit(): void;
|
||||
|
||||
as_promise(): Promise<void>;
|
||||
}
|
||||
|
||||
interface Signal1<T1> extends AnySignal {
|
||||
connect(callable: Callable1<T1>, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable1<T1>): void;
|
||||
is_connected(callable: Callable1<T1>): boolean;
|
||||
emit(v1: T1): void;
|
||||
|
||||
// the first argument is used as the resolved value
|
||||
as_promise(): Promise<T1>;
|
||||
}
|
||||
|
||||
interface Signal2<T1, T2> extends AnySignal {
|
||||
connect(callable: Callable2<T1, T2>, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable2<T1, T2>): void;
|
||||
is_connected(callable: Callable2<T1, T2>): boolean;
|
||||
emit(v1: T1, v2: T2): void;
|
||||
|
||||
// the first argument is used as the resolved value
|
||||
as_promise(): Promise<T1>;
|
||||
}
|
||||
|
||||
interface Signal3<T1, T2, T3> extends AnySignal {
|
||||
connect(callable: Callable3<T1, T2, T3>, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable3<T1, T2, T3>): void;
|
||||
is_connected(callable: Callable3<T1, T2, T3>): boolean;
|
||||
emit(v1: T1, v2: T2, v3: T3): void;
|
||||
|
||||
// the first argument is used as the resolved value
|
||||
as_promise(): Promise<T1>;
|
||||
}
|
||||
|
||||
interface Signal4<T1, T2, T3, T4> extends AnySignal {
|
||||
connect(callable: Callable4<T1, T2, T3, T4>, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable4<T1, T2, T3, T4>): void;
|
||||
is_connected(callable: Callable4<T1, T2, T3, T4>): boolean;
|
||||
emit(v1: T1, v2: T2, v3: T3, v4: T4): void;
|
||||
|
||||
// the first argument is used as the resolved value
|
||||
as_promise(): Promise<T1>;
|
||||
}
|
||||
|
||||
interface Signal5<T1, T2, T3, T4, T5> extends AnySignal {
|
||||
connect(callable: Callable5<T1, T2, T3, T4, T5>, flags: int64 = 0): void;
|
||||
disconnect(callable: Callable5<T1, T2, T3, T4, T5>): void;
|
||||
is_connected(callable: Callable5<T1, T2, T3, T4, T5>): boolean;
|
||||
emit(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5): void;
|
||||
|
||||
// the first argument is used as the resolved value
|
||||
as_promise(): Promise<T1>;
|
||||
}
|
||||
|
||||
}
|
11172
typings/godot0.gen.d.ts
vendored
Normal file
11172
typings/godot0.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9364
typings/godot1.gen.d.ts
vendored
Normal file
9364
typings/godot1.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9333
typings/godot2.gen.d.ts
vendored
Normal file
9333
typings/godot2.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9542
typings/godot3.gen.d.ts
vendored
Normal file
9542
typings/godot3.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9809
typings/godot4.gen.d.ts
vendored
Normal file
9809
typings/godot4.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9679
typings/godot5.gen.d.ts
vendored
Normal file
9679
typings/godot5.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
9426
typings/godot6.gen.d.ts
vendored
Normal file
9426
typings/godot6.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
7876
typings/godot7.gen.d.ts
vendored
Normal file
7876
typings/godot7.gen.d.ts
vendored
Normal file
File diff suppressed because it is too large
Load diff
64
typings/jsb.editor.bundle.d.ts
vendored
Normal file
64
typings/jsb.editor.bundle.d.ts
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
declare module "jsb.editor.codegen" {
|
||||
import * as jsb from "godot-jsb";
|
||||
export class TypeDB {
|
||||
singletons: {
|
||||
[name: string]: jsb.editor.SingletonInfo;
|
||||
};
|
||||
classes: {
|
||||
[name: string]: jsb.editor.ClassInfo;
|
||||
};
|
||||
primitive_types: {
|
||||
[name: string]: jsb.editor.PrimitiveClassInfo;
|
||||
};
|
||||
primitive_type_names: {
|
||||
[type: number]: string;
|
||||
};
|
||||
globals: {
|
||||
[name: string]: jsb.editor.GlobalConstantInfo;
|
||||
};
|
||||
utilities: {
|
||||
[name: string]: jsb.editor.MethodBind;
|
||||
};
|
||||
class_docs: {
|
||||
[name: string]: jsb.editor.ClassDoc | false;
|
||||
};
|
||||
constructor();
|
||||
find_doc(class_name: string): jsb.editor.ClassDoc | undefined;
|
||||
is_primitive_type(name: string): boolean;
|
||||
is_valid_method_name(name: string): boolean;
|
||||
make_classname(class_name: string, used_as_input: boolean): string;
|
||||
make_typename(info: jsb.editor.PropertyInfo, used_as_input: boolean): string;
|
||||
make_arg(info: jsb.editor.PropertyInfo, type_replacer?: (name: string) => string): string;
|
||||
make_literal_value(value: jsb.editor.DefaultArgumentInfo): string;
|
||||
replace_type_inplace(name: string | undefined, type_replacer?: (name: string) => string): string;
|
||||
make_arg_default_value(method_info: jsb.editor.MethodBind, index: number, type_replacer?: (name: string) => string): string;
|
||||
make_args(method_info: jsb.editor.MethodBind, type_replacer?: (name: string) => string): string;
|
||||
make_return(method_info: jsb.editor.MethodBind, type_replacer?: (name: string) => string): string;
|
||||
make_signal_type(method_info: jsb.editor.MethodBind): string;
|
||||
}
|
||||
export default class TSDCodeGen {
|
||||
private _split_index;
|
||||
private _outDir;
|
||||
private _splitter;
|
||||
private _types;
|
||||
constructor(outDir: string);
|
||||
private make_path;
|
||||
private new_splitter;
|
||||
private split;
|
||||
private cleanup;
|
||||
has_class(name?: string): boolean;
|
||||
emit(): void;
|
||||
private emit_mock;
|
||||
private emit_singletons;
|
||||
private emit_utilities;
|
||||
private emit_globals;
|
||||
private emit_godot;
|
||||
private emit_godot_primitive;
|
||||
private emit_godot_class;
|
||||
}
|
||||
}
|
||||
declare module "jsb.editor.main" {
|
||||
import { PackedStringArray } from "godot";
|
||||
export function auto_complete(pattern: string): PackedStringArray;
|
||||
export function run_npm_install(): void;
|
||||
}
|
68
typings/jsb.runtime.bundle.d.ts
vendored
Normal file
68
typings/jsb.runtime.bundle.d.ts
vendored
Normal file
|
@ -0,0 +1,68 @@
|
|||
declare module "godot.annotations" {
|
||||
import { PropertyHint, PropertyUsageFlags, Variant, MultiplayerAPI, MultiplayerPeer } from "godot";
|
||||
import * as jsb from "godot-jsb";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
export function signal(): (target: any, key: string) => void;
|
||||
export function export_multiline(): (target: any, key: string) => void;
|
||||
export function export_range(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, key: string) => void;
|
||||
export function export_range_i(min: number, max: number, step?: number, ...extra_hints: string[]): (target: any, key: string) => void;
|
||||
/** String as a path to a file, custom filter provided as hint. */
|
||||
export function export_file(filter: string): (target: any, key: string) => void;
|
||||
export function export_dir(filter: string): (target: any, key: string) => void;
|
||||
export function export_global_file(filter: string): (target: any, key: string) => void;
|
||||
export function export_global_dir(filter: string): (target: any, key: string) => void;
|
||||
export function export_exp_easing(hint?: "" | "attenuation" | "positive_only" | "attenuation,positive_only"): (target: any, key: string) => void;
|
||||
export function export_(type: Variant.Type, details?: {
|
||||
class_?: Function;
|
||||
hint?: PropertyHint;
|
||||
hint_string?: string;
|
||||
usage?: PropertyUsageFlags;
|
||||
}): (target: any, key: string) => void;
|
||||
/**
|
||||
* In Godot, class members can be exported.
|
||||
* This means their value gets saved along with the resource (such as the scene) they're attached to.
|
||||
* They will also be available for editing in the property editor.
|
||||
* Exporting is done by using the `@export_var` (or `@export_`) annotation.
|
||||
*/
|
||||
export function export_var(type: Variant.Type, details?: {
|
||||
class_?: Function;
|
||||
hint?: PropertyHint;
|
||||
hint_string?: string;
|
||||
usage?: PropertyUsageFlags;
|
||||
}): (target: any, key: string) => void;
|
||||
/**
|
||||
* NOTE only int value enums are allowed
|
||||
*/
|
||||
export function export_enum(enum_type: any): (target: any, key: string) => void;
|
||||
/**
|
||||
* NOTE only int value enums are allowed
|
||||
*/
|
||||
export function export_flags(enum_type: any): (target: any, key: string) => void;
|
||||
export interface RPCConfig {
|
||||
mode?: MultiplayerAPI.RPCMode;
|
||||
sync?: "call_remote" | "call_local";
|
||||
transfer_mode?: MultiplayerPeer.TransferMode;
|
||||
transfer_channel?: number;
|
||||
}
|
||||
export function rpc(config?: RPCConfig): (target: any, propertyKey?: PropertyKey, descriptor?: PropertyDescriptor) => void;
|
||||
/**
|
||||
* auto initialized on ready (before _ready called)
|
||||
* @param evaluator for now, only string is accepted
|
||||
*/
|
||||
export function onready(evaluator: string | jsb.internal.OnReadyEvaluatorFunc): (target: any, key: string) => void;
|
||||
export function tool(): (target: any) => void;
|
||||
export function icon(path: string): (target: any) => void;
|
||||
export function deprecated(message?: string): (target: any, propertyKey?: PropertyKey, descriptor?: PropertyDescriptor) => void;
|
||||
export function experimental(message?: string): (target: any, propertyKey?: PropertyKey, descriptor?: PropertyDescriptor) => void;
|
||||
export function help(message?: string): (target: any, propertyKey?: PropertyKey, descriptor?: PropertyDescriptor) => void;
|
||||
}
|
||||
declare module "godot.typeloader" {
|
||||
/**
|
||||
* @param type the loaded type or function in godot module
|
||||
*/
|
||||
export type TypeLoadedCallback = (type: any) => void;
|
||||
export function on_type_loaded(type_name: string | string[], callback: TypeLoadedCallback): void;
|
||||
}
|
||||
declare module "jsb.core" { }
|
Loading…
Add table
Reference in a new issue