Show network Ping & start AI behaviour tree

This commit is contained in:
2023-01-22 23:44:41 +01:00
parent ce7b74c832
commit 26f17fbd03
89 changed files with 2839 additions and 53 deletions

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,7 @@
[plugin]
name="Yet Another Behavior Tree"
description="A Behavior Tree implementation for Godot Engine"
author="Adrien Quillet"
version="2.0.0"
script="yet_another_behavior_tree.gd"

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b48sosvxi4n24"
path="res://.godot/imported/btaction.png-18977c497a76704723d083978b2ea595.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png"
dest_files=["res://.godot/imported/btaction.png-18977c497a76704723d083978b2ea595.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cbnehk2kgxha0"
path="res://.godot/imported/btactionblackboarddelete.png-e03a9a160a95593083f9e35e81bdc103.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png"
dest_files=["res://.godot/imported/btactionblackboarddelete.png-e03a9a160a95593083f9e35e81bdc103.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://boyttypw3logy"
path="res://.godot/imported/btactionblackboardset.png-1278deabaaedde513ea46a9a4bb621bb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png"
dest_files=["res://.godot/imported/btactionblackboardset.png-1278deabaaedde513ea46a9a4bb621bb.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://2oj3rjstv2l6"
path="res://.godot/imported/btactioncallable.png-8ff3e8c57248454d9afe7b8c14b8034f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btactioncallable.png"
dest_files=["res://.godot/imported/btactioncallable.png-8ff3e8c57248454d9afe7b8c14b8034f.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ct3k7bwcr4n23"
path="res://.godot/imported/btactionwait.png-35eefe67990a95ed2449e53d56e2cf8f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png"
dest_files=["res://.godot/imported/btactionwait.png-35eefe67990a95ed2449e53d56e2cf8f.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bc3t7dlq5ojd7"
path="res://.godot/imported/btblackboard.png-7f733cee4dbff616004368a725149731.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png"
dest_files=["res://.godot/imported/btblackboard.png-7f733cee4dbff616004368a725149731.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://61mky8di67wd"
path="res://.godot/imported/btcomposite.png-e026d4d004e93322dbcd1e6f926f41a2.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png"
dest_files=["res://.godot/imported/btcomposite.png-e026d4d004e93322dbcd1e6f926f41a2.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d30ihyblas1o0"
path="res://.godot/imported/btcondition.png-afc407604bdfe2e82f2cbf0d2c34ed27.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png"
dest_files=["res://.godot/imported/btcondition.png-afc407604bdfe2e82f2cbf0d2c34ed27.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b4q7fnl5uons7"
path="res://.godot/imported/btconditionblackboardkeyexists.png-6b1c537ccdd672a561e7966389cda13e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardkeyexists.png"
dest_files=["res://.godot/imported/btconditionblackboardkeyexists.png-6b1c537ccdd672a561e7966389cda13e.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://fcjo6te2i4fh"
path="res://.godot/imported/btconditionblackboardvaluescomparison.png-eecd4feaf86eb841c950cbbeb86bd20e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardvaluescomparison.png"
dest_files=["res://.godot/imported/btconditionblackboardvaluescomparison.png-eecd4feaf86eb841c950cbbeb86bd20e.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://y6usgtpm8654"
path="res://.godot/imported/btconditioncallable.png-536cf1db6a6b7ab4d372e700c9ec5b2a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditioncallable.png"
dest_files=["res://.godot/imported/btconditioncallable.png-536cf1db6a6b7ab4d372e700c9ec5b2a.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cmwqhdcyhptro"
path="res://.godot/imported/btdecorator.png-8fdc93bf956127379273d9a2949c9c1c.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png"
dest_files=["res://.godot/imported/btdecorator.png-8fdc93bf956127379273d9a2949c9c1c.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c73l5rvxyrnda"
path="res://.godot/imported/btfailure.png-43c62fa29ae4a153c528e033a8bbecc9.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png"
dest_files=["res://.godot/imported/btfailure.png-43c62fa29ae4a153c528e033a8bbecc9.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://gutmaw46jlyh"
path="res://.godot/imported/btinverter.png-2f7d6a7358d40fcfcaf67b8a6acea047.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png"
dest_files=["res://.godot/imported/btinverter.png-2f7d6a7358d40fcfcaf67b8a6acea047.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://gxdluh7wjomk"
path="res://.godot/imported/btleaf.png-c2431b3a96122c6dc535e0b78c164efc.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btleaf.png"
dest_files=["res://.godot/imported/btleaf.png-c2431b3a96122c6dc535e0b78c164efc.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://byk2pkxf1m2xm"
path="res://.godot/imported/btlimiter.png-4154342ba1ecd7c753485e0c1895d99d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png"
dest_files=["res://.godot/imported/btlimiter.png-4154342ba1ecd7c753485e0c1895d99d.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://sccepp5a5goa"
path="res://.godot/imported/btnode.png-3ebad094cfaf4e989cef065b27b78174.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png"
dest_files=["res://.godot/imported/btnode.png-3ebad094cfaf4e989cef065b27b78174.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://i8yclvjdd2po"
path="res://.godot/imported/btparallel.png-72c2892f41b80e22bfa4396abf59a1a3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png"
dest_files=["res://.godot/imported/btparallel.png-72c2892f41b80e22bfa4396abf59a1a3.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cj1bxkdykjv23"
path="res://.godot/imported/btrandom.png-0f3e4c1202cc1fd7fd32f36ce482ef97.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png"
dest_files=["res://.godot/imported/btrandom.png-0f3e4c1202cc1fd7fd32f36ce482ef97.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b3s6eyhvmsmca"
path="res://.godot/imported/btrandomselector.png-5bbaa6b1d149c5357046de0f8d6b7707.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png"
dest_files=["res://.godot/imported/btrandomselector.png-5bbaa6b1d149c5357046de0f8d6b7707.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dtc18hhykvswh"
path="res://.godot/imported/btrepeatuntil.png-b92f22528a4b73d0ca2d27142e092367.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png"
dest_files=["res://.godot/imported/btrepeatuntil.png-b92f22528a4b73d0ca2d27142e092367.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bs628dnvnsxwl"
path="res://.godot/imported/btroot.png-5ce207fd487015fa6d9a79efff94f0e4.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png"
dest_files=["res://.godot/imported/btroot.png-5ce207fd487015fa6d9a79efff94f0e4.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ctyhhfi6jks5a"
path="res://.godot/imported/btselector.png-68934baa4bd97bc50fd24775d28386ac.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png"
dest_files=["res://.godot/imported/btselector.png-68934baa4bd97bc50fd24775d28386ac.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://chnob03fb7a5"
path="res://.godot/imported/btsequence.png-c2e63f47520b7d091ffbf0c6bc2a76a0.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png"
dest_files=["res://.godot/imported/btsequence.png-c2e63f47520b7d091ffbf0c6bc2a76a0.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://v47uxlomir5w"
path="res://.godot/imported/btsuccess.png-7ab9f0bea97f3881521c44275dcb2c13.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png"
dest_files=["res://.godot/imported/btsuccess.png-7ab9f0bea97f3881521c44275dcb2c13.ctex"]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
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

View File

@@ -0,0 +1,59 @@
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png")
extends Node
class_name BTBlackboard
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
@export var data:Dictionary = {}
#------------------------------------------
# Variables privées
#------------------------------------------
var _execution_data:Dictionary = {}
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _ready() -> void:
# On copie le dico défini par l'utilisateur dans le dico privé
_execution_data.merge(data)
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func get_delta() -> float:
return get_data("delta")
func has_data(key:Variant) -> bool:
return get_data(key) != null
func get_data(key:Variant, default_value:Variant = null) -> Variant:
var result:Variant = _execution_data.get(key, default_value)
return result.get_ref() if result is WeakRef else result
func set_data(key:Variant, value:Variant) -> Variant:
var old_value:Variant = _execution_data[key] if _execution_data.has(key) else null
_execution_data[key] = weakref(value) if value is Node else value
return old_value.get_ref() if old_value is WeakRef else old_value
func delete_data(key:Variant) -> Variant:
var old_value = _execution_data[key] if _execution_data.has(key) else null
_execution_data.erase(key)
return old_value.get_ref() if old_value is WeakRef else old_value
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,116 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png")
extends Node
class_name BTNode
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
@onready var _is_in_editor:bool = Engine.is_editor_hint()
var _children:Array[BTNode] = []
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _init() -> void:
super._init()
if _is_in_editor:
child_entered_tree.connect(_update_configuration_warnings_1)
child_exiting_tree.connect(_update_configuration_warnings_1)
tree_entered.connect(_update_configuration_warnings_0)
tree_exited.connect(_update_configuration_warnings_0)
child_entered_tree.connect(_update_cached_children)
child_exiting_tree.connect(_update_cached_children)
func _ready() -> void:
if _is_in_editor:
update_configuration_warnings()
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
return BTTickResult.SUCCESS
func is_leaf() -> bool:
return false
func enter(blackboard:BTBlackboard) -> void:
pass
func start(blackboard:BTBlackboard) -> void:
pass
func stop(blackboard:BTBlackboard) -> void:
pass
func exit(blackboard:BTBlackboard) -> void:
pass
#------------------------------------------
# Fonctions privées
#------------------------------------------
func _update_configuration_warnings_0() -> void:
update_configuration_warnings()
func _update_configuration_warnings_1(any) -> void:
update_configuration_warnings()
func is_valid() -> bool:
return false
func _update_cached_children(any) -> void:
_children = get_children().map(_node_as_bt_node)
func _execute(actor:Node2D, blackboard:BTBlackboard) -> int:
if _is_in_editor:
return BTTickResult.FAILURE
_enter(blackboard);
_start(blackboard)
var result:int = tick(actor, blackboard)
if result != BTTickResult.RUNNING:
_stop(blackboard)
_exit(blackboard)
return result
func _node_as_bt_node(node:Node) -> BTNode:
return node as BTNode
func _enter(blackboard:BTBlackboard) -> void:
enter(blackboard)
pass
func _start(blackboard:BTBlackboard) -> void:
blackboard.get_data("running_nodes", []).append(self)
if not blackboard.get_data("previously_running_nodes", []).has(self):
start(blackboard)
func _stop(blackboard:BTBlackboard) -> void:
blackboard.get_data("running_nodes", []).erase(self)
stop(blackboard)
func _exit(blackboard:BTBlackboard) -> void:
exit(blackboard)
pass

View File

@@ -0,0 +1,162 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png")
extends BTNode
class_name BTRoot
enum BTRootProcessMode {
PROCESS,
PHYSIC_PROCESS
}
#------------------------------------------
# Signaux
#------------------------------------------
signal on_running(running_node_names:Array)
signal on_idle()
#------------------------------------------
# Exports
#------------------------------------------
@export var enabled:bool = true:
set(value):
enabled = value
set_process(enabled)
set_physics_process(enabled)
@export var root_process_mode:BTRootProcessMode = BTRootProcessMode.PHYSIC_PROCESS
@export var actor_path:NodePath :
set(value):
actor_path = value
_update_actor_from_path()
update_configuration_warnings()
@export var blackboard:BTBlackboard = null :
set(value):
blackboard = value
update_configuration_warnings()
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _blackboard:BTBlackboard
var _previous_running_nodes:Array[BTNode] = []
var _actor:Node2D
var _execution_blackboard:BTBlackboard
var _execution_start_time_ms:float
var _execution_stop_time_ms:float
@onready var _performance_monitor_identifier:String = "BTRoot/%s-%s" % [get_name(), get_instance_id()]
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _ready() -> void:
super._ready()
if not is_valid():
enabled = false
# Init du blackboard: soit celui de l'utilisateur, soit un tout neuf
if blackboard != null and is_instance_valid(blackboard):
_blackboard= blackboard
else:
_blackboard = BTBlackboard.new()
if not Engine.is_editor_hint():
_add_custom_performance_monitor()
tree_entered.connect(_add_custom_performance_monitor)
tree_exited.connect(_remove_custom_performance_monitor)
func _process(delta:float) -> void:
if not Engine.is_editor_hint() and enabled and root_process_mode == BTRootProcessMode.PROCESS:
_do_execute(delta)
func _physics_process(delta:float) -> void:
if not Engine.is_editor_hint() and enabled and root_process_mode == BTRootProcessMode.PHYSIC_PROCESS:
_do_execute(delta)
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
if not _check_direct_children_validity():
warnings.append("Root tree must contains only one child of type BTComposite")
if not _check_actor_validity():
warnings.append("Root tree actor must be filled")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _check_direct_children_validity() and _check_actor_validity()
func _check_direct_children_validity() -> bool:
var is_valid:bool = get_child_count() == 1
if is_valid:
is_valid = get_child(0) is BTComposite
return is_valid
func _check_actor_validity() -> bool:
var is_valid:bool = actor_path != null and not actor_path.is_empty()
if is_valid:
_update_actor_from_path()
is_valid =_actor != null and is_instance_valid(_actor)
return is_valid
func _update_actor_from_path() -> void:
_actor = get_node_or_null(actor_path)
if not is_instance_valid(_actor) and is_inside_tree():
# Fallback : si le chemin donné n'était pas relatif à la scene courante, on le check en absolu
_actor = get_tree().current_scene.get_node_or_null(actor_path)
func _do_execute(delta:float):
_register_execution_start()
_blackboard.set_data("delta", delta)
_blackboard.set_data("previously_running_nodes", Array(_previous_running_nodes))
_blackboard.set_data("running_nodes", [])
_children[0]._execute(_actor, _blackboard)
var running_nodes:Array[BTNode] = _blackboard.get_data("running_nodes", [])
if _previous_running_nodes != running_nodes:
for n in _previous_running_nodes:
if not running_nodes.has(n):
n._stop( _blackboard)
if not running_nodes.is_empty():
var running_node_names:Array[String] = running_nodes.filter(func(n): return n.is_leaf()).map(func(n): return str(n.name))
on_running.emit(running_node_names)
else:
on_idle.emit()
_previous_running_nodes = running_nodes
_register_execution_stop()
func _add_custom_performance_monitor() -> void:
if not Performance.has_custom_monitor(_performance_monitor_identifier):
Performance.add_custom_monitor(_performance_monitor_identifier, _compute_last_exec_time)
func _remove_custom_performance_monitor() -> void:
if Performance.has_custom_monitor(_performance_monitor_identifier):
Performance.remove_custom_monitor(_performance_monitor_identifier)
func _register_execution_start() -> void:
_execution_start_time_ms = Time.get_ticks_msec()
func _register_execution_stop() -> void:
_execution_stop_time_ms = Time.get_ticks_msec()
func _compute_last_exec_time() -> float:
return _execution_stop_time_ms - _execution_start_time_ms

View File

@@ -0,0 +1,52 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png")
extends BTNode
class_name BTComposite
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
if not _has_at_least_one_child():
warnings.append("A composite must have at least one child node")
if not _all_children_are_bt_nodes():
warnings.append("A composite must have children nodes of type BTNode")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _has_at_least_one_child() and _all_children_are_bt_nodes()
func _has_at_least_one_child() -> bool:
return get_child_count() >= 1
func _all_children_are_bt_nodes() -> bool:
for child in get_children():
if not child is BTNode:
return false
return true

View File

@@ -0,0 +1,52 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png")
extends BTComposite
class_name BTParallel
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var at_least_one_child_running:bool = false
var at_least_one_child_success:bool = false
for child in _children:
var result:int = child._execute(actor, blackboard)
if result == BTTickResult.SUCCESS:
at_least_one_child_success = true
if result == BTTickResult.RUNNING:
at_least_one_child_running = true
# At least one runn ing : this is still running !
if at_least_one_child_running:
return BTTickResult.RUNNING
# No one is running, so, at least one success > success, else failure
elif at_least_one_child_success:
return BTTickResult.SUCCESS
else:
return BTTickResult.FAILURE
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,37 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png")
extends BTSelector
class_name BTRandomSelector
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------
func start(blackboard:BTBlackboard) -> void:
super.start(blackboard)
if not save_progression or _running_child_index == -1:
_children.shuffle()

View File

@@ -0,0 +1,54 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png")
extends BTComposite
class_name BTSelector
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var save_progression:bool = false
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _running_child_index:int = -1
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
for child_index in _children.size():
if not save_progression or child_index >= _running_child_index:
var child:BTNode = _children[child_index]
var result:int = child._execute(actor, blackboard)
if result != BTTickResult.FAILURE:
if save_progression and result == BTTickResult.RUNNING:
_running_child_index = child_index
return result
return BTTickResult.FAILURE
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------
func start(blackboard:BTBlackboard) -> void:
_running_child_index = 0
func stop(blackboard:BTBlackboard) -> void:
_running_child_index = -1

View File

@@ -0,0 +1,43 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png")
extends BTComposite
class_name BTSequence
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var save_progression:bool = false
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
for child in _children:
var result:int = child._execute(actor, blackboard)
if result != BTTickResult.SUCCESS:
return result
return BTTickResult.SUCCESS
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,52 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png")
extends BTNode
class_name BTDecorator
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
if not _has_only_one_child():
warnings.append("A decorator must have only one child")
if not _child_is_bt_node():
warnings.append("A decorator must have a child of type BTNode")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _has_only_one_child() and _child_is_bt_node()
func _has_only_one_child() -> bool:
return get_child_count() >= 1
func _child_is_bt_node() -> bool:
for child in get_children():
if not child is BTNode:
return false
return true

View File

@@ -0,0 +1,37 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png")
extends BTDecorator
class_name BTFailure
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
_children[0]._execute(actor, blackboard)
return BTTickResult.FAILURE
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,41 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png")
extends BTDecorator
class_name BTInverter
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var child_result:int = _children[0]._execute(actor, blackboard)
if child_result == BTTickResult.SUCCESS:
return BTTickResult.FAILURE
if child_result == BTTickResult.FAILURE:
return BTTickResult.SUCCESS
return BTTickResult.RUNNING
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,51 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png")
extends BTDecorator
class_name BTLimiter
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export_range(0, 9999999, 1) var limit:int = 1
@export var include_limit:bool = true
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _invocation_count:int = 0
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var limit_reached:bool = _invocation_count >= limit
if not include_limit:
limit_reached = _invocation_count >= limit - 1
if limit_reached:
return BTTickResult.FAILURE
var result:int = _children[0]._execute(actor, blackboard)
if result != BTTickResult.RUNNING:
_invocation_count += 1
return result
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,40 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png")
extends BTDecorator
class_name BTRandom
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export_range(0, 1) var probability:float = 0.5
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var random_float:float = randf()
if random_float > probability:
return BTTickResult.FAILURE
return _children[0]._execute(actor, blackboard)
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,56 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png")
extends BTDecorator
class_name BTRepeatUntil
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export_enum("SUCCESS:0", "RUNNING:1", "FAILURE:2") var stop_condition:int = 0
@export_range(0, 999999) var max_iteration:int = 0
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var result:int
var not_stopped:bool = true
var iteration_count:int = 0
while not_stopped:
result = _children[0]._execute(actor, blackboard)
if stop_condition == BTTickResult.SUCCESS and result == BTTickResult.SUCCESS:
not_stopped = false
if stop_condition == BTTickResult.RUNNING and result == BTTickResult.RUNNING:
not_stopped = false
if stop_condition == BTTickResult.FAILURE and result == BTTickResult.FAILURE:
not_stopped = false
if max_iteration > 0:
iteration_count += 1
if not not_stopped and iteration_count > max_iteration:
not_stopped = false
return result
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,37 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png")
extends BTDecorator
class_name BTSuccess
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
_children[0]._execute(actor, blackboard)
return BTTickResult.SUCCESS
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,32 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png")
extends BTLeaf
class_name BTAction
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,58 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png")
extends BTLeaf
class_name BTActionBlackboardDelete
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var blackboard_key:String = "" :
set(value):
blackboard_key = value
update_configuration_warnings()
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _blackboard_key_is_set():
warnings.append("Blackboard key must be set")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
blackboard.delete_data(blackboard_key)
return BTTickResult.SUCCESS
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
var is_valid:bool = super.is_valid()
if is_valid:
is_valid = _blackboard_key_is_set()
return is_valid
func _blackboard_key_is_set() -> bool:
return blackboard_key != null and not blackboard_key.is_empty()

View File

@@ -0,0 +1,85 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png")
extends BTLeaf
class_name BTActionBlackboardSet
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var blackboard_key:String = "" :
set(value):
blackboard_key = value
update_configuration_warnings()
@export_multiline var expression:String = "" :
set(value):
if value != expression:
expression = value
_update_expression()
update_configuration_warnings()
@export var can_overwrite_value:bool = false
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _expression:BTExpression = BTExpression.new()
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _blackboard_key_is_set():
warnings.append("Blackboard key must be set")
if not _expression_key_is_set():
warnings.append("Expression must be set")
if not _expression_is_valid():
warnings.append("Expression is not valid")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
if can_overwrite_value or not blackboard.has_data(blackboard_key):
var value:Variant = _expression.evaluate(actor, blackboard)
blackboard.set_data(blackboard_key, value)
return BTTickResult.SUCCESS
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
var is_valid:bool = super.is_valid()
if is_valid:
is_valid = _blackboard_key_is_set()
if is_valid:
is_valid = _expression_key_is_set()
return is_valid
func _blackboard_key_is_set() -> bool:
return blackboard_key != null and not blackboard_key.is_empty()
func _expression_key_is_set() -> bool:
return expression != null and not expression.is_empty()
func _expression_is_valid() -> bool:
return _expression.is_valid()
func _update_expression() -> void:
_expression.expression = expression

View File

@@ -0,0 +1,100 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btactioncallable.png")
extends BTLeaf
class_name BTActionCallable
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var method_owner_path:NodePath:
set(value):
method_owner_path = value
_update_method_owner_from_path()
update_configuration_warnings()
@export var method_name:String = "":
set(value):
method_name = value
update_configuration_warnings()
@export var method_arguments:Array[String] = []
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _method_owner:Node
var _cached_method_arguments:Array[String] = []
var _argument_expression:Array[BTExpression] = []
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _ready() -> void:
_update_method_owner_from_path()
_update_argument_expressions()
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _check_method_owner_validity():
warnings.append("Method owner must be set")
if not _check_method_name_validity():
warnings.append("Method name must be set")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
_update_argument_expressions()
var arguments:Array[Variant] = _argument_expression.map(func(expr):return expr.evaluate(actor, blackboard))
var result:Variant = _method_owner.callv(method_name, arguments)
if result is bool:
return BTTickResult.SUCCESS if result else BTTickResult.FAILURE
if result is int:
return result
return BTTickResult.SUCCESS
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _check_method_owner_validity() and _check_method_name_validity()
func _check_method_owner_validity() -> bool:
var is_valid:bool = method_owner_path != null and not method_owner_path.is_empty()
if is_valid:
_update_method_owner_from_path()
is_valid = _method_owner != null and is_instance_valid(_method_owner)
return is_valid
func _check_method_name_validity() -> bool:
return method_name != null and not method_name.is_empty()
func _update_method_owner_from_path() -> void:
_method_owner = get_node_or_null(method_owner_path)
if not is_instance_valid(_method_owner) and is_inside_tree():
# Fallback : si le chemin donné n'était pas relatif à la scene courante, on le check en absolu
_method_owner = get_tree().current_scene.get_node_or_null(method_owner_path)
func _update_argument_expressions() -> void:
if _cached_method_arguments != method_arguments:
_cached_method_arguments = Array(method_arguments)
_argument_expression.clear()
for expr in _cached_method_arguments:
var btexpression:BTExpression = BTExpression.new()
btexpression.expression = expr
_argument_expression.append(btexpression)

View File

@@ -0,0 +1,53 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png")
extends BTLeaf
class_name BTActionWait
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var wait_time_ms:int = 1_000
@export var random_deviation_ms:int = 0
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _current_time_ms:float = 0
var _time_to_reach_ms:int
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
_current_time_ms += blackboard.get_delta() * 1_000
if _current_time_ms <= _time_to_reach_ms:
return BTTickResult.RUNNING
return BTTickResult.SUCCESS
func start(blackboard:BTBlackboard) -> void:
_current_time_ms = 0
_time_to_reach_ms = wait_time_ms
if random_deviation_ms != 0:
_time_to_reach_ms += randi_range(0, random_deviation_ms)
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,32 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png")
extends BTLeaf
class_name BTCondition
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,59 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardkeyexists.png")
extends BTLeaf
class_name BTConditionBlackboardKeyExists
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var blackboard_key:String = "" :
set(value):
blackboard_key = value
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _blackboard_key_is_set():
warnings.append("Blackboard key must be set")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var result:int = BTTickResult.FAILURE
if blackboard.has_data(blackboard_key):
result = BTTickResult.SUCCESS
return result
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
var is_valid:bool = super.is_valid()
if is_valid:
is_valid = _blackboard_key_is_set()
return is_valid
func _blackboard_key_is_set() -> bool:
return blackboard_key != null and not blackboard_key.is_empty()

View File

@@ -0,0 +1,96 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardvaluescomparison.png")
extends BTLeaf
class_name BTConditionBlackboardValuesComparison
enum Operator {
EQUAL,
NOT_EQUAL,
LOWER,
LOWER_OR_EQUAL,
GREATER,
GREATER_OR_EQUAL
}
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var first_operand_blackboard_key:String = "" :
set(value):
first_operand_blackboard_key = value
update_configuration_warnings()
@export_enum(EQUAL, NOT_EQUAL, LOWER, LOWER_OR_EQUAL, GREATER, GREATER_OR_EQUAL) var operator:int = 0
@export var second_operand_blackboard_key:String = "" :
set(value):
second_operand_blackboard_key = value
update_configuration_warnings()
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _parsed_compared_value:Variant
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _blackboard_keys_are_set():
warnings.append("Blackboard keys must be set")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
var result:int = BTTickResult.FAILURE
var first_operand:Variant = blackboard.get_data(first_operand_blackboard_key)
var second_operand:Variant = blackboard.get_data(second_operand_blackboard_key)
if first_operand != null and second_operand != null:
var compare_result:bool = false
match(operator):
Operator.EQUAL:
compare_result = first_operand == second_operand
Operator.NOT_EQUAL:
compare_result = first_operand != second_operand
Operator.LOWER:
compare_result = first_operand < second_operand
Operator.LOWER_OR_EQUAL:
compare_result = first_operand <= second_operand
Operator.GREATER:
compare_result = first_operand > second_operand
Operator.GREATER_OR_EQUAL:
compare_result = first_operand >= second_operand
if compare_result:
return BTTickResult.SUCCESS
return result
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
var is_valid:bool = super.is_valid()
if is_valid:
is_valid = _blackboard_keys_are_set()
return is_valid
func _blackboard_keys_are_set() -> bool:
return first_operand_blackboard_key != null and not first_operand_blackboard_key.is_empty() and second_operand_blackboard_key != null and not second_operand_blackboard_key.is_empty()

View File

@@ -0,0 +1,96 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btconditioncallable.png")
extends BTLeaf
class_name BTConditionCallable
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
@export var method_owner_path:NodePath:
set(value):
method_owner_path = value
_update_method_owner_from_path()
update_configuration_warnings()
@export var method_name:String = "":
set(value):
method_name = value
update_configuration_warnings()
@export var method_arguments:Array[String] = []
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
var _method_owner:Node
var _cached_method_arguments:Array[String] = []
var _argument_expression:Array[BTExpression] = []
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _ready() -> void:
_update_method_owner_from_path()
_update_argument_expressions()
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
warnings.append_array(super._get_configuration_warnings())
if not _check_method_owner_validity():
warnings.append("Method owner must be set")
if not _check_method_name_validity():
warnings.append("Method name must be set")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func tick(actor:Node2D, blackboard:BTBlackboard) -> int:
_update_argument_expressions()
var arguments:Array[Variant] = _argument_expression.map(func(expr):return expr.evaluate(actor, blackboard))
var result:bool = _method_owner.callv(method_name, arguments)
return BTTickResult.SUCCESS if result else BTTickResult.FAILURE
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _check_method_owner_validity() and _check_method_name_validity()
func _check_method_owner_validity() -> bool:
var is_valid:bool = method_owner_path != null and not method_owner_path.is_empty()
if is_valid:
_update_method_owner_from_path()
is_valid = _method_owner != null and is_instance_valid(_method_owner)
return is_valid
func _check_method_name_validity() -> bool:
return method_name != null and not method_name.is_empty()
func _update_method_owner_from_path() -> void:
_method_owner = get_node_or_null(method_owner_path)
if not is_instance_valid(_method_owner) and is_inside_tree():
# Fallback : si le chemin donné n'était pas relatif à la scene courante, on le check en absolu
_method_owner = get_tree().current_scene.get_node_or_null(method_owner_path)
func _update_argument_expressions() -> void:
if _cached_method_arguments != method_arguments:
_cached_method_arguments = Array(method_arguments)
_argument_expression.clear()
for expr in _cached_method_arguments:
var btexpression:BTExpression = BTExpression.new()
btexpression.expression = expr
_argument_expression.append(btexpression)

View File

@@ -0,0 +1,48 @@
@tool
@icon("res://addons/yet_another_behavior_tree/src/Assets/Icons/btleaf.png")
extends BTNode
class_name BTLeaf
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
func _get_configuration_warnings() -> PackedStringArray:
var warnings:PackedStringArray = []
if not _has_no_child():
warnings.append("A leaf must not have child")
return warnings
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func is_leaf() -> bool:
return true
#------------------------------------------
# Fonctions privées
#------------------------------------------
func is_valid() -> bool:
return _has_no_child()
func _has_no_child() -> bool:
return get_child_count() == 0

View File

@@ -0,0 +1,36 @@
extends RefCounted
class_name BTTickResult
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
enum {
SUCCESS = 0,
RUNNING = 1,
FAILURE = 2
}
#------------------------------------------
# Variables privées
#------------------------------------------
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
#------------------------------------------
# Fonctions privées
#------------------------------------------

View File

@@ -0,0 +1,64 @@
extends RefCounted
class_name BTExpression
#------------------------------------------
# Signaux
#------------------------------------------
#------------------------------------------
# Exports
#------------------------------------------
#------------------------------------------
# Variables publiques
#------------------------------------------
var expression:String = "":
set(value):
if value != expression:
expression = value
_expression = _parse_expression(expression)
#------------------------------------------
# Variables privées
#------------------------------------------
var _expression:Expression
#------------------------------------------
# Fonctions Godot redéfinies
#------------------------------------------
#------------------------------------------
# Fonctions publiques
#------------------------------------------
func is_valid() -> bool:
return _expression != null
func evaluate(actor:Node2D, blackboard:BTBlackboard) -> Variant:
var arguments:Array[Variant] = [actor, blackboard, blackboard.get_delta()]
return _execute_expression(arguments)
#------------------------------------------
# Fonctions privées
#------------------------------------------
func _parse_expression(string_expr:String) -> Expression:
var expr:Expression = Expression.new()
var parse_code:int = expr.parse(string_expr, ["actor", "blackboard", "delta"])
if parse_code != OK:
push_error("Unable to parse expression '%s' : %s" % [string_expr, expr.get_error_text()])
return null
return expr
func _execute_expression(arguments:Array[Variant]) -> Variant:
var result:Variant = null
if _expression == null:
_expression = _parse_expression(expression)
if _expression != null:
result = _expression.execute(arguments, self, true)
if _expression.has_execute_failed():
result = null
push_error("Unable to execute expression '%s' : %s" % [expression, _expression.get_error_text()])
return result

View File

@@ -0,0 +1,12 @@
@tool
extends EditorPlugin
func _enter_tree() -> void:
# Initialization of the plugin goes here.
pass
func _exit_tree() -> void:
# Clean-up of the plugin goes here.
pass

View File

@@ -6,15 +6,15 @@
[ext_resource type="Shader" path="res://assets/shader/crosshair.gdshader" id="3_3vnqi"]
[ext_resource type="Script" path="res://entities/PlayerSync.gd" id="5_828co"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_6d8kk"]
[sub_resource type="CylinderShape3D" id="CylinderShape3D_isqk5"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ikq67"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1h62m"]
albedo_texture = ExtResource("2_mxb5i")
uv1_scale = Vector3(3, 2, 1)
[sub_resource type="CylinderMesh" id="CylinderMesh_4e7dm"]
[sub_resource type="CylinderMesh" id="CylinderMesh_w15yb"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_08bwh"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_loyla"]
shader = ExtResource("3_3vnqi")
shader_parameter/center_enabled = null
shader_parameter/legs_enabled = null
@@ -29,7 +29,7 @@ shader_parameter/len = null
shader_parameter/spacing = null
shader_parameter/spread = null
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_rfdcv"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_qcftn"]
properties/0/path = NodePath("Body/Head:rotation")
properties/0/spawn = true
properties/0/sync = true
@@ -51,14 +51,14 @@ script = ExtResource("1")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CylinderShape3D_6d8kk")
shape = SubResource("CylinderShape3D_isqk5")
[node name="Body" type="Node3D" parent="."]
[node name="MeshInstance3D" type="MeshInstance3D" parent="Body"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
material_override = SubResource("StandardMaterial3D_ikq67")
mesh = SubResource("CylinderMesh_4e7dm")
material_override = SubResource("StandardMaterial3D_1h62m")
mesh = SubResource("CylinderMesh_w15yb")
skeleton = NodePath("../../CollisionShape3D")
[node name="Head" type="Node3D" parent="Body"]
@@ -68,7 +68,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.75, 0)
script = ExtResource("2_dl1i1")
[node name="Crosshair" type="ColorRect" parent="Body/Head/Hand"]
material = SubResource("ShaderMaterial_08bwh")
material = SubResource("ShaderMaterial_loyla")
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
@@ -97,4 +97,4 @@ script = ExtResource("5_828co")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="Networking"]
root_path = NodePath("../..")
replication_config = SubResource("SceneReplicationConfig_rfdcv")
replication_config = SubResource("SceneReplicationConfig_qcftn")

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=5 format=3 uid="uid://bp5ekvan8qsmc"]
[gd_scene load_steps=6 format=3 uid="uid://bp5ekvan8qsmc"]
[ext_resource type="Script" path="res://scripts/player/Hitable.gd" id="1_f1sho"]
@@ -10,9 +10,12 @@ material = SubResource("StandardMaterial3D_uw38t")
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_mfgnk"]
[sub_resource type="SphereShape3D" id="SphereShape3D_yvynv"]
radius = 20.0
[node name="Enemy" type="CharacterBody3D"]
collision_layer = 512
collision_mask = 512
collision_mask = 513
script = ExtResource("1_f1sho")
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
@@ -22,3 +25,14 @@ mesh = SubResource("CapsuleMesh_3ufk0")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_mfgnk")
[node name="Area3D" type="Area3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
collision_layer = 512
collision_mask = 512
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D"]
shape = SubResource("SphereShape3D_yvynv")
[connection signal="body_entered" from="Area3D" to="." method="_on_area_3d_body_entered"]
[connection signal="body_exited" from="Area3D" to="." method="_on_area_3d_body_exited"]

View File

@@ -8,34 +8,6 @@
config_version=5
_global_script_classes=[{
"base": "Node3D",
"class": &"Game",
"language": &"GDScript",
"path": "res://Game.gd"
}, {
"base": "Node",
"class": &"Hitable",
"language": &"GDScript",
"path": "res://scripts/player/Hitable.gd"
}, {
"base": "EditorPlugin",
"class": &"TBPlugin",
"language": &"GDScript",
"path": "res://addons/tbloader/src/plugin.gd"
}, {
"base": "Node3D",
"class": &"Weapon",
"language": &"GDScript",
"path": "res://scripts/player/Weapon.gd"
}]
_global_script_class_icons={
"Game": "",
"Hitable": "",
"TBPlugin": "",
"Weapon": ""
}
[application]
config/name="Scoom"
@@ -56,9 +28,13 @@ window/size/height=360
window/size/test_width=1280
window/size/test_height=720
[editor]
export/convert_text_resources_to_binary=true
[editor_plugins]
enabled=PackedStringArray("res://addons/tbloader/plugin.cfg")
enabled=PackedStringArray("res://addons/yet_another_behavior_tree/plugin.cfg")
[input]
@@ -108,6 +84,10 @@ reload={
]
}
[layer_names]
3d_physics/layer_10="Enemy"
[physics]
common/enable_pause_aware_picking=true

9
scenes/map/NearEnemy.gd Normal file
View File

@@ -0,0 +1,9 @@
extends BTCondition
class_name NearEnemy
@export var player_detection_distance:int = 50
func tick(actor:Node2D, _blackboard:BTBlackboard) -> int:
if actor.enemies_in_range.size() > 0:
return BTTickResult.SUCCESS
return BTTickResult.FAILURE

View File

@@ -1,10 +1,16 @@
[gd_scene load_steps=12 format=3 uid="uid://bq7p576e7a17i"]
[gd_scene load_steps=18 format=3 uid="uid://bq7p576e7a17i"]
[ext_resource type="Texture2D" uid="uid://bx4pdgghucl4k" path="res://textures/concrete_15.jpg" id="1_37wdm"]
[ext_resource type="Texture2D" uid="uid://bj2qm3joiywso" path="res://textures/dark.png" id="2_f8syx"]
[ext_resource type="Texture2D" uid="uid://bt671xkej3a2s" path="res://textures/shipping_container_01_side.jpg" id="3_vf5qg"]
[ext_resource type="Texture2D" uid="uid://c52qu6ad3taix" path="res://textures/shipping_container_01_front.jpg" id="4_70w0l"]
[ext_resource type="PackedScene" uid="uid://bp5ekvan8qsmc" path="res://entities/enemy/dummy.tscn" id="5_1x24o"]
[ext_resource type="Script" path="res://addons/yet_another_behavior_tree/src/Nodes/BTRoot.gd" id="6_sr8ry"]
[ext_resource type="Script" path="res://addons/yet_another_behavior_tree/src/Nodes/Composite/BTSelector.gd" id="7_2hqse"]
[ext_resource type="Script" path="res://addons/yet_another_behavior_tree/src/Nodes/Decorators/BTInverter.gd" id="8_6fp60"]
[ext_resource type="Script" path="res://addons/yet_another_behavior_tree/src/Nodes/Composite/BTSequence.gd" id="8_oe2bf"]
[ext_resource type="Script" path="res://scenes/map/NearEnemy.gd" id="9_dts0y"]
[ext_resource type="Script" path="res://addons/yet_another_behavior_tree/src/Blackboard/BTBlackboard.gd" id="10_xftr2"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yhpph"]
albedo_texture = ExtResource("1_37wdm")
@@ -81,3 +87,23 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.7493, -0.748922, -3.17036
[node name="Enemy" parent="." instance=ExtResource("5_1x24o")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.47822, -2.5938, -7.02456)
[node name="BTRoot" type="Node" parent="Enemy" node_paths=PackedStringArray("blackboard")]
script = ExtResource("6_sr8ry")
actor_path = NodePath("..")
blackboard = NodePath("../BTBlackboard")
[node name="States" type="Node" parent="Enemy/BTRoot"]
script = ExtResource("7_2hqse")
[node name="Idle" type="Node" parent="Enemy/BTRoot/States"]
script = ExtResource("8_oe2bf")
[node name="Enemy not in range" type="Node" parent="Enemy/BTRoot/States/Idle"]
script = ExtResource("8_6fp60")
[node name="enemy in sight" type="Node" parent="Enemy/BTRoot/States/Idle/Enemy not in range"]
script = ExtResource("9_dts0y")
[node name="BTBlackboard" type="Node" parent="Enemy"]
script = ExtResource("10_xftr2")

View File

@@ -2,9 +2,20 @@ extends Node
class_name Hitable
var health = 200
var enemies_in_range = []
func Hit(dmg):
#var tween = create_tween()
health -= dmg
if(health <= 0):
queue_free()
func _on_area_3d_body_entered(body):
if body.get_collision_layer() == 10:
enemies_in_range.append(body)
func _on_area_3d_body_exited(body):
if body.get_collision_layer() == 10:
enemies_in_range.erase(body)

View File

@@ -47,7 +47,11 @@ func _process(_delta):
label.text = "H Velocity: %3.2f" % [Vector2(velocity.x, velocity.z).length()]
label.text += "\nV Velocity: %3.2f" % [velocity.y]
label.text += "\nOn floor: %s" % is_on_floor()
label.text += "\nNetwork ID: %d" % multiplayer.get_unique_id()
if(multiplayer.get_unique_id() == 1):
label.text += "\nNetwork ID: HOST"
else:
label.text += "\nNetwork ID: %d " % multiplayer.get_unique_id()
label.text += "(%dms)" % Network.delta_latency
func get_move_direction() -> Vector3:
var input_dir := Vector2(

View File

@@ -1,11 +1,14 @@
extends Node
signal player_spawn
# The player scene (which we want to configure for replication).
const Player = preload("res://entities/Player.tscn")
@onready var NetworkingRoot = get_node("/root/Game/Networking")
var client_clock = 0
var latency = 0
var delta_latency = 0
var latency_array = []
func start_network(server: bool, ip="localhost"):
var peer = ENetMultiplayerPeer.new()
@@ -20,26 +23,47 @@ func start_network(server: bool, ip="localhost"):
else:
peer.create_client(ip, 27015)
multiplayer.set_multiplayer_peer(peer)
var timer = Timer.new()
timer.wait_time = 0.5
timer.autostart = true
timer.connect("timeout", func(): rpc_id(1, "Ping", Time.get_unix_time_from_system()))
add_child(timer)
timer.start()
func add_network_entity(path):
var spawner = NetworkingRoot.get_node("Networking") as MultiplayerSpawner
spawner.add_spawnable_scene(path)
func create_player(id=1):
# Instantiate a new player for this client.
var p = Player.instantiate()
# Sets the player name (only sent during spawn).
#p.player_name = "Player %d" % id
# Set a random position (sent on every replicator update).
#p.position = Vector2(randi() % 500, randi() % 500)
# Add it to the "Players" node.
# We give the new Node a name for easy retrieval, but that's not necessary.
p.name = str(id)
#p.set_multiplayer_authority(id)
NetworkingRoot.add_child(p)
p.init()
func destroy_player(id):
# Delete this peer's node.
NetworkingRoot.get_node(str(id)).queue_free()
@rpc(any_peer)
func Ping(client_time):
print("Got ping")
var player_id = multiplayer.get_remote_sender_id()
rpc_id(player_id, "Pong", client_time)
@rpc
func Pong(client_time):
latency_array.append((Time.get_unix_time_from_system() - client_time) /2)
if latency_array.size() == 9:
var total_latency = 0
latency_array.sort()
var mid_point = latency_array[4]
for i in range(latency_array.size()-1,-1,-1):
if latency_array[i] > (2 * mid_point) and latency_array[i] > 20:
latency_array.remove_at(i)
else:
total_latency += latency_array[i]
delta_latency = (total_latency / latency_array.size()) - latency
latency = total_latency / latency_array.size()
latency_array.clear()
print(delta_latency)