From 26f17fbd0304b1656f32a2f3cbf4886878021447 Mon Sep 17 00:00:00 2001 From: kookroach Date: Sun, 22 Jan 2023 23:44:41 +0100 Subject: [PATCH] Show network Ping & start AI behaviour tree --- addons/yet_another_behavior_tree/LICENSE.md | 201 ++++++++++++++++++ addons/yet_another_behavior_tree/plugin.cfg | 7 + .../src/Assets/Icons/Icons.pdn | Bin 0 -> 11229 bytes .../src/Assets/Icons/btaction.png | Bin 0 -> 286 bytes .../src/Assets/Icons/btaction.png.import | 34 +++ .../Assets/Icons/btactionblackboarddelete.png | Bin 0 -> 271 bytes .../Icons/btactionblackboarddelete.png.import | 34 +++ .../Assets/Icons/btactionblackboardset.png | Bin 0 -> 299 bytes .../Icons/btactionblackboardset.png.import | 34 +++ .../src/Assets/Icons/btactioncallable.png | Bin 0 -> 317 bytes .../Assets/Icons/btactioncallable.png.import | 34 +++ .../src/Assets/Icons/btactionwait.png | Bin 0 -> 358 bytes .../src/Assets/Icons/btactionwait.png.import | 34 +++ .../src/Assets/Icons/btblackboard.png | Bin 0 -> 197 bytes .../src/Assets/Icons/btblackboard.png.import | 34 +++ .../src/Assets/Icons/btcomposite.png | Bin 0 -> 145 bytes .../src/Assets/Icons/btcomposite.png.import | 34 +++ .../src/Assets/Icons/btcondition.png | Bin 0 -> 258 bytes .../src/Assets/Icons/btcondition.png.import | 34 +++ .../Icons/btconditionblackboardkeyexists.png | Bin 0 -> 299 bytes .../btconditionblackboardkeyexists.png.import | 34 +++ .../btconditionblackboardvaluescomparison.png | Bin 0 -> 317 bytes ...itionblackboardvaluescomparison.png.import | 34 +++ .../src/Assets/Icons/btconditioncallable.png | Bin 0 -> 317 bytes .../Icons/btconditioncallable.png.import | 34 +++ .../src/Assets/Icons/btdecorator.png | Bin 0 -> 145 bytes .../src/Assets/Icons/btdecorator.png.import | 34 +++ .../src/Assets/Icons/btfailure.png | Bin 0 -> 246 bytes .../src/Assets/Icons/btfailure.png.import | 34 +++ .../src/Assets/Icons/btinverter.png | Bin 0 -> 501 bytes .../src/Assets/Icons/btinverter.png.import | 34 +++ .../src/Assets/Icons/btleaf.png | Bin 0 -> 235 bytes .../src/Assets/Icons/btleaf.png.import | 34 +++ .../src/Assets/Icons/btlimiter.png | Bin 0 -> 159 bytes .../src/Assets/Icons/btlimiter.png.import | 34 +++ .../src/Assets/Icons/btnode.png | Bin 0 -> 145 bytes .../src/Assets/Icons/btnode.png.import | 34 +++ .../src/Assets/Icons/btparallel.png | Bin 0 -> 205 bytes .../src/Assets/Icons/btparallel.png.import | 34 +++ .../src/Assets/Icons/btrandom.png | Bin 0 -> 218 bytes .../src/Assets/Icons/btrandom.png.import | 34 +++ .../src/Assets/Icons/btrandomselector.png | Bin 0 -> 190 bytes .../Assets/Icons/btrandomselector.png.import | 34 +++ .../src/Assets/Icons/btrepeatuntil.png | Bin 0 -> 367 bytes .../src/Assets/Icons/btrepeatuntil.png.import | 34 +++ .../src/Assets/Icons/btroot.png | Bin 0 -> 213 bytes .../src/Assets/Icons/btroot.png.import | 34 +++ .../src/Assets/Icons/btselector.png | Bin 0 -> 181 bytes .../src/Assets/Icons/btselector.png.import | 34 +++ .../src/Assets/Icons/btsequence.png | Bin 0 -> 248 bytes .../src/Assets/Icons/btsequence.png.import | 34 +++ .../src/Assets/Icons/btsuccess.png | Bin 0 -> 314 bytes .../src/Assets/Icons/btsuccess.png.import | 34 +++ .../src/Blackboard/BTBlackboard.gd | 59 +++++ .../src/Nodes/BTNode.gd | 116 ++++++++++ .../src/Nodes/BTRoot.gd | 162 ++++++++++++++ .../src/Nodes/Composite/BTComposite.gd | 52 +++++ .../src/Nodes/Composite/BTParallel.gd | 52 +++++ .../src/Nodes/Composite/BTRandomSelector.gd | 37 ++++ .../src/Nodes/Composite/BTSelector.gd | 54 +++++ .../src/Nodes/Composite/BTSequence.gd | 43 ++++ .../src/Nodes/Decorators/BTDecorator.gd | 52 +++++ .../src/Nodes/Decorators/BTFailure.gd | 37 ++++ .../src/Nodes/Decorators/BTInverter.gd | 41 ++++ .../src/Nodes/Decorators/BTLimiter.gd | 51 +++++ .../src/Nodes/Decorators/BTRandom.gd | 40 ++++ .../src/Nodes/Decorators/BTRepeatUntil.gd | 56 +++++ .../src/Nodes/Decorators/BTSuccess.gd | 37 ++++ .../src/Nodes/Leaves/BTAction.gd | 32 +++ .../Nodes/Leaves/BTActionBlackboardDelete.gd | 58 +++++ .../src/Nodes/Leaves/BTActionBlackboardSet.gd | 85 ++++++++ .../src/Nodes/Leaves/BTActionCallable.gd | 100 +++++++++ .../src/Nodes/Leaves/BTActionWait.gd | 53 +++++ .../src/Nodes/Leaves/BTCondition.gd | 32 +++ .../Leaves/BTConditionBlackboardKeyExists.gd | 59 +++++ .../BTConditionBlackboardValuesComparison.gd | 96 +++++++++ .../src/Nodes/Leaves/BTConditionCallable.gd | 96 +++++++++ .../src/Nodes/Leaves/BTLeaf.gd | 48 +++++ .../src/Result/BTTickResult.gd | 36 ++++ .../src/Utils/BTExpression.gd | 64 ++++++ .../yet_another_behavior_tree.gd | 12 ++ entities/Player.tscn | 20 +- entities/enemy/dummy.tscn | 18 +- project.godot | 38 +--- scenes/map/NearEnemy.gd | 9 + scenes/map/test_map_gd.tscn | 28 ++- scripts/player/Hitable.gd | 11 + scripts/player/PlayerQ3.gd | 6 +- scripts/utils/network.gd | 44 +++- 89 files changed, 2839 insertions(+), 53 deletions(-) create mode 100644 addons/yet_another_behavior_tree/LICENSE.md create mode 100644 addons/yet_another_behavior_tree/plugin.cfg create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/Icons.pdn create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactioncallable.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactioncallable.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardkeyexists.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardkeyexists.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardvaluescomparison.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditionblackboardvaluescomparison.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditioncallable.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btconditioncallable.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btleaf.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btleaf.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png.import create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png create mode 100644 addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png.import create mode 100644 addons/yet_another_behavior_tree/src/Blackboard/BTBlackboard.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/BTNode.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/BTRoot.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Composite/BTComposite.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Composite/BTParallel.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Composite/BTRandomSelector.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Composite/BTSelector.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Composite/BTSequence.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTDecorator.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTFailure.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTInverter.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTLimiter.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRandom.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRepeatUntil.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Decorators/BTSuccess.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTAction.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardDelete.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardSet.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionCallable.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionWait.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTCondition.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardKeyExists.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardValuesComparison.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionCallable.gd create mode 100644 addons/yet_another_behavior_tree/src/Nodes/Leaves/BTLeaf.gd create mode 100644 addons/yet_another_behavior_tree/src/Result/BTTickResult.gd create mode 100644 addons/yet_another_behavior_tree/src/Utils/BTExpression.gd create mode 100644 addons/yet_another_behavior_tree/yet_another_behavior_tree.gd create mode 100644 scenes/map/NearEnemy.gd diff --git a/addons/yet_another_behavior_tree/LICENSE.md b/addons/yet_another_behavior_tree/LICENSE.md new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/addons/yet_another_behavior_tree/LICENSE.md @@ -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. diff --git a/addons/yet_another_behavior_tree/plugin.cfg b/addons/yet_another_behavior_tree/plugin.cfg new file mode 100644 index 0000000..7a3f256 --- /dev/null +++ b/addons/yet_another_behavior_tree/plugin.cfg @@ -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" diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/Icons.pdn b/addons/yet_another_behavior_tree/src/Assets/Icons/Icons.pdn new file mode 100644 index 0000000000000000000000000000000000000000..22a75da373758769aa30df81f16f303efa0d85b0 GIT binary patch literal 11229 zcmd^E2~?A3*8V=W@F|-sND%^R)k4`(P?jX@vV~2tDiD$n2xfsSENX*@3ROEYt^Qg& zb*b1<+nKsdTb+)@g$kY4U#)A$T5%o0j*5zd2xRVk5fYMiI{$ypf6jkS!^xBTe)rzz zzU#ejf-ojEXp#jLUMf)}%0)#iw?Zn>6i0Xk%<$qCv(lns&44TuRk12{gjZmw7gsGR zXC?Ebn&P?eNUBssc!l`-`-TPw`1=M02M2|CMTU#DYK>AJ8LlbT$_u!qilPWF>0Cit zMumS;e36n5uhh)!;@IpWkObJ|r$_Ts@Kc$b9+rgyKPNRa!#|O)QU{A?q~n7OMS6As zSVvcuRFsF#PtS&Df}-r$%Ipl(r;6sprX^|SmFJXHdPgg>{0ihtgnsY}ni&=*N{(aU zS$S4bMfuE7Z|#!A#f3Ay{WS1AHBgdPsHzG{WmDq(W`=pg+b`9-B%?gJKocevCX|<` z15*PFg{gt8P?(UTDo>cNPRp!%Elm|GO_O>Trh-j+Mo8+6MC{}oacuEx;tD=LMvdc{ z8N(M#%FE)hg93SGc7|YXba7UpxH2b3$uEkHotvSKsj5^)CkJZF!z9s*L--~06+!bu zrQ+A(V+y^K)PB*ii8F=S>6NkN>P%@&dd%VkwX!r$mYTp1QD%6{i_+x*LS<^z98q#c zSz54yEnHGs6p~OSDhQBP$Q80Ub(&l5nf!s$Z)^G1@s%-7?BhWe-x#M7k=W)&H^A+D3U5PF-lD;tMQEy zX+%EU!F@4&TljFJwK9!X#YQMttwtr1`EZ5W0-02t#8zb~7qf~8g;plBM)I-4IF(|p zoKnW7MJ$c%unpkUTNG;ER2|0VgN z1&eU-6k`eC^y1CHTv3cQfHgk;={Z9in^KVqmd1&%Qi-Z?BE9pZIN6Ry57g2n>}aEQ z`9RjN0{Wj^=Yh3AWNNqHVizl zpUhTD3w<@BBL4;ci)==~BVIT@;z}hEUP1mLUR)U@Bd>s9FRrGll!c<_#U%t0UgG$; z(gH=gwm?4DKQSg-3n`u?Ou7r^6zA2(Zdin1j9?Fs{0tES!=Sd32*5iKAZRE6zvudK5vCx#j4%~p8p3ph zR}j1rd=Oqm@I~+gu(z`FhmT=3Dq5*x4Qcs*Riki(&c=mAAl1l4rKFsYGF7Tlma;01 zlvQ)oT2-M)%sLUJx1oNG9C$#=m)(FoP{dwX8YoE8vwHPs;&~gz77m5Qoj=CdBXgh| zI2*LBt*5bSAUMI{1SAIsfCm!@V5km3NP-JYRyr62CIrA>FasJiEThVvq&` zBLpxQq(g(ojZX|RKwvTf3*y5STmwgF!wtXgq|(Km-C)0AMf>LxaWxN(>|*Ff4$a8DKtDAeAmN|jtBd(pH2AAB>b0IV?s{8U1*LZ$H?+(r#oUky&bfR0#@%qTaa28$D+{4WsffHGPshwr5D&1ZnH?g{H71P) z8$!Ah1Ud%5jIown)HxA4Q?{4(QN^8cu2Q>)*gm*6p zxL(PusBoyOS;mxDk_qJ>&~Xlc8RZ{QgLRrvehh+*AZyqTNHb={8crAwpkE4r8RJ3J zU|}bWe*$5IAS;u_9|(-rX^t^#8W<7Q&(K#0V8(g~HR%9^^)Lud&`*&K^m~kILO%?#*{sIKjV>nw1v0=yZj9KxbL0FHWFWxxJSdXIyZy$v91PHc* zER&5j+n5vYCWP}Odd>$h<7`0vzeZ=g+L+OP zgBrZ%5ZY59zyu^J;D-neYdBf~#;mzuL|D(DZytad>si#~0}$44L9i2K31m=g3X~$1 zWN6F!81st2jPPCnfi3_rHk%lD(KU_*pHs5`ITg4^7`h<47goNFv=rzQq7$k#3_#20$X+0Rfg}U|-G?Ne!9b z#h6zPW`wsLz42yg#@m4!B>>^Q2LdC=N|wqY>l^ma7-P~>upy-P(X|Y~jPwC&Q~-qZ zAqe(x?AcOQq{&ujq_Uw|a4;rTgB>A$jP4o$GvX(x(EkyHjh>JIhP%9ykYYzS!|x-J1QBkf1cQUF4#2LbZP zK;|3b)b|?|{$*f7I4x-Kd>vY5oR+B34RTsR3l6+c1iv}USi_w57_(LnvU1RO`A@Oh zqNZk$6@Q$B96hkJ;Hn}M!KHGj$6dzUD+amkkfHXcxb0E1a**2rT4RjP$1r-VtPhRo ztyh8De|V<{OLC{TUJb&}-O4RNXA55miZsPDf|+8G8fFfD!C$-4d%KHgSw68x_1V3Tg-J^2X))b zbvp-jjpn-DgF3unne-FyPNbiBRWi{X7}Om!*Wq1;_~F&X#1HQxM2A-o6Wy^v9bO~b3b(p$MbeNKfA7)?^9cEUd!$fML!wgAum=H~LnCFNN)0&A6 z^AyoxS{kk!Y1rcwHPK_OEkuRai0At1vFlc(`)AP96aB110|&usKnXbAU@6Ye?>@~7 zd)awihlhRB*(cFe{hlvbQhz(E9cAkEim}&rx9_)#9&K|A-&-Br8+Xp}_OrUt6s4hI zPm?%?U?y&t?I9YX84qB9v{{3cc$u1iQPGm4ZZi9Qu+_-S4_Nh zZ)%I3rjPsMhQ1q3rO&koy526Z@rCx*&W@&>d-eyq#)xe^q5a;|o~EqFDF?c42G!<3 zd()#kP0LQm4|IuxYP0&dZVkOpn@UbCI?y%gUH%_+E-z30_?q;o)eHNCM;_FKT5Y;g+CDYb@6Wo7F0Xr2_{E#`D&>9dOO~@%>#o+5Ol}zyDOH zIatpGm2`L%>)-B(dhKq@-*Z(rS3m+-n5jxNrJMJ2bjPQxKIN-f%CvLR53PHDqfVl> zJ-khLxnZZrck-MkNBg4J>G%A><7!{`lQEX1?JeWxHm;m>gr=rV7?W)pBi}TJQ~u8Q zHM;OSbA-E_==$}R`z@_|MEMa;AGQhOeY)+N&zTzNtPYjepnyqbfw|C{xokP z-R#qNcU4CPRWKo=>nxnbtBHrpO@mbq3l`Z17qVGAH$jb#!?mgT2k#@0oVp#FLwMit zKhU`xa%lD)d$+FUHqVF8tG06Q8N4CX{O*}hG?x%rF z55H|(g5%iQQ(pXPOQ+dho%a&XuK(I^a>p3DAf?g&Q1tu#vl>gOXYm_i`rhY#6g%h8 z&3*b;-s$1Db8g+2sh&8Fqo}1zE?qE*PLD7||Kwc6;^X;FN6W4`eOdBh+Xn|Hy1kln zHf3x~O!_qI9fv~0x|xM**S2xL+@-70)qOkvcMCsf$Bng`R93G)8sz3VVvTz*_m-+9 z!msSG!aXyX)OqgW%aD{De{dHz*P?sX4+97(~S>AY$-8YZr zO19hyy0x@vOH-Zln}>DNZ#ZSUJo7*@|-SL;c;4JfS`h;`7*;P<-XT+>&zq=f5zpe6wYt?U`?mqa* ze+Pba|D7X|uWnu75aGM#rKkHYYX70n@7j0&$3-`6&sSe|Gnp1D+b}KSd>40K>z)*J^D%Q^c9&%L#_?-)`;PEljye6|JpIOv8;^D0{(4h>K!e*i6LX%_-sY9Ky1Mqyo;7R5 zcie^Z=GFaC9~IfxnvCs&`KO;B=g>?#W=?I-t=-|A@{tD)$il)x?-8Zzy>{~CohYHpI=-yICBfm2 zgHO*f6}QXN(^G$~soL=(=Qwvpg5Bi0Mu*?)Hc!|V`MQO8b8g0y+8_HK-5%*O>G>*` zzE(xt(~)#v+ryh}ZB*U31Mdz{rF9>>nRe_mdQ$(H=6zp!I5O>ZoJD$}H6?VLmSj4B zuYP#|j-&Mt7KA>ozHt7O-ZJSAuf0_T0%FY{l-t@6{ zYR;c^4M+Tb(Dj@?al&$L%dumf`p%mz`iX9C``S7C)2Y@|NuO=wr>}L~evk9aSrXNn z+mJhc{P=x+zP`St2lJnb&pD3fJo9KQ>Uq+h@48;Uzn#Q{wEn<K=;fU~@h8@ov=>dYpf)_XyVTU};jktC0ViWR@1y7yJ#NAMGMtXbHJj^}|KJ2w zfeJ2zA=(96uFs`+M{pmylsI$V3g1x9t-=itxfJg{XI0RWoSJTK*}BkX3*n7=+p@Q4>Wve#R+5h z9?c%5_=vvothm6Pw`{_uD`(EDs7^WeQ=a;5OV1+-g)6DfvT2`N)o&W}q4QVkuJYU* zwQDUV^zg6CsYi}`mbBYbo}V{GnD$INtY=xvYb`=7c)c$5@`ranso6{K`O-$PygR}n zNVZ+Y4e6$41l3W zRz00}Iafv&2oB{OD+=$?kJ+J*^6Xnl9qHQnyiV9X>dbn--VerH?`^Mq@|bt(=tdn+ z6@KW6V=P5Yc;&_yrXhL5LN3GQ7{&XZYIc)!q*)a>Ra!L%#B?0v^c2gZLi(ac-+Y_b z`{v214iq)M`FfEl+3>Y>MY46bIxGvSxsig^xz5~3rkVTjy@UuE??=1l=i7Vo+nh%& z`Fwe|$Ck*@<$Ir{@uDJ+&fzsVWL*{e+~?2^UcLP<)$5m^x7a_$9jGe`edfyYM$T&U8LZ8@MgI6EPqe*|GQ`Z0*WcGPyhe` literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a9c0be61ca252ba2ed6278961724cd99821886 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}N0G|+7ApI^m=tFJ(=V@J^x@!Ob|NraKxet|D|9<`awr<(G^zc8=9)Id- z_<8d1`@*EpGkX8Lc=kR&{>$9S-!`szpA+-%&z~Rrcld zL>4nJ@ErzW#^d=bQhLoCkC{H!PC{xWt~$(698+UdA|Sv literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png.import new file mode 100644 index 0000000..e2f07df --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btaction.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png new file mode 100644 index 0000000000000000000000000000000000000000..bfdc4c0b1b40711f7a2179089871364e380c4019 GIT binary patch literal 271 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}x0G|+7ApI^m=uJ|<>Hxi3XVD5Lp&EBd0Re%>k00CE*o1_Hynp}x)2B~g zzI@@};Arqwc#-J$GS2!FP#b4~M`SSr1K(i~W;~w1A_XXz>gnPbq7j_i7tPmTz`+uJ z`j*q{$N!d#1}^SB$IdC7aB%v<$KgGm5*|{{Dn(XR`kE~U;;dUzyf}oyLRUBLVO?W- zIQoUn?`z66_qOLL#&n&Jj$F4`ZnxaVxN|q&R_1VD{HSi#AlvnenK^0eXE~sS44$rj JF6*2UngAV;U9$iH literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png.import new file mode 100644 index 0000000..5315d14 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboarddelete.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionblackboardset.png new file mode 100644 index 0000000000000000000000000000000000000000..6978498f0661a20ae266357e0905d086c13d4091 GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}-0G|+7ApI^m=uJ|<>Hxi3XVD5Lp_zrgo2ORIDG5BcYvuFj&*#sdzj*QD zPj6rF@bGYOa6Eqe*ulZ!%=V@K|Nm!UVR3PBnLd4bK|#TbM8BhEe6m2}I14-?iy0XB z4ude`@%$AjK*3B;7sn8d;M{Ys`5F{B91^)sZ1Q>g>bHF+SN7SbKOcU%E%Gov{A!C_ zr|O|NhDw9QLR=S8(sw_RHQ?mQW0g;06f=m9EB8$(k?Sis#JA=^@Q$W^3&T4e*G~KV pTjSMNS%Lh70G|+7ApI^m==0?E-?y%P>S_3W_tyXa|Ns5^`7SN&Q+NHZ>zDrh{{4OX z`hWlay-N%IP@Dhv?VES$;s5^p`SD#XVv0Q!*y`A5aPs~Y4xc_6dJ%^LEt&5@1Z=nto<_XmrOCo(`_%hsIE^x~A zUvQ^0V@sBG=e>HXgeNt#@*_6Ps&w7(a&8!V``Px#1ZP1_K>z@;j|==^1poj5Z%|BBMF0Q*?qgE!XIKCK|L<&E{q5}XhkEX1RQuoC z?{sAImWuuL^zeOe^{Jrw&dBtglK%Mj{qF4k_Vw_5ZurE#`OL@eYFhcq#PW-N{p{-W zpq2Hbng0F#_q?_E!Mpzb{P(!9{OjrPb!YtO=J>z3H})B)00009a7bBm000id000id z0mpBsWB>pFfJsC_R47wr&f5}#Fbo9Hu5GE8DuNNUS`qR8zmZf)W*GOar`b%*f3V0G zR)FOwIA0Y(Sa0Tu?XHT}#{EGmsE>`czC9_>xdXZj2}I9tT$@{*A(gNDqs~d-3Ap|R zg*fmfZ-h}QAYut0T?$7-&Lfr8Kj2nMJkJr(Ff3xs1g@h6utD7iE&u=k07*qoM6N<$ Ef=1h_)Bpeg literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png.import new file mode 100644 index 0000000..33bb4c2 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btactionwait.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png new file mode 100644 index 0000000000000000000000000000000000000000..49cfc760d3765187f340fecc1fe21001335ad20d GIT binary patch literal 197 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFFMGaB5^snf!WQ`K)@kMV|QCyn*^ievV{%;JSjVxLfRN47b>`E)Um}F##9@f ja4=@nDRX3CW@b3Jlec&8z4BE+Ll`_={an^LB{Ts5+JZI3 literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png.import new file mode 100644 index 0000000..bbaa025 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btblackboard.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png new file mode 100644 index 0000000000000000000000000000000000000000..0e938f2a9b65a3802ba741992605dd3ed492bb6c GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK{Zbo#}EtuWCc+Jrj054bX%MSZ01+Y;5?-w k)sv;b)|0h>F(HA0A+D2IrtZKapaup8Pgg&ebxsLQ0OgJ&=Kufz literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png.import new file mode 100644 index 0000000..1d5e6d2 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btcomposite.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btcondition.png new file mode 100644 index 0000000000000000000000000000000000000000..0cca0b8ccb5c7854d9559feba230dcd0662ef80b GIT binary patch literal 258 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}B0G|+7AbqV<;K4HQSBKkf&(Qz<<<+8>VmAD6Ic>;BE7I;J!GcfQS24TkI`72U@f}x%+jv*SsrDvo0 z8Web30=?cc*g1UPAGz`3GMByf&VC9lT<@ar}k z)*N`&IMMrS!0dky^WW@Z+bFY(?V31GYXQ@n8pe~##mD-A7BG0a`njxgN@xNAmpxNS%G}-0G|+7AbqV<;7Yr|!bHIuSHTJ=p_zrgo2ORIDG5BcYvuFj&*#sdzj*QD zPj6rF@bGYOa6Eqe*ulZ!%=V@K|Nm!UVR3PBnLd4bK|#UAR)NoszpH@8aTa()7BevL z9R^{>NS%LhJ0G|+7AbqV<;7Yr|!bHIuSHTJ=p_v6fyXLodMH_y8_v-)u|6S2WuU@@U zR#txb@?}FqgQKHkU0t1$l9Gssh^D6IojZ3#MMbr=v|il5ez8?x_kxZM6H7mcYh?k= zNS%Lh70G|+7AbqV<;L+NsuaA#ESmFQe*_r?U|Ns5{{aUx^gB5;X9vu4j=hvGP z6aW4Dcdc9G?p(`XpPpRr5&!r1_rJe??k{%xbbI@aez_lSZrq)3b9bK2$Ls4p-q`SD zQ_8C&9WVCP+~}8OsWe{%w1cz2BeIx*f$uN~Gak=hkpdJ<^K@|x(Fm?R6VBJ5AmAFf z!DizErEk0b$8z~O^mcwvJ~1aH;r@@+_8d;uwl0Q3zlAzXm?uF(HA0A)}jF#%wD~A5aH_r>mdKI;Vst0Ptud(*OVf literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png.import new file mode 100644 index 0000000..3ca2c72 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btdecorator.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png new file mode 100644 index 0000000000000000000000000000000000000000..f6885087023d1c43f52edd55a0c1924459e67bde GIT binary patch literal 246 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFmWISUjueh% z>|N6uuW)otZBuWOY?91v5^#GG!r{C{$5!ABhd)aei%~;VgH$8WR2N4_Lv;mbiImob g42Oa^5)v2~f|l`D-8TAZ477~F)78&qol`;+0L~gf@Bjb+ literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png.import new file mode 100644 index 0000000..ebf2c72 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btfailure.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btinverter.png new file mode 100644 index 0000000000000000000000000000000000000000..de30df74cf07d372af58949de14cbca2b9c1d062 GIT binary patch literal 501 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Li90X`wFK-$AM*WD-E*(1%>E7RFMRnO2>&&bW*CBe-*+ubL}*xXNE$v{QT z+|nk@#UtI#JIl#E)!aHnQQ1gdQQy$S%fcp9*TBWaGd(4vIUuxHQ^!tPR#RF=Q&31s zMo!zwEoH{+wcoz|*s|?#Zef>$OCl>P2NM%BAHS%LV@zGsjQ{`t-@Ns(Z{iXY3x6J7 zAx0)978W)WbN^Sb-{lwg7#MrXD(H$!Dhmlqb8_)%>pA)c75@42r@ncni)V(hnXit% zvzb-Uiq*T?I_G`<{I$5OKRvsxrG0L2MA@aq*RBG+$64SJS+Qm?GTd*pioH(rzS%7GCdKb| zgZ$g%fV(xSp$vKRfOEak7aXGnx v+0D^Fz#)l)Q;Unk=u%T-qBx6z0RzJoKepz8=Wp)=l`?p``njxgN@xNA4mc{G literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png.import new file mode 100644 index 0000000..70b06e9 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btlimiter.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png new file mode 100644 index 0000000000000000000000000000000000000000..7b10b335b897c35cba69334b9b3e8abfb4041159 GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucK{Zbo#}EtuWCc+Jri~|iZVT`^7N|K-F(HA0p?NN|jN-zopr0O6`5e*gdg literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png.import new file mode 100644 index 0000000..4f57653 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btnode.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png new file mode 100644 index 0000000000000000000000000000000000000000..ca32a9c377a5d3c5f186bc3740914fb4c2ba08f9 GIT binary patch literal 205 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPF|C(4?f?J(Pu{)AUeq*m|H_|9_f7&;a29w( z7BevL9R^{>rtc7VupB;%1<%tE(#<%CeAc9d{?= sloo@AQ;N45*%Z1JRx`eCVqjxq*nW(6vW8puDWDk)p00i_>zopr0NnvU;{X5v literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png.import new file mode 100644 index 0000000..ad39689 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btparallel.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png new file mode 100644 index 0000000000000000000000000000000000000000..08d368b4b8b658330cf9fdc1c58afa93e728c408 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFB}QNlw@@PvRrCvT~?$blqr76SvILmh<}8lV0Lxrf2i)z4*}Q$iB} DHA_G1 literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png.import new file mode 100644 index 0000000..0981d0e --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandom.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png new file mode 100644 index 0000000000000000000000000000000000000000..d5707812d794a7302d635fbd847945fe62deea00 GIT binary patch literal 190 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFhu=sU-R2Q1K=h5k7zfSI5)gBwT clzkEJoMoK8{=6wWfhI9{y85}Sb4q9e07o4;2mk;8 literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png.import new file mode 100644 index 0000000..47923b2 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btrandomselector.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btrepeatuntil.png new file mode 100644 index 0000000000000000000000000000000000000000..0aa49d27e7a7f5534f2c1ff25a56ef53c2922270 GIT binary patch literal 367 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%Lhb0G|+7AnoCs+dpYpdUo5?8LPJMJo@VOyIs3a1cVm1w9ozj|9@l4tUdcq z1xJ**dS&_s6~1`!X5;3AiVB>*9XXBFV4U9cmSlHS- zCv$LcY3n)g@$tEOM5$?5#Koru1xK>7vP<|@8Utg0R*-ha{EF1KQ${~we6y=}Mf{zl(_2mJJO56-*q zxbR%T65;xlBSEK+1-8@|!LnJOIH!!<78VDpLgao-5v`i71DCr<+ahT(jKpCrcn1~5yi-7}E z0-FcJk$^JROlG4HCPf}IRRe}D5hvYN1~xW^vjJQyTrZXQ15IS`boFyt=akR{0I}gd AQ2+n{ literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png.import new file mode 100644 index 0000000..da713a0 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btroot.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png new file mode 100644 index 0000000000000000000000000000000000000000..1af7092c870e58b1ef2f13f0a04f9db5c09b0fca GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPFXJk~Qo90>^w4E4qw&)@xi Q2(p5~)78&qol`;+0AU3%2LJ#7 literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png.import new file mode 100644 index 0000000..dd497d2 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btselector.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png b/addons/yet_another_behavior_tree/src/Assets/Icons/btsequence.png new file mode 100644 index 0000000000000000000000000000000000000000..1d54127ec9ed708afbb6cb0bf88f2f91e13c1030 GIT binary patch literal 248 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G}B0G|+7AT611`~Uxcy&C_X?eosuzY;V#ciY87mdz2r|NLHfWc`}cJFh>x z>pvmu%a5lBSEK+1y**tVLo|Yu53uxT zFsK}0X$x>z#=v6WtkJ^2tu5W*B$SYp^t@pfBm10~Gb@;U?j$ho5R;1&G5+y`wL!$G m!B@aXk!1mcMgxNS%Lh70G|+7AnoCs>*b$+`RbjNjOIyGS6sYwD>$O;?YocZ*=?)W?b)*J@Q06| zA3c5%8C!Mw%+&>pH}BegqPl+C{RdBdg9@KMeN|A>TUt4>rG4(T>-T2QUBCa}nRDlF z^z<)|ORmq#>!`~=w*hDeXMsm#F#`kNVGw3Kp1&dmD46W&;uxY4Tze*xuR%e8Ilw{S zyXc+izwZZS1Q;7`lo$SW>A=2+D*qLfJROggESx;WY1(dPfft)DFuFumu9&(%!eniA zscjoWGP}8SE&qH!26))uQs4{44$rjF6*2U FngHJ}faw4L literal 0 HcmV?d00001 diff --git a/addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png.import b/addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png.import new file mode 100644 index 0000000..34ed00c --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Assets/Icons/btsuccess.png.import @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Blackboard/BTBlackboard.gd b/addons/yet_another_behavior_tree/src/Blackboard/BTBlackboard.gd new file mode 100644 index 0000000..a773071 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Blackboard/BTBlackboard.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/BTNode.gd b/addons/yet_another_behavior_tree/src/Nodes/BTNode.gd new file mode 100644 index 0000000..83381db --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/BTNode.gd @@ -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 + diff --git a/addons/yet_another_behavior_tree/src/Nodes/BTRoot.gd b/addons/yet_another_behavior_tree/src/Nodes/BTRoot.gd new file mode 100644 index 0000000..c01dda2 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/BTRoot.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Nodes/Composite/BTComposite.gd b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTComposite.gd new file mode 100644 index 0000000..5fb293d --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTComposite.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Nodes/Composite/BTParallel.gd b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTParallel.gd new file mode 100644 index 0000000..47827f8 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTParallel.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Composite/BTRandomSelector.gd b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTRandomSelector.gd new file mode 100644 index 0000000..24847d4 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTRandomSelector.gd @@ -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() diff --git a/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSelector.gd b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSelector.gd new file mode 100644 index 0000000..70934bf --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSelector.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSequence.gd b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSequence.gd new file mode 100644 index 0000000..151913e --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Composite/BTSequence.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTDecorator.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTDecorator.gd new file mode 100644 index 0000000..1f2c958 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTDecorator.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTFailure.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTFailure.gd new file mode 100644 index 0000000..3342e15 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTFailure.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTInverter.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTInverter.gd new file mode 100644 index 0000000..08e31e5 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTInverter.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTLimiter.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTLimiter.gd new file mode 100644 index 0000000..5f0ea34 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTLimiter.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRandom.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRandom.gd new file mode 100644 index 0000000..56ce19a --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRandom.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRepeatUntil.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRepeatUntil.gd new file mode 100644 index 0000000..ba88262 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTRepeatUntil.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTSuccess.gd b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTSuccess.gd new file mode 100644 index 0000000..d83ff45 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Decorators/BTSuccess.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTAction.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTAction.gd new file mode 100644 index 0000000..40feb87 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTAction.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardDelete.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardDelete.gd new file mode 100644 index 0000000..81fe449 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardDelete.gd @@ -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() + diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardSet.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardSet.gd new file mode 100644 index 0000000..36fa29c --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionBlackboardSet.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionCallable.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionCallable.gd new file mode 100644 index 0000000..6ef781b --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionCallable.gd @@ -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) diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionWait.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionWait.gd new file mode 100644 index 0000000..0c764bb --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTActionWait.gd @@ -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 +#------------------------------------------ + + diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTCondition.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTCondition.gd new file mode 100644 index 0000000..3a1266b --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTCondition.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardKeyExists.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardKeyExists.gd new file mode 100644 index 0000000..1149d3e --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardKeyExists.gd @@ -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() + diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardValuesComparison.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardValuesComparison.gd new file mode 100644 index 0000000..5425c7e --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionBlackboardValuesComparison.gd @@ -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() + diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionCallable.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionCallable.gd new file mode 100644 index 0000000..f150c4f --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTConditionCallable.gd @@ -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) diff --git a/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTLeaf.gd b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTLeaf.gd new file mode 100644 index 0000000..9debae0 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Nodes/Leaves/BTLeaf.gd @@ -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 + diff --git a/addons/yet_another_behavior_tree/src/Result/BTTickResult.gd b/addons/yet_another_behavior_tree/src/Result/BTTickResult.gd new file mode 100644 index 0000000..5c160d0 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Result/BTTickResult.gd @@ -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 +#------------------------------------------ diff --git a/addons/yet_another_behavior_tree/src/Utils/BTExpression.gd b/addons/yet_another_behavior_tree/src/Utils/BTExpression.gd new file mode 100644 index 0000000..315d1b9 --- /dev/null +++ b/addons/yet_another_behavior_tree/src/Utils/BTExpression.gd @@ -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 diff --git a/addons/yet_another_behavior_tree/yet_another_behavior_tree.gd b/addons/yet_another_behavior_tree/yet_another_behavior_tree.gd new file mode 100644 index 0000000..0813f65 --- /dev/null +++ b/addons/yet_another_behavior_tree/yet_another_behavior_tree.gd @@ -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 diff --git a/entities/Player.tscn b/entities/Player.tscn index aa1ae6b..1d7258c 100644 --- a/entities/Player.tscn +++ b/entities/Player.tscn @@ -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") diff --git a/entities/enemy/dummy.tscn b/entities/enemy/dummy.tscn index c57f0db..f910f0d 100644 --- a/entities/enemy/dummy.tscn +++ b/entities/enemy/dummy.tscn @@ -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"] diff --git a/project.godot b/project.godot index 097b2a6..3cba1b9 100644 --- a/project.godot +++ b/project.godot @@ -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 diff --git a/scenes/map/NearEnemy.gd b/scenes/map/NearEnemy.gd new file mode 100644 index 0000000..861528b --- /dev/null +++ b/scenes/map/NearEnemy.gd @@ -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 diff --git a/scenes/map/test_map_gd.tscn b/scenes/map/test_map_gd.tscn index 488142d..43d650b 100644 --- a/scenes/map/test_map_gd.tscn +++ b/scenes/map/test_map_gd.tscn @@ -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") diff --git a/scripts/player/Hitable.gd b/scripts/player/Hitable.gd index 80c2645..4020775 100644 --- a/scripts/player/Hitable.gd +++ b/scripts/player/Hitable.gd @@ -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) diff --git a/scripts/player/PlayerQ3.gd b/scripts/player/PlayerQ3.gd index 7902cca..ead3243 100644 --- a/scripts/player/PlayerQ3.gd +++ b/scripts/player/PlayerQ3.gd @@ -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( diff --git a/scripts/utils/network.gd b/scripts/utils/network.gd index 29ec4cc..c18bcbc 100644 --- a/scripts/utils/network.gd +++ b/scripts/utils/network.gd @@ -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)