Compare commits
143 Commits
Author | SHA1 | Date |
---|---|---|
|
1a192b6129 | |
|
8e3f37d46a | |
|
98778c1645 | |
|
7ca4c63191 | |
|
8788d8bf12 | |
|
f31d722320 | |
|
bbb4512437 | |
|
43ec612949 | |
|
998bf212b7 | |
|
ec8eb4bf91 | |
|
05cd3e67b0 | |
|
ed9762e62f | |
|
ac0b68aa13 | |
|
c3da26caba | |
|
e9f6a6fea5 | |
|
c3144875df | |
|
e37ff39641 | |
|
6292ee4404 | |
|
77dc9b3b85 | |
|
88701e9f20 | |
|
576df4092a | |
|
b8f266588a | |
|
eac7e56f42 | |
|
7aebed5897 | |
|
a6613c32f9 | |
|
76e02a75e5 | |
|
1b9cf17339 | |
|
0584b0401f | |
|
98917a2055 | |
|
10defe21a5 | |
|
3dcbee829c | |
|
e3be34670e | |
|
e3262108d7 | |
|
b144ebc7bc | |
|
672f92c87b | |
|
e2e42b90a8 | |
|
a952009293 | |
|
0982804a86 | |
|
dd427c25e2 | |
|
dddc713a3a | |
|
6fecc1e4b5 | |
|
fe87a87759 | |
|
0e0a4685f9 | |
|
955da07652 | |
|
90c0a9a4f6 | |
|
1359f1e606 | |
|
0d65c1117a | |
|
a5118ebc1b | |
|
17872e7048 | |
|
f7a63ca673 | |
|
691208016c | |
|
35a2cbac56 | |
|
db827a8d30 | |
|
360e24c330 | |
|
e9884589a8 | |
|
9cfdabca3f | |
|
23a6e5fdfe | |
|
6644f191ca | |
|
8b0b15fce4 | |
|
11548c51f0 | |
|
62a142f188 | |
|
7a3d5bc6a2 | |
|
6d79b7474e | |
|
44040dda06 | |
|
ba90deaa6a | |
|
08d8fcdf92 | |
|
51878e4b6e | |
|
008702b1e4 | |
|
6e8c22d598 | |
|
0b3b11a383 | |
|
4cac6276aa | |
|
ea671dd54b | |
|
bc7f677810 | |
|
057d4e669c | |
|
f600d633a3 | |
|
ae61d551c0 | |
|
a14cc4cc68 | |
|
d304f957ef | |
|
bf85350260 | |
|
03476721d9 | |
|
bebd6a15eb | |
|
4c9028fc66 | |
|
e21156df35 | |
|
591a1fe672 | |
|
f90c48eb81 | |
|
162de0f868 | |
|
423c4ce7a4 | |
|
a5d59a0a51 | |
|
85eda3c804 | |
|
6de8b9e4c4 | |
|
bbe71bb378 | |
|
7feff38d6b | |
|
632e26c922 | |
|
106608aca9 | |
|
d5bc62830a | |
|
3b15abf2c9 | |
|
6d049a3701 | |
|
65454c36a8 | |
|
e0e15b0ec4 | |
|
ee8c773e71 | |
|
7f38fe2b8b | |
|
500775eb14 | |
|
1cdde4d5a9 | |
|
eaa43020f5 | |
|
b5b1ac7289 | |
|
ece17d68d9 | |
|
85787616e7 | |
|
11abf36c99 | |
|
19d771fef2 | |
|
2b89d1d23e | |
|
6f318b83b8 | |
|
7a1b56f9c8 | |
|
2b86928737 | |
|
8c557f87f7 | |
|
6776319472 | |
|
760af804c0 | |
|
c49e5142a5 | |
|
60a767032e | |
|
60142b191d | |
|
134bb3214a | |
|
db7c990f51 | |
|
08884e6180 | |
|
c2130a7b2f | |
|
5ddc43fe94 | |
|
601aed3684 | |
|
0e4c06f3b8 | |
|
ac2d734122 | |
|
1ca1154cd0 | |
|
a8a0f24492 | |
|
50e9e570dd | |
|
d72c2e0648 | |
|
da2bc5e3bb | |
|
c4481d8bed | |
|
689c8fab6f | |
|
fd0eb34b4e | |
|
bfcc2f8e1b | |
|
b8c9db0d44 | |
|
4df6647a75 | |
|
d78adabf7c | |
|
1742018696 | |
|
a460c7898b | |
|
8ee3688da2 | |
|
9032ca0c7b |
|
@ -8,6 +8,9 @@ inputs:
|
|||
- linuxbsd
|
||||
- windows
|
||||
- macos
|
||||
bin:
|
||||
required: true
|
||||
type: string
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
|
@ -22,7 +25,7 @@ runs:
|
|||
- name: Generate C# glue
|
||||
shell: bash
|
||||
run: |
|
||||
./bin/${BIN} --headless --generate-mono-glue ./modules/mono/glue || true
|
||||
./bin/${{inputs.bin}} --headless --generate-mono-glue ./modules/mono/glue || true
|
||||
|
||||
- name: Build .NET assemblies
|
||||
shell: bash
|
||||
|
|
|
@ -5,7 +5,7 @@ on:
|
|||
godot-ref:
|
||||
description: A tag, branch or commit hash in the Godot repository.
|
||||
type: string
|
||||
default: 4.3-stable
|
||||
default: master
|
||||
limboai-ref:
|
||||
description: A tag, branch or commit hash in the LimboAI repository.
|
||||
type: string
|
||||
|
@ -13,7 +13,7 @@ on:
|
|||
godot-cpp-ref:
|
||||
description: A tag, branch or commit hash in the godot-cpp repository.
|
||||
type: string
|
||||
default: godot-4.3-stable
|
||||
default: master
|
||||
|
||||
jobs:
|
||||
cache-sha:
|
||||
|
|
|
@ -165,15 +165,16 @@ jobs:
|
|||
python --version
|
||||
scons --version
|
||||
|
||||
- name: Set up scons cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
restore-keys: |
|
||||
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.BIN}}-${{inputs.godot-ref}}
|
||||
# ! Note: we stopped using the scons cache in release builds.
|
||||
# - name: Set up scons cache
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: ${{github.workspace}}/.scons_cache/
|
||||
# key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# restore-keys: |
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}
|
||||
|
||||
- name: Compilation
|
||||
env:
|
||||
|
|
|
@ -11,7 +11,11 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
debug-symbols:
|
||||
description: Build with debug symbols
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -26,17 +30,22 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
debug-symbols:
|
||||
description: Build with debug symbols
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
SCONS_CACHE_LIMIT: 4096
|
||||
SCONSFLAGS: dev_build=no debug_symbols=no
|
||||
SCONSFLAGS: use_mingw=yes dev_build=no
|
||||
EM_VERSION: 3.1.45
|
||||
EM_CACHE_FOLDER: "emsdk-cache"
|
||||
GODOT_VERSION: 4.3-stable
|
||||
GODOT_VERSION: 4.4-beta3
|
||||
GODOT_REPO: godotengine/godot-builds
|
||||
|
||||
jobs:
|
||||
gdextension:
|
||||
|
@ -100,7 +109,7 @@ jobs:
|
|||
- name: 🌐 Web (wasm32, debug)
|
||||
runner: ubuntu-20.04
|
||||
platform: web
|
||||
target: template_debug
|
||||
target: editor
|
||||
arch: wasm32
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -114,7 +123,7 @@ jobs:
|
|||
- name: 🤖 Android (arm64, debug)
|
||||
runner: ubuntu-20.04
|
||||
platform: android
|
||||
target: template_debug
|
||||
target: editor
|
||||
arch: arm64
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -128,7 +137,7 @@ jobs:
|
|||
- name: 🤖 Android (arm32, debug)
|
||||
runner: ubuntu-20.04
|
||||
platform: android
|
||||
target: template_debug
|
||||
target: editor
|
||||
arch: arm32
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -142,7 +151,7 @@ jobs:
|
|||
- name: 🤖 Android (x86_64, debug)
|
||||
runner: ubuntu-20.04
|
||||
platform: android
|
||||
target: template_debug
|
||||
target: editor
|
||||
arch: x86_64
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -156,10 +165,40 @@ jobs:
|
|||
- name: 🤖 Android (x86_32, debug)
|
||||
runner: ubuntu-20.04
|
||||
platform: android
|
||||
target: template_debug
|
||||
target: editor
|
||||
arch: x86_32
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: 🍏 iOS (arm64, release)
|
||||
runner: macos-latest
|
||||
platform: ios
|
||||
target: template_release
|
||||
arch: arm64
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: 🍏 iOS (arm64, debug)
|
||||
runner: macos-latest
|
||||
platform: ios
|
||||
target: editor
|
||||
arch: arm64
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: 🍏 iOS (simulator, release)
|
||||
runner: macos-latest
|
||||
platform: ios
|
||||
target: template_release
|
||||
arch: universal
|
||||
scons-flags: ios_simulator=yes
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: 🍏 iOS (simulator, debug)
|
||||
runner: macos-latest
|
||||
platform: ios
|
||||
target: editor
|
||||
arch: universal
|
||||
scons-flags: ios_simulator=yes
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
exclude:
|
||||
- { opts: { should-build: false } }
|
||||
|
||||
|
@ -247,26 +286,29 @@ jobs:
|
|||
uses: ammaraskar/msvc-problem-matcher@master
|
||||
|
||||
- name: Set up scons cache
|
||||
if: inputs.test-build # ! Only cache test/PR builds
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
key: ${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
key: ${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
restore-keys: |
|
||||
${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
${{env.BIN}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.BIN}}-${{inputs.godot-cpp-ref}}
|
||||
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.BIN}}-${{inputs.debug-symbols}}-${{inputs.godot-cpp-ref}}
|
||||
|
||||
- name: Compilation
|
||||
shell: bash
|
||||
env:
|
||||
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
|
||||
DEBUG_FLAGS: ${{ inputs.debug-symbols && 'debug_symbols=yes symbols_visibility=visible' || 'debug_symbols=no' }}
|
||||
run: |
|
||||
PATH=${GITHUB_WORKSPACE}/buildroot/bin:$PATH
|
||||
scons platform=${{matrix.opts.platform}} target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} ${{env.SCONSFLAGS}}
|
||||
scons platform=${{matrix.opts.platform}} target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} ${{env.DEBUG_FLAGS}} ${{matrix.opts.scons-flags}} ${{env.SCONSFLAGS}}
|
||||
|
||||
- name: Prepare artifact
|
||||
shell: bash
|
||||
run: |
|
||||
ls -R demo/addons/limboai/
|
||||
mkdir out
|
||||
mv demo/addons/ out/
|
||||
cp {README,LICENSE,LOGO_LICENSE}.md out/addons/limboai/
|
||||
|
@ -310,7 +352,7 @@ jobs:
|
|||
echo "Downloading Godot ${GODOT_VERSION}"
|
||||
mkdir bin
|
||||
cd bin
|
||||
wget "https://github.com/godotengine/godot/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
|
||||
wget "https://github.com/${GODOT_REPO}/releases/download/${GODOT_VERSION}/Godot_v${GODOT_VERSION}_linux.x86_64.zip" -O godot.zip
|
||||
unzip godot.zip
|
||||
rm godot.zip
|
||||
mv Godot_* godot
|
||||
|
|
|
@ -136,17 +136,25 @@ jobs:
|
|||
|
||||
- name: Set up Vulkan SDK
|
||||
run: |
|
||||
sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
|
||||
#sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
|
||||
- name: Set up scons cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
restore-keys: |
|
||||
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.BIN}}-${{inputs.godot-ref}}
|
||||
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
|
||||
unzip /tmp/vulkan-sdk.zip -d /tmp
|
||||
/tmp/InstallVulkan.app/Contents/MacOS/InstallVulkan --accept-licenses --default-answer --confirm-command install
|
||||
rm -Rf /tmp/InstallVulkan.app
|
||||
rm -f /tmp/vulkan-sdk.zip
|
||||
|
||||
# ! Note: we stopped using the scons cache in release builds.
|
||||
# - name: Set up scons cache
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: ${{github.workspace}}/.scons_cache/
|
||||
# key: ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# restore-keys: |
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
# ${{env.BIN}}-${{inputs.godot-ref}}
|
||||
|
||||
- name: Compilation
|
||||
env:
|
||||
|
@ -192,7 +200,14 @@ jobs:
|
|||
|
||||
- name: Set up Vulkan SDK
|
||||
run: |
|
||||
sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
|
||||
#sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
|
||||
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
|
||||
unzip /tmp/vulkan-sdk.zip -d /tmp
|
||||
/tmp/InstallVulkan.app/Contents/MacOS/InstallVulkan --accept-licenses --default-answer --confirm-command install
|
||||
rm -Rf /tmp/InstallVulkan.app
|
||||
rm -f /tmp/vulkan-sdk.zip
|
||||
|
||||
- name: Download templates artifact
|
||||
uses: actions/download-artifact@v4
|
||||
|
|
|
@ -11,7 +11,7 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -26,7 +26,7 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -227,6 +227,7 @@ jobs:
|
|||
sudo apt-get install libwayland-dev
|
||||
|
||||
- name: Set up scons cache
|
||||
if: inputs.test-build # ! Only cache test/PR builds
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
|
@ -248,6 +249,7 @@ jobs:
|
|||
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
|
||||
with:
|
||||
platform: linuxbsd
|
||||
bin: ${{env.BIN}}
|
||||
|
||||
- name: Prepare artifact
|
||||
env:
|
||||
|
|
|
@ -11,7 +11,7 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -26,7 +26,7 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -165,9 +165,19 @@ jobs:
|
|||
|
||||
- name: Set up Vulkan SDK
|
||||
run: |
|
||||
sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
# ! Note: Vulkan SDK changed packaging, so we need to inline these steps for the time being.
|
||||
#sh misc/scripts/install_vulkan_sdk_macos.sh
|
||||
|
||||
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/config.json" -o /tmp/vulkan-sdk.json
|
||||
sdk_version=`jq -r '.version' /tmp/vulkan-sdk.json`
|
||||
curl -L "https://sdk.lunarg.com/sdk/download/latest/mac/vulkan-sdk.zip" -o /tmp/vulkan-sdk.zip
|
||||
unzip /tmp/vulkan-sdk.zip -d /tmp
|
||||
/tmp/InstallVulkan-${sdk_version}.app/Contents/MacOS/InstallVulkan-${sdk_version} --accept-licenses --default-answer --confirm-command install
|
||||
rm -Rf /tmp/InstallVulkan-${sdk_version}.app
|
||||
rm -f /tmp/vulkan-sdk.zip
|
||||
|
||||
- name: Set up scons cache
|
||||
if: inputs.test-build # ! Only cache test/PR builds
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
|
@ -188,6 +198,7 @@ jobs:
|
|||
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
|
||||
with:
|
||||
platform: macos
|
||||
bin: ${{env.BIN}}
|
||||
|
||||
- name: Prepare artifact
|
||||
run: |
|
||||
|
|
|
@ -26,8 +26,8 @@ concurrency:
|
|||
|
||||
# Global Settings.
|
||||
env:
|
||||
GODOT_REF: "4.3-stable"
|
||||
GODOT_CPP_REF: "godot-4.3-stable"
|
||||
GODOT_REF: "master"
|
||||
GODOT_CPP_REF: "master"
|
||||
|
||||
jobs:
|
||||
unit-tests:
|
||||
|
@ -36,7 +36,7 @@ jobs:
|
|||
|
||||
# Settings
|
||||
env:
|
||||
SCONSFLAGS: platform=linuxbsd target=editor arch=x86_64 production=false dev_build=true tests=true verbose=yes warnings=extra werror=yes
|
||||
SCONSFLAGS: platform=linuxbsd target=editor arch=x86_64 production=false dev_build=true tests=true verbose=yes warnings=extra werror=yes strict_checks=yes
|
||||
SCONS_CACHE_LIMIT: 7168
|
||||
BIN: godot.linuxbsd.editor.dev.x86_64
|
||||
|
||||
|
@ -101,6 +101,18 @@ jobs:
|
|||
run: |
|
||||
bin/${{ env.BIN }} --test --headless
|
||||
|
||||
static-checks:
|
||||
name: ⚙️ Static checks
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Clone LimboAI module
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Code style checks
|
||||
uses: pre-commit/action@v3.0.1
|
||||
with:
|
||||
extra_args: --all-files
|
||||
|
||||
cache-env:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
|
|
|
@ -120,15 +120,16 @@ jobs:
|
|||
python --version
|
||||
scons --version
|
||||
|
||||
- name: Set up scons cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
key: ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
restore-keys: |
|
||||
${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.CACHE_NAME}}-${{inputs.godot-ref}}
|
||||
# ! Note: we stopped using the scons cache in release builds.
|
||||
# - name: Set up scons cache
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: ${{github.workspace}}/.scons_cache/
|
||||
# key: ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# restore-keys: |
|
||||
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}-${{env.LIMBOAI_VERSION}}
|
||||
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
# ${{env.CACHE_NAME}}-${{inputs.godot-ref}}
|
||||
|
||||
- name: Compilation
|
||||
env:
|
||||
|
|
|
@ -11,7 +11,7 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
|
@ -26,22 +26,23 @@ on:
|
|||
type: string
|
||||
default: master
|
||||
test-build:
|
||||
description: Should we perform only a limited number of test builds?
|
||||
description: Limit to pre-defined test builds
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
# Global Settings
|
||||
env:
|
||||
SCONS_CACHE_MSVC_CONFIG: true
|
||||
BUILD_IMAGE_VERSION: 4.3-f40
|
||||
MESA_VERSION: 23.1.9-1
|
||||
SCONS_CACHE_LIMIT: 4096
|
||||
SCONSFLAGS: production=yes tests=no verbose=yes warnings=extra werror=yes
|
||||
DOTNET_NOLOGO: true
|
||||
DOTNET_CLI_TELEMETRY_OPTOUT: true
|
||||
SCONSFLAGS: production=yes use_mingw=yes verbose=yes warnings=no progress=no d3d12=yes
|
||||
|
||||
jobs:
|
||||
windows-builds:
|
||||
runs-on: "windows-latest"
|
||||
runs-on: "ubuntu-24.04"
|
||||
name: ${{ matrix.opts.name }}
|
||||
outputs:
|
||||
built-dotnet-editor: ${{ steps.mark-dotnet-editor.outputs.built-dotnet-editor }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
@ -51,18 +52,21 @@ jobs:
|
|||
- name: Editor (x86_64, release)
|
||||
target: editor
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: false
|
||||
should-build: true
|
||||
|
||||
- name: Template (x86_64, release)
|
||||
target: template_release
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: false
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (x86_64, debug)
|
||||
target: template_debug
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: false
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -71,18 +75,21 @@ jobs:
|
|||
# - name: Editor (x86_32, release)
|
||||
# target: editor
|
||||
# arch: x86_32
|
||||
# llvm: false
|
||||
# dotnet: false
|
||||
# should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (x86_32, release)
|
||||
target: template_release
|
||||
arch: x86_32
|
||||
llvm: false
|
||||
dotnet: false
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (x86_32, debug)
|
||||
target: template_debug
|
||||
arch: x86_32
|
||||
llvm: false
|
||||
dotnet: false
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -91,19 +98,24 @@ jobs:
|
|||
# - name: Editor (arm64, release)
|
||||
# target: editor
|
||||
# arch: arm64
|
||||
# llvm: true
|
||||
# dotnet: false
|
||||
# should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (arm64, release)
|
||||
target: template_release
|
||||
arch: arm64
|
||||
llvm: true
|
||||
dotnet: false
|
||||
scons-flags: mingw_prefix=/root/llvm-mingw
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (arm64, debug)
|
||||
target: template_debug
|
||||
arch: arm64
|
||||
llvm: true
|
||||
dotnet: false
|
||||
scons-flags: mingw_prefix=/root/llvm-mingw
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
# * .NET x86_64
|
||||
|
@ -111,18 +123,21 @@ jobs:
|
|||
- name: Editor .NET (x86_64, release)
|
||||
target: editor
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: true
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template .NET (x86_64, release)
|
||||
target: template_release
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: true
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template .NET (x86_64, debug)
|
||||
target: template_debug
|
||||
arch: x86_64
|
||||
llvm: false
|
||||
dotnet: true
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
|
@ -131,46 +146,54 @@ jobs:
|
|||
# - name: Editor .NET (x86_32, release)
|
||||
# target: editor
|
||||
# arch: x86_32
|
||||
# llvm: false
|
||||
# dotnet: true
|
||||
# should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template .NET (x86_32, release)
|
||||
target: template_release
|
||||
arch: x86_32
|
||||
llvm: false
|
||||
dotnet: true
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template .NET (x86_32, debug)
|
||||
target: template_debug
|
||||
arch: x86_32
|
||||
llvm: false
|
||||
dotnet: true
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
# * .NET arm64
|
||||
|
||||
# - name: Editor (arm64, release)
|
||||
# - name: Editor .NET (arm64, release)
|
||||
# target: editor
|
||||
# arch: arm64
|
||||
# llvm: true
|
||||
# dotnet: true
|
||||
# should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (arm64, release)
|
||||
- name: Template .NET (arm64, release)
|
||||
target: template_release
|
||||
arch: arm64
|
||||
llvm: true
|
||||
dotnet: true
|
||||
scons-flags: mingw_prefix=/root/llvm-mingw
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
- name: Template (arm64, debug)
|
||||
- name: Template .NET (arm64, debug)
|
||||
target: template_debug
|
||||
arch: arm64
|
||||
llvm: true
|
||||
dotnet: true
|
||||
scons-flags: mingw_prefix=/root/llvm-mingw
|
||||
should-build: ${{ !inputs.test-build }}
|
||||
|
||||
exclude:
|
||||
- { opts: { should-build: false } }
|
||||
|
||||
env:
|
||||
BIN: godot.windows.${{matrix.opts.target}}.${{matrix.opts.arch}}${{ matrix.opts.dotnet == true && '.mono' || '' }}
|
||||
BIN: godot.windows.${{matrix.opts.target}}.${{matrix.opts.arch}}${{matrix.opts.llvm && '.llvm' || ''}}${{matrix.opts.dotnet == true && '.mono' || ''}}
|
||||
|
||||
steps:
|
||||
- name: Clone Godot
|
||||
|
@ -185,26 +208,11 @@ jobs:
|
|||
path: modules/limboai
|
||||
ref: ${{ inputs.limboai-ref }}
|
||||
|
||||
# Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
|
||||
# Inits GODOT_VERSION, LIMBOAI_VERSION, NAME_PREFIX, GODOT_VERSION_STATUS, BUILD_NAME environment variables.
|
||||
- uses: ./modules/limboai/.github/actions/init-version
|
||||
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
architecture: "x64"
|
||||
|
||||
- name: Set up scons
|
||||
run: |
|
||||
python -c "import sys; print(sys.version)"
|
||||
python -m pip install scons==4.4.0
|
||||
python --version
|
||||
scons --version
|
||||
|
||||
- name: Set up MSVC problem matcher
|
||||
uses: ammaraskar/msvc-problem-matcher@master
|
||||
|
||||
- name: Set up scons cache
|
||||
if: inputs.test-build # ! Only cache test/PR builds
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{github.workspace}}/.scons_cache/
|
||||
|
@ -214,17 +222,54 @@ jobs:
|
|||
${{env.BIN}}-${{inputs.godot-ref}}-${{inputs.limboai-ref}}
|
||||
${{env.BIN}}-${{inputs.godot-ref}}
|
||||
|
||||
- name: Compilation
|
||||
env:
|
||||
SCONS_CACHE: ${{github.workspace}}/.scons_cache/
|
||||
- name: Static ANGLE libs
|
||||
run: |
|
||||
scons -j2 platform=windows target=${{matrix.opts.target}} arch=${{matrix.opts.arch}} module_mono_enabled=${{matrix.opts.dotnet}} ${{env.SCONSFLAGS}}
|
||||
mkdir -p deps/angle
|
||||
cd deps/angle
|
||||
url=https://github.com/godotengine/godot-angle-static/releases/download/chromium%2F6601.2/godot-angle-static
|
||||
curl -L -o windows_${{matrix.opts.arch}}.zip $url-${{matrix.opts.arch}}-${{matrix.opts.llvm && 'llvm' || 'gcc'}}-release.zip
|
||||
unzip windows_${{matrix.opts.arch}}.zip
|
||||
rm windows_${{matrix.opts.arch}}.zip
|
||||
|
||||
- name: Build .NET assemblies
|
||||
if: matrix.opts.dotnet && matrix.opts.target == 'editor'
|
||||
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
|
||||
with:
|
||||
platform: windows
|
||||
- name: Mesa libs
|
||||
run: |
|
||||
mkdir -p deps/mesa
|
||||
cd deps/mesa
|
||||
curl -L -o mesa_${{matrix.opts.arch}}.zip https://github.com/godotengine/godot-nir-static/releases/download/${{env.MESA_VERSION}}/godot-nir-static-${{matrix.opts.arch}}-${{matrix.opts.llvm && 'llvm' || 'gcc'}}-release.zip
|
||||
unzip -o mesa_${{matrix.opts.arch}}.zip
|
||||
rm -f mesa_${{matrix.opts.arch}}.zip
|
||||
|
||||
- name: Pull build container
|
||||
run: |
|
||||
podman pull ghcr.io/limbonaut/godot-windows:${{env.BUILD_IMAGE_VERSION}}
|
||||
|
||||
- name: Build using container
|
||||
shell: bash
|
||||
run: |
|
||||
scons_command="scons \
|
||||
platform=windows \
|
||||
target=${{matrix.opts.target}} \
|
||||
arch=${{matrix.opts.arch}} \
|
||||
use_llvm=${{matrix.opts.llvm}} \
|
||||
module_mono_enabled=${{matrix.opts.dotnet}} \
|
||||
${{env.SCONSFLAGS}} \
|
||||
${{matrix.opts.scons-flags}} \
|
||||
angle_libs=/build/deps/angle \
|
||||
mesa_libs=/build/deps/mesa \
|
||||
"
|
||||
podman_run="podman run -it --rm \
|
||||
--env GODOT_VERSION_STATUS=${GODOT_VERSION_STATUS} \
|
||||
--env BUILD_NAME=${BUILD_NAME} \
|
||||
--env NUM_CORES=$(nproc --all) \
|
||||
--env DOTNET_NOLOGO=true \
|
||||
--env DOTNET_CLI_TELEMETRY_OPTOUT=true \
|
||||
--env SCONS_CACHE=/build/.scons_cache/ \
|
||||
--env SCONS_CACHE_LIMIT=${SCONS_CACHE_LIMIT} \
|
||||
-v ${GITHUB_WORKSPACE}/:/build/ \
|
||||
-w /build godot-windows:${{env.BUILD_IMAGE_VERSION}} bash -c \
|
||||
"
|
||||
echo "Running ${podman_run} \"${scons_command}\""
|
||||
${podman_run} "${scons_command}"
|
||||
|
||||
- name: Prepare artifact
|
||||
shell: bash
|
||||
|
@ -252,3 +297,62 @@ jobs:
|
|||
with:
|
||||
name: ${{env.NAME_PREFIX}}${{matrix.opts.dotnet == true && '.dotnet' || ''}}.${{matrix.opts.target}}.windows.${{matrix.opts.arch}}
|
||||
path: out/*
|
||||
|
||||
- name: Mark .NET editor as built
|
||||
if: matrix.opts.dotnet && matrix.opts.target == 'editor'
|
||||
id: mark-dotnet-editor
|
||||
run: echo "built-dotnet-editor=true" >> $GITHUB_OUTPUT
|
||||
|
||||
|
||||
dotnet-assemblies:
|
||||
name: .NET assembly for ${{matrix.opts.arch}}
|
||||
needs: windows-builds
|
||||
if: always() && needs.windows-builds.outputs.built-dotnet-editor == 'true'
|
||||
runs-on: "windows-latest"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
opts:
|
||||
- arch: x86_64
|
||||
llvm: false
|
||||
env:
|
||||
BIN: godot.windows.editor.${{matrix.opts.arch}}${{matrix.opts.llvm && '.llvm' || ''}}.mono
|
||||
steps:
|
||||
- name: Clone Godot
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: godotengine/godot
|
||||
ref: ${{ inputs.godot-ref }}
|
||||
|
||||
- name: Clone LimboAI module
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: modules/limboai
|
||||
ref: ${{ inputs.limboai-ref }}
|
||||
|
||||
# Inits GODOT_VERSION, LIMBOAI_VERSION and NAME_PREFIX environment variables.
|
||||
- uses: ./modules/limboai/.github/actions/init-version
|
||||
|
||||
- name: Reconstruct artifact name
|
||||
shell: bash
|
||||
run: |
|
||||
echo "ARTIFACT=${{env.NAME_PREFIX}}.dotnet.editor.windows.${{matrix.opts.arch}}" >> $GITHUB_ENV
|
||||
|
||||
- name: Download editor artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{env.ARTIFACT}}
|
||||
path: bin/
|
||||
|
||||
- name: Build .NET assemblies
|
||||
uses: ./modules/limboai/.github/actions/build-dotnet-assemblies
|
||||
with:
|
||||
platform: windows
|
||||
bin: ${{env.BIN}}
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.ARTIFACT}}
|
||||
overwrite: true
|
||||
path: bin/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Copyright 2021-2024 Serhii Snitsaruk
|
||||
Copyright (c) 2023-2025 Serhii Snitsaruk and the LimboAI contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
|
39
README.md
39
README.md
|
@ -16,7 +16,7 @@
|
|||
**LimboAI** is an open-source C++ plugin for **Godot Engine 4** providing a combination of
|
||||
**Behavior Trees** and **State Machines**, which can be used together to create complex AI behaviors.
|
||||
It comes with a behavior tree editor, built-in documentation, visual debugger, extensive demo project with a tutorial, and more!
|
||||
While it is implemented in C++, it fully supports GDScript for [creating your own tasks](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html) and [states](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html).
|
||||
While it is implemented in C++, it fully supports GDScript for [creating your own tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) and [states](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html).
|
||||
|
||||
If you enjoy using LimboAI, please **consider supporting** my efforts with a donation on Ko-fi 😊 Your contribution will help me continue developing and improving it.
|
||||
|
||||
|
@ -24,7 +24,7 @@ If you enjoy using LimboAI, please **consider supporting** my efforts with a don
|
|||
|
||||

|
||||
|
||||
Behavior Trees are powerful hierarchical structures used to model and control the behavior of agents in a game (e.g., characters, enemies). They are designed to make it easier to create rich and highly modular behaviors for your games. To learn more about behavior trees, check out [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/getting-started/introduction.html) and our demo project, which includes a tutorial.
|
||||
Behavior Trees are powerful hierarchical structures used to model and control the behavior of agents in a game (e.g., characters, enemies). They are designed to make it easier to create rich and highly modular behaviors for your games. To learn more about behavior trees, check out [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html) and our demo project, which includes a tutorial.
|
||||
|
||||
## Demonstration
|
||||
|
||||
|
@ -50,13 +50,13 @@ Behavior Trees are powerful hierarchical structures used to model and control th
|
|||
- Execute `BehaviorTree` resources using the `BTPlayer` node.
|
||||
- Create complex behaviors by combining and nesting tasks in a hierarchy.
|
||||
- Control execution flow using composite, decorator, and condition tasks.
|
||||
- [Create custom tasks](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html) by extending core classes: `BTAction`, `BTCondition`, `BTDecorator`, and `BTComposite`.
|
||||
- [Create custom tasks](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html) by extending core classes: `BTAction`, `BTCondition`, `BTDecorator`, and `BTComposite`.
|
||||
- Built-in class documentation.
|
||||
- Blackboard system: Share data seamlessly between tasks using the `Blackboard`.
|
||||
- Blackboard plans: Define variables in the BehaviorTree resource and override their values in the BTPlayer node.
|
||||
- Plan editor: Manage variables, their data types and property hints.
|
||||
- Blackboard scopes: Prevent name conflicts and enable advanced techniques like [sharing data between several agents](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html#sharing-data-between-several-agents).
|
||||
- Blackboard parameters: [Export a BB parameter](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html#task-parameters), for which user can provide a value or bind it to a blackboard variable (can be used in custom tasks).
|
||||
- Blackboard scopes: Prevent name conflicts and enable advanced techniques like [sharing data between several agents](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#sharing-data-between-several-agents).
|
||||
- Blackboard parameters: [Export a BB parameter](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html#task-parameters), for which user can provide a value or bind it to a blackboard variable (can be used in custom tasks).
|
||||
- Inspector support for specifying blackboard variables (custom editor for exported `StringName` properties ending with "_var").
|
||||
- Use the `BTSubtree` task to execute a tree from a different resource file, promoting organization and reusability.
|
||||
- Visual Debugger: Inspect the execution of any BT in a running scene to identify and troubleshoot issues.
|
||||
|
@ -67,24 +67,24 @@ Behavior Trees are powerful hierarchical structures used to model and control th
|
|||
- Extend the `LimboState` class to implement state logic.
|
||||
- `LimboHSM` node serves as a state machine that manages `LimboState` instances and transitions.
|
||||
- `LimboHSM` is a state itself and can be nested within other `LimboHSM` instances.
|
||||
- [Event-based](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html#events-and-transitions): Transitions are associated with events and are triggered by the state machine when the relevant event is dispatched, allowing for better decoupling of transitions from state logic.
|
||||
- [Event-based](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#events-and-transitions): Transitions are associated with events and are triggered by the state machine when the relevant event is dispatched, allowing for better decoupling of transitions from state logic.
|
||||
- Combine state machines with behavior trees using `BTState` for advanced reactive AI.
|
||||
- Delegation Option: Using the vanilla `LimboState`, [delegate the implementation](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html#single-file-state-machine-setup) to your callback functions, making it perfect for rapid prototyping and game jams.
|
||||
- Delegation Option: Using the vanilla `LimboState`, [delegate the implementation](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html#single-file-state-machine-setup) to your callback functions, making it perfect for rapid prototyping and game jams.
|
||||
- 🛈 Note: State machine setup and initialization require code; there is no GUI editor.
|
||||
|
||||
- **Tested:** Behavior tree tasks and HSM are covered by unit tests.
|
||||
|
||||
- **GDExtension:** LimboAI can be [used as extension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html). Custom engine builds are not necessary.
|
||||
- **GDExtension:** LimboAI can be [used as extension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version). Custom engine builds are not necessary.
|
||||
|
||||
- **Demo + Tutorial:** Check out our extensive demo project, which includes an introduction to behavior trees using examples.
|
||||
|
||||
## First steps
|
||||
|
||||
Follow the [First steps](https://limboai.readthedocs.io/en/stable/index.html#first-steps) guide to learn how to get started with LimboAI and the demo project.
|
||||
Follow the [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html) guide to learn how to get started with LimboAI and the demo project.
|
||||
|
||||
## Getting LimboAI
|
||||
|
||||
LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html).
|
||||
LimboAI can be used as either a C++ module or as a GDExtension shared library. GDExtension version is more convenient to use but somewhat limited in features. Whichever you choose to use, your project will stay compatible with both and you can switch from one to the other any time. See [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version).
|
||||
|
||||
### Precompiled builds
|
||||
|
||||
|
@ -109,19 +109,20 @@ LimboAI can be used as either a C++ module or as a GDExtension shared library. G
|
|||
## Using the plugin
|
||||
|
||||
- Online Documentation: [stable](https://limboai.readthedocs.io/en/stable/index.html), [latest](https://limboai.readthedocs.io/en/latest/index.html)
|
||||
- [First steps](https://limboai.readthedocs.io/en/stable/index.html#first-steps)
|
||||
- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/getting-started/introduction.html)
|
||||
- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/stable/getting-started/custom-tasks.html)
|
||||
- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/stable/getting-started/using-blackboard.html)
|
||||
- [Accessing nodes in the scene tree](https://limboai.readthedocs.io/en/stable/getting-started/accessing-nodes.html)
|
||||
- [State machines](https://limboai.readthedocs.io/en/stable/getting-started/hsm.html)
|
||||
- [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/gdextension.html)
|
||||
- [Getting started](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html)
|
||||
- [Introduction to Behavior Trees](https://limboai.readthedocs.io/en/stable/behavior-trees/introduction.html)
|
||||
- [Creating custom tasks in GDScript](https://limboai.readthedocs.io/en/stable/behavior-trees/custom-tasks.html)
|
||||
- [Sharing data using Blackboard](https://limboai.readthedocs.io/en/stable/behavior-trees/using-blackboard.html)
|
||||
- [Accessing nodes in the scene tree](https://limboai.readthedocs.io/en/stable/behavior-trees/accessing-nodes.html)
|
||||
- [State machines](https://limboai.readthedocs.io/en/stable/hierarchical-state-machines/create-hsm.html)
|
||||
- [Using GDExtension](https://limboai.readthedocs.io/en/stable/getting-started/getting-limboai.html#get-gdextension-version)
|
||||
- [Using LimboAI with C#](https://limboai.readthedocs.io/en/stable/getting-started/c-sharp.html)
|
||||
- [Class reference](https://limboai.readthedocs.io/en/stable/getting-started/featured-classes.html)
|
||||
- [Class reference](https://limboai.readthedocs.io/en/stable/classes/featured-classes.html)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please open issues for bug reports, feature requests, or code changes. Keep the minor versions backward-compatible when submitting pull requests.
|
||||
Contributions are welcome! Please open issues for bug reports, feature requests, or code changes.
|
||||
For detailed guidelines on contributing to code or documentation, check out our [Contributing](https://limboai.readthedocs.io/en/latest/getting-started/contributing.html) page.
|
||||
|
||||
If you have an idea for a behavior tree task or a feature that could be useful in a variety of projects, open an issue to discuss it.
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_aabb.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_basis.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_bool.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_byte_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_color.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_color_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_dictionary.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_float.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_float32_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_float64_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_int.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_int32_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_int64_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_node.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -11,18 +11,9 @@
|
|||
|
||||
#include "bb_node.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/error/error_macros.h"
|
||||
#include "scene/main/node.h"
|
||||
#endif // LIMBOAI_MODULE
|
||||
|
||||
#ifdef LIMBOAI_GDEXTENSION
|
||||
#include <godot_cpp/classes/node.hpp>
|
||||
#endif // LIMBOAI_GDEXTENSION
|
||||
|
||||
Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboard, const Variant &p_default) {
|
||||
ERR_FAIL_NULL_V_MSG(p_scene_root, Variant(), "BBNode: get_value() failed - scene_root is null.");
|
||||
ERR_FAIL_NULL_V_MSG(p_blackboard, Variant(), "BBNode: get_value() failed - blackboard is null.");
|
||||
ERR_FAIL_COND_V_MSG(p_blackboard.is_null(), Variant(), "BBNode: get_value() failed - blackboard is null.");
|
||||
|
||||
Variant val;
|
||||
if (get_value_source() == SAVED_VALUE) {
|
||||
|
@ -33,13 +24,10 @@ Variant BBNode::get_value(Node *p_scene_root, const Ref<Blackboard> &p_blackboar
|
|||
|
||||
if (val.get_type() == Variant::NODE_PATH) {
|
||||
return p_scene_root->get_node_or_null(val);
|
||||
} else if (val.get_type() == Variant::OBJECT || val.get_type() == Variant::NIL) {
|
||||
return val;
|
||||
} else {
|
||||
Object *obj = val;
|
||||
if (unlikely(obj == nullptr && val.get_type() != Variant::NIL)) {
|
||||
WARN_PRINT("BBNode: Unexpected variant type of a blackboard variable.");
|
||||
return p_default;
|
||||
} else {
|
||||
return obj;
|
||||
}
|
||||
WARN_PRINT("BBNode: Unexpected variant type: " + Variant::get_type_name(val.get_type()) + ". Returning default value.");
|
||||
return p_default;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_node.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_param.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_param.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_plane.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_projection.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_quaternion.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_rect2.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_rect2i.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_string.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_string_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_string_name.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_transform2d.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_transform3d.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_variant.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_variant.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector2.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector2_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector2i.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector3.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector3_array.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector3i.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector4.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_vector4i.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_variable.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bb_variable.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* blackboard.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
#include "blackboard.h"
|
||||
#include "../util/limbo_compat.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "core/variant/variant.h"
|
||||
|
@ -75,6 +76,26 @@ TypedArray<StringName> Blackboard::list_vars() const {
|
|||
return var_names;
|
||||
}
|
||||
|
||||
void Blackboard::print_state() const {
|
||||
Ref<Blackboard> bb{ this };
|
||||
int scope_idx = 0;
|
||||
while (bb.is_valid()) {
|
||||
int i = 0;
|
||||
String line = "Scope " + itos(scope_idx) + ": { ";
|
||||
for (const KeyValue<StringName, BBVariable> &kv : bb->data) {
|
||||
if (i > 0) {
|
||||
line += ", ";
|
||||
}
|
||||
line += String(kv.key) + ": " + String(kv.value.get_value());
|
||||
i++;
|
||||
}
|
||||
line += " }";
|
||||
PRINT_LINE(line);
|
||||
bb = bb->get_parent();
|
||||
scope_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary Blackboard::get_vars_as_dict() const {
|
||||
Dictionary dict;
|
||||
for (const KeyValue<StringName, BBVariable> &kv : data) {
|
||||
|
@ -136,6 +157,7 @@ void Blackboard::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("erase_var", "var_name"), &Blackboard::erase_var);
|
||||
ClassDB::bind_method(D_METHOD("clear"), &Blackboard::clear);
|
||||
ClassDB::bind_method(D_METHOD("list_vars"), &Blackboard::list_vars);
|
||||
ClassDB::bind_method(D_METHOD("print_state"), &Blackboard::print_state);
|
||||
ClassDB::bind_method(D_METHOD("get_vars_as_dict"), &Blackboard::get_vars_as_dict);
|
||||
ClassDB::bind_method(D_METHOD("populate_from_dict", "dictionary"), &Blackboard::populate_from_dict);
|
||||
ClassDB::bind_method(D_METHOD("top"), &Blackboard::top);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* blackboard.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -57,6 +57,7 @@ public:
|
|||
void erase_var(const StringName &p_name);
|
||||
void clear() { data.clear(); }
|
||||
TypedArray<StringName> list_vars() const;
|
||||
void print_state() const;
|
||||
|
||||
Dictionary get_vars_as_dict() const;
|
||||
void populate_from_dict(const Dictionary &p_dictionary);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* blackboard_plan.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -13,9 +13,20 @@
|
|||
|
||||
#include "../util/limbo_utility.h"
|
||||
|
||||
#ifdef LIMBOAI_MODULE
|
||||
#include "editor/editor_inspector.h"
|
||||
#include "editor/editor_interface.h"
|
||||
#elif LIMBOAI_GDEXTENSION
|
||||
#include <godot_cpp/classes/editor_inspector.hpp>
|
||||
#include <godot_cpp/classes/editor_interface.hpp>
|
||||
#include <godot_cpp/classes/engine.hpp>
|
||||
#include <godot_cpp/classes/scene_tree.hpp>
|
||||
#endif
|
||||
|
||||
bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
||||
String name_str = p_name;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// * Editor
|
||||
if (var_map.has(p_name)) {
|
||||
BBVariable &var = var_map[p_name];
|
||||
|
@ -26,29 +37,51 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
// * Mapping
|
||||
if (name_str.begins_with("mapping/")) {
|
||||
StringName mapped_var_name = name_str.get_slicec('/', 1);
|
||||
StringName value = p_value;
|
||||
bool properties_changed = false;
|
||||
bool prop_list_changed = false;
|
||||
if (value == StringName()) {
|
||||
if (parent_scope_mapping.has(mapped_var_name)) {
|
||||
properties_changed = true;
|
||||
prop_list_changed = true;
|
||||
parent_scope_mapping.erase(mapped_var_name);
|
||||
}
|
||||
} else {
|
||||
if (!parent_scope_mapping.has(mapped_var_name)) {
|
||||
properties_changed = true;
|
||||
prop_list_changed = true;
|
||||
}
|
||||
parent_scope_mapping[mapped_var_name] = value;
|
||||
}
|
||||
if (properties_changed) {
|
||||
if (prop_list_changed) {
|
||||
notify_property_list_changed();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// * Binding
|
||||
if (name_str.begins_with("binding/")) {
|
||||
StringName bound_var = name_str.get_slicec('/', 1);
|
||||
NodePath value = p_value;
|
||||
bool prop_list_changed = false;
|
||||
if (value.is_empty()) {
|
||||
if (property_bindings.has(bound_var)) {
|
||||
prop_list_changed = true;
|
||||
property_bindings.erase(bound_var);
|
||||
}
|
||||
} else {
|
||||
if (!property_bindings.has(bound_var)) {
|
||||
prop_list_changed = true;
|
||||
}
|
||||
property_bindings[bound_var] = value;
|
||||
}
|
||||
if (prop_list_changed) {
|
||||
notify_property_list_changed();
|
||||
}
|
||||
}
|
||||
|
||||
// * Storage
|
||||
if (name_str.begins_with("var/")) {
|
||||
StringName var_name = name_str.get_slicec('/', 1);
|
||||
|
@ -66,6 +99,8 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
|||
var_map[var_name].set_hint((PropertyHint)(int)p_value);
|
||||
} else if (what == "hint_string") {
|
||||
var_map[var_name].set_hint_string(p_value);
|
||||
} else if (what == "property_binding") {
|
||||
property_bindings[var_name] = NodePath(p_value);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -78,28 +113,64 @@ bool BlackboardPlan::_set(const StringName &p_name, const Variant &p_value) {
|
|||
bool BlackboardPlan::_get(const StringName &p_name, Variant &r_ret) const {
|
||||
String name_str = p_name;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// * Editor
|
||||
if (var_map.has(p_name)) {
|
||||
if (has_mapping(p_name)) {
|
||||
r_ret = "Mapped to " + LimboUtility::get_singleton()->decorate_var(parent_scope_mapping[p_name]);
|
||||
} else if (has_property_binding(p_name)) {
|
||||
const NodePath &binding = property_bindings[p_name];
|
||||
|
||||
Node *edited_node = Object::cast_to<Node>(EditorInterface::get_singleton()->get_inspector()->get_edited_object());
|
||||
if (!edited_node) {
|
||||
edited_node = SCENE_TREE()->get_edited_scene_root();
|
||||
}
|
||||
Node *bound_node = edited_node ? edited_node->get_node_or_null(binding) : nullptr;
|
||||
|
||||
String shortened_path;
|
||||
if (bound_node) {
|
||||
shortened_path = (String)bound_node->get_name() +
|
||||
":" + (String)binding.get_concatenated_subnames();
|
||||
} else {
|
||||
shortened_path = (String)binding.get_name(binding.get_name_count() - 1) +
|
||||
":" + (String)binding.get_concatenated_subnames();
|
||||
}
|
||||
r_ret = String::utf8("🔗 ") + shortened_path;
|
||||
} else {
|
||||
r_ret = var_map[p_name].get_value();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
// * Mapping
|
||||
if (name_str.begins_with("mapping/")) {
|
||||
StringName mapped_var_name = name_str.get_slicec('/', 1);
|
||||
ERR_FAIL_COND_V(mapped_var_name == StringName(), false);
|
||||
if (parent_scope_mapping.has(mapped_var_name)) {
|
||||
if (has_mapping(mapped_var_name)) {
|
||||
r_ret = parent_scope_mapping[mapped_var_name];
|
||||
} else if (has_property_binding(mapped_var_name)) {
|
||||
r_ret = RTR("Already bound to property.");
|
||||
} else {
|
||||
r_ret = StringName();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// * Binding
|
||||
if (name_str.begins_with("binding/")) {
|
||||
StringName bound_var = name_str.get_slicec('/', 1);
|
||||
ERR_FAIL_COND_V(bound_var == StringName(), false);
|
||||
if (has_property_binding(bound_var)) {
|
||||
r_ret = property_bindings[bound_var];
|
||||
} else if (has_mapping(bound_var)) {
|
||||
r_ret = RTR("Already mapped to variable.");
|
||||
} else {
|
||||
r_ret = NodePath();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// * Storage
|
||||
if (!name_str.begins_with("var/")) {
|
||||
return false;
|
||||
|
@ -127,14 +198,16 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
String var_name = p.first;
|
||||
BBVariable var = p.second;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
// * Editor
|
||||
if (var.get_type() != Variant::NIL && (!is_derived() || !var_name.begins_with("_"))) {
|
||||
if (has_mapping(var_name)) {
|
||||
if (!_is_var_nil(var) && !_is_var_private(var_name, var)) {
|
||||
if (has_mapping(var_name) || has_property_binding(var_name)) {
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, var_name, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
|
||||
} else {
|
||||
p_list->push_back(PropertyInfo(var.get_type(), var_name, var.get_hint(), var.get_hint_string(), PROPERTY_USAGE_EDITOR));
|
||||
}
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
// * Storage
|
||||
if (is_derived() && (!var.is_value_changed() || var.get_value() == base->var_map[var_name].get_value())) {
|
||||
|
@ -153,9 +226,32 @@ void BlackboardPlan::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
if (is_mapping_enabled()) {
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "Mapping", PROPERTY_HINT_NONE, "mapping/", PROPERTY_USAGE_GROUP));
|
||||
for (const Pair<StringName, BBVariable> &p : var_list) {
|
||||
// Serialize only non-empty mappings.
|
||||
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
|
||||
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
|
||||
if (_is_var_private(p.first, p.second)) {
|
||||
continue;
|
||||
}
|
||||
if (unlikely(has_property_binding(p.first))) {
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "mapping/" + p.first, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
|
||||
} else {
|
||||
// Serialize only non-empty mappings.
|
||||
PropertyUsageFlags usage = has_mapping(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
|
||||
p_list->push_back(PropertyInfo(Variant::STRING_NAME, "mapping/" + p.first, PROPERTY_HINT_NONE, "", usage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// * Binding
|
||||
p_list->push_back(PropertyInfo(Variant::NIL, "Binding", PROPERTY_HINT_NONE, "binding/", PROPERTY_USAGE_GROUP));
|
||||
for (const Pair<StringName, BBVariable> &p : var_list) {
|
||||
if (_is_var_nil(p.second) || _is_var_private(p.first, p.second)) {
|
||||
continue;
|
||||
}
|
||||
if (unlikely(has_mapping(p.first))) {
|
||||
p_list->push_back(PropertyInfo(Variant::STRING, "binding/" + p.first, PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY));
|
||||
} else {
|
||||
PropertyUsageFlags usage = has_property_binding(p.first) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_EDITOR;
|
||||
// PROPERTY_HINT_LINK is used to signal that NodePath should point to a property.
|
||||
// Our inspector plugin will know how to handle it.
|
||||
p_list->push_back(PropertyInfo(Variant::NODE_PATH, "binding/" + p.first, PROPERTY_HINT_LINK, itos(p.second.get_type()), usage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +295,11 @@ bool BlackboardPlan::has_mapping(const StringName &p_name) const {
|
|||
return is_mapping_enabled() && parent_scope_mapping.has(p_name) && parent_scope_mapping[p_name] != StringName();
|
||||
}
|
||||
|
||||
void BlackboardPlan::set_property_binding(const StringName &p_name, const NodePath &p_path) {
|
||||
property_bindings[p_name] = p_path;
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
void BlackboardPlan::set_prefetch_nodepath_vars(bool p_enable) {
|
||||
prefetch_nodepath_vars = p_enable;
|
||||
emit_changed();
|
||||
|
@ -387,33 +488,16 @@ void BlackboardPlan::sync_with_base_plan() {
|
|||
}
|
||||
}
|
||||
|
||||
// Add a variable duplicate to the blackboard, optionally with NodePath prefetch.
|
||||
inline void bb_add_var_dup_with_prefetch(const Ref<Blackboard> &p_blackboard, const StringName &p_name, const BBVariable &p_var, bool p_prefetch, Node *p_node) {
|
||||
if (unlikely(p_prefetch && p_var.get_type() == Variant::NODE_PATH)) {
|
||||
Node *n = p_node->get_node_or_null(p_var.get_value());
|
||||
BBVariable var = p_var.duplicate(true);
|
||||
if (n != nullptr) {
|
||||
var.set_value(n);
|
||||
} else {
|
||||
ERR_PRINT(vformat("BlackboardPlan: Prefetch failed for variable $%s with value: %s", p_name, p_var.get_value()));
|
||||
var.set_value(Variant());
|
||||
}
|
||||
p_blackboard->assign_var(p_name, var);
|
||||
} else {
|
||||
p_blackboard->assign_var(p_name, p_var.duplicate(true));
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_node, const Ref<Blackboard> &p_parent_scope) {
|
||||
ERR_FAIL_COND_V(p_node == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
|
||||
Ref<Blackboard> BlackboardPlan::create_blackboard(Node *p_prefetch_root, const Ref<Blackboard> &p_parent_scope, Node *p_prefetch_root_for_base_plan) {
|
||||
ERR_FAIL_COND_V(p_prefetch_root == nullptr && prefetch_nodepath_vars, memnew(Blackboard));
|
||||
Ref<Blackboard> bb = memnew(Blackboard);
|
||||
bb->set_parent(p_parent_scope);
|
||||
populate_blackboard(bb, true, p_node);
|
||||
populate_blackboard(bb, true, p_prefetch_root, p_prefetch_root_for_base_plan);
|
||||
return bb;
|
||||
}
|
||||
|
||||
void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node) {
|
||||
ERR_FAIL_COND(p_node == nullptr && prefetch_nodepath_vars);
|
||||
void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_prefetch_root, Node *p_prefetch_root_for_base_plan) {
|
||||
ERR_FAIL_COND(p_prefetch_root == nullptr && prefetch_nodepath_vars);
|
||||
ERR_FAIL_COND(p_blackboard.is_null());
|
||||
for (const Pair<StringName, BBVariable> &p : var_list) {
|
||||
if (p_blackboard->has_local_var(p.first) && !overwrite) {
|
||||
|
@ -427,15 +511,48 @@ void BlackboardPlan::populate_blackboard(const Ref<Blackboard> &p_blackboard, bo
|
|||
#endif
|
||||
continue;
|
||||
}
|
||||
bool is_bound = has_property_binding(p.first) || (is_derived() && get_base_plan()->has_property_binding(p.first));
|
||||
bool has_mapping = parent_scope_mapping.has(p.first);
|
||||
bool do_prefetch = !has_mapping && prefetch_nodepath_vars;
|
||||
bb_add_var_dup_with_prefetch(p_blackboard, p.first, p.second, do_prefetch, p_node);
|
||||
bool do_prefetch = !is_bound && !has_mapping && prefetch_nodepath_vars;
|
||||
|
||||
// Add a variable duplicate to the blackboard, optionally with NodePath prefetch.
|
||||
BBVariable var = p.second.duplicate(true);
|
||||
if (unlikely(do_prefetch && p.second.get_type() == Variant::NODE_PATH)) {
|
||||
Node *prefetch_root = !p_prefetch_root_for_base_plan || !is_derived() || is_derived_var_changed(p.first) ? p_prefetch_root : p_prefetch_root_for_base_plan;
|
||||
Node *n = prefetch_root->get_node_or_null(p.second.get_value());
|
||||
if (n != nullptr) {
|
||||
var.set_value(n);
|
||||
} else {
|
||||
ERR_PRINT(vformat("BlackboardPlan: Prefetch failed for variable $%s with value: %s", p.first, p.second.get_value()));
|
||||
var.set_value(Variant());
|
||||
}
|
||||
}
|
||||
p_blackboard->assign_var(p.first, var);
|
||||
|
||||
if (has_mapping) {
|
||||
StringName target_var = parent_scope_mapping[p.first];
|
||||
if (target_var != StringName()) {
|
||||
ERR_CONTINUE_MSG(p_blackboard->get_parent() == nullptr, vformat("BlackboardPlan: Cannot link variable %s to parent scope because the parent scope is not set.", LimboUtility::get_singleton()->decorate_var(p.first)));
|
||||
ERR_CONTINUE_MSG(p_blackboard->get_parent().is_null(), vformat("BlackboardPlan: Cannot link variable %s to parent scope because the parent scope is not set.", LimboUtility::get_singleton()->decorate_var(p.first)));
|
||||
p_blackboard->link_var(p.first, p_blackboard->get_parent(), target_var);
|
||||
}
|
||||
} else if (is_bound) {
|
||||
// Bind variable to a property of a scene node.
|
||||
NodePath binding_path;
|
||||
Node *binding_root;
|
||||
if (has_property_binding(p.first)) {
|
||||
binding_path = property_bindings[p.first];
|
||||
binding_root = p_prefetch_root;
|
||||
} else {
|
||||
binding_path = get_base_plan()->property_bindings[p.first];
|
||||
binding_root = p_prefetch_root_for_base_plan;
|
||||
}
|
||||
ERR_CONTINUE_MSG(binding_path.get_subname_count() != 1, vformat("BlackboardPlan: Can't bind variable %s using property path that contains multiple sub-names: %s", LimboUtility::get_singleton()->decorate_var(p.first), binding_path));
|
||||
NodePath node_path{ binding_path.get_concatenated_names() };
|
||||
StringName prop_name = binding_path.get_subname(0);
|
||||
// TODO: Implement binding for base plan as well.
|
||||
Node *n = binding_root->get_node_or_null(node_path);
|
||||
ERR_CONTINUE_MSG(n == nullptr, vformat("BlackboardPlan: Binding failed for variable %s using property path: %s", LimboUtility::get_singleton()->decorate_var(p.first), binding_path));
|
||||
var.bind(n, prop_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -450,8 +567,8 @@ void BlackboardPlan::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("sync_with_base_plan"), &BlackboardPlan::sync_with_base_plan);
|
||||
ClassDB::bind_method(D_METHOD("set_parent_scope_plan_provider", "callable"), &BlackboardPlan::set_parent_scope_plan_provider);
|
||||
ClassDB::bind_method(D_METHOD("get_parent_scope_plan_provider"), &BlackboardPlan::get_parent_scope_plan_provider);
|
||||
ClassDB::bind_method(D_METHOD("create_blackboard", "node", "parent_scope"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()));
|
||||
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "node"), &BlackboardPlan::populate_blackboard);
|
||||
ClassDB::bind_method(D_METHOD("create_blackboard", "prefetch_root", "parent_scope", "prefetch_root_for_base_plan"), &BlackboardPlan::create_blackboard, DEFVAL(Ref<Blackboard>()), DEFVAL(Variant()));
|
||||
ClassDB::bind_method(D_METHOD("populate_blackboard", "blackboard", "overwrite", "prefetch_root", "prefetch_root_for_base_plan"), &BlackboardPlan::populate_blackboard, DEFVAL(Variant()));
|
||||
|
||||
// To avoid cluttering the member namespace, we do not export unnecessary properties in this class.
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "prefetch_nodepath_vars", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "set_prefetch_nodepath_vars", "is_prefetching_nodepath_vars");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* blackboard_plan.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -34,18 +34,26 @@ private:
|
|||
// When base is not null, the plan is considered to be derived from the base plan.
|
||||
// A derived plan can only have variables that exist in the base plan,
|
||||
// and only the values can be different in those variables.
|
||||
// The derived plan is synced with the base plan to maintain consistency.
|
||||
Ref<BlackboardPlan> base;
|
||||
|
||||
// Mapping between variables in this plan and their parent scope names.
|
||||
// Used for linking variables to their parent scope counterparts upon Blackboard creation/population.
|
||||
HashMap<StringName, StringName> parent_scope_mapping;
|
||||
// Fetcher function for the parent scope plan. Funtion should return a Ref<BlackboardPlan>.
|
||||
// Used in the inspector. When set, mapping feature becomes available.
|
||||
// Fetcher function for the parent scope plan. Function should return a Ref<BlackboardPlan>.
|
||||
// Used in the inspector: enables mapping feature when set.
|
||||
Callable parent_scope_plan_provider;
|
||||
|
||||
// Bindings to properties in the scene to which this plan belongs.
|
||||
HashMap<StringName, NodePath> property_bindings;
|
||||
bool property_binding_enabled = false;
|
||||
|
||||
// If true, NodePath variables will be prefetched, so that the vars will contain node pointers instead (upon BB creation/population).
|
||||
bool prefetch_nodepath_vars = true;
|
||||
|
||||
_FORCE_INLINE_ bool _is_var_nil(const BBVariable &p_var) const { return p_var.get_type() == Variant::NIL; }
|
||||
_FORCE_INLINE_ bool _is_var_private(const String &p_name, const BBVariable &p_var) const { return is_derived() && p_name.begins_with("_"); }
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -69,6 +77,10 @@ public:
|
|||
bool is_mapping_enabled() const { return parent_scope_plan_provider.is_valid() && (parent_scope_plan_provider.call() != Ref<BlackboardPlan>()); }
|
||||
bool has_mapping(const StringName &p_name) const;
|
||||
|
||||
bool has_property_binding(const StringName &p_name) const { return property_bindings.has(p_name); }
|
||||
void set_property_binding(const StringName &p_name, const NodePath &p_path);
|
||||
NodePath get_property_binding(const StringName &p_name) const { return property_bindings.has(p_name) ? property_bindings[p_name] : NodePath(); }
|
||||
|
||||
void set_prefetch_nodepath_vars(bool p_enable);
|
||||
bool is_prefetching_nodepath_vars() const;
|
||||
|
||||
|
@ -88,9 +100,10 @@ public:
|
|||
|
||||
void sync_with_base_plan();
|
||||
_FORCE_INLINE_ bool is_derived() const { return base.is_valid(); }
|
||||
_FORCE_INLINE_ bool is_derived_var_changed(const StringName &p_name) const { return base.is_valid() && var_map.has(p_name) && var_map[p_name].is_value_changed(); }
|
||||
|
||||
Ref<Blackboard> create_blackboard(Node *p_agent, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>());
|
||||
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_node);
|
||||
Ref<Blackboard> create_blackboard(Node *p_prefetch_root, const Ref<Blackboard> &p_parent_scope = Ref<Blackboard>(), Node *p_prefetch_root_for_base_plan = nullptr);
|
||||
void populate_blackboard(const Ref<Blackboard> &p_blackboard, bool overwrite, Node *p_prefetch_root, Node *p_prefetch_root_for_base_plan = nullptr);
|
||||
|
||||
BlackboardPlan();
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* behavior_tree.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -78,10 +78,10 @@ void BehaviorTree::copy_other(const Ref<BehaviorTree> &p_other) {
|
|||
}
|
||||
|
||||
Ref<BTInstance> BehaviorTree::instantiate(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_instance_owner, Node *p_custom_scene_root) const {
|
||||
ERR_FAIL_COND_V_MSG(root_task == nullptr, nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
|
||||
ERR_FAIL_COND_V_MSG(root_task.is_null(), nullptr, "BehaviorTree: Instantiation failed - BT has no valid root task.");
|
||||
ERR_FAIL_NULL_V_MSG(p_agent, nullptr, "BehaviorTree: Instantiation failed - agent can't be null.");
|
||||
ERR_FAIL_NULL_V_MSG(p_instance_owner, nullptr, "BehaviorTree: Instantiation failed -- instance owner can't be null.");
|
||||
ERR_FAIL_NULL_V_MSG(p_blackboard, nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
|
||||
ERR_FAIL_COND_V_MSG(p_blackboard.is_null(), nullptr, "BehaviorTree: Instantiation failed - blackboard can't be null.");
|
||||
Node *scene_root = p_custom_scene_root ? p_custom_scene_root : p_instance_owner->get_owner();
|
||||
ERR_FAIL_NULL_V_MSG(scene_root, nullptr, "BehaviorTree: Instantiation failed - unable to establish scene root. This is likely due to the instance owner not being owned by a scene node and custom_scene_root being null.");
|
||||
Ref<BTTask> root_copy = root_task->clone();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* behavior_tree.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_instance.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -25,7 +25,7 @@
|
|||
#endif
|
||||
|
||||
Ref<BTInstance> BTInstance::create(Ref<BTTask> p_root_task, String p_source_bt_path, Node *p_owner_node) {
|
||||
ERR_FAIL_NULL_V(p_root_task, nullptr);
|
||||
ERR_FAIL_COND_V(p_root_task.is_null(), nullptr);
|
||||
ERR_FAIL_NULL_V(p_owner_node, nullptr);
|
||||
Ref<BTInstance> inst;
|
||||
inst.instantiate();
|
||||
|
@ -42,6 +42,7 @@ BT::Status BTInstance::update(double p_delta) {
|
|||
double start = Time::get_singleton()->get_ticks_usec();
|
||||
#endif
|
||||
|
||||
const Ref<BTInstance> keep_alive{ this }; // keep instance alive until update is finished
|
||||
last_status = root_task->execute(p_delta);
|
||||
emit_signal(LW_NAME(updated), last_status);
|
||||
|
||||
|
@ -82,7 +83,7 @@ void BTInstance::register_with_debugger() {
|
|||
|
||||
void BTInstance::unregister_with_debugger() {
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (LimboDebugger::get_singleton()->is_active()) {
|
||||
if (LimboDebugger::get_singleton() && LimboDebugger::get_singleton()->is_active()) {
|
||||
LimboDebugger::get_singleton()->unregister_bt_instance(get_instance_id());
|
||||
}
|
||||
#endif
|
||||
|
@ -102,7 +103,7 @@ double BTInstance::_get_mean_update_time_msec_and_reset() {
|
|||
|
||||
void BTInstance::_add_custom_monitor() {
|
||||
ERR_FAIL_NULL(get_owner_node());
|
||||
ERR_FAIL_NULL(root_task);
|
||||
ERR_FAIL_COND(root_task.is_null());
|
||||
ERR_FAIL_NULL(root_task->get_agent());
|
||||
|
||||
if (monitor_id == StringName()) {
|
||||
|
@ -150,5 +151,6 @@ BTInstance::~BTInstance() {
|
|||
emit_signal(LW_NAME(freed));
|
||||
#ifdef DEBUG_ENABLED
|
||||
_remove_custom_monitor();
|
||||
unregister_with_debugger();
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_instance.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_player.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -42,13 +42,13 @@
|
|||
|
||||
VARIANT_ENUM_CAST(BTPlayer::UpdateMode);
|
||||
|
||||
void BTPlayer::_load_tree() {
|
||||
void BTPlayer::_instantiate_bt() {
|
||||
bt_instance.unref();
|
||||
ERR_FAIL_COND_MSG(!behavior_tree.is_valid(), "BTPlayer: Initialization failed - needs a valid behavior tree.");
|
||||
ERR_FAIL_COND_MSG(!behavior_tree->get_root_task().is_valid(), "BTPlayer: Initialization failed - behavior tree has no valid root task.");
|
||||
Node *agent = GET_NODE(this, agent_node);
|
||||
ERR_FAIL_NULL_MSG(agent, vformat("BTPlayer: Initialization failed - can't get agent with path '%s'.", agent_node));
|
||||
Node *scene_root = scene_root_hint ? scene_root_hint : get_owner();
|
||||
Node *scene_root = _get_scene_root();
|
||||
ERR_FAIL_COND_MSG(scene_root == nullptr,
|
||||
"BTPlayer: Initialization failed - unable to establish scene root. This is likely due to BTPlayer not being owned by a scene node. Check BTPlayer.set_scene_root_hint().");
|
||||
bt_instance = behavior_tree->instantiate(agent, blackboard, this, scene_root);
|
||||
|
@ -70,6 +70,19 @@ void BTPlayer::_update_blackboard_plan() {
|
|||
blackboard_plan->set_base_plan(behavior_tree.is_valid() ? behavior_tree->get_blackboard_plan() : nullptr);
|
||||
}
|
||||
|
||||
void BTPlayer::_initialize() {
|
||||
if (blackboard.is_null()) {
|
||||
blackboard = Ref<Blackboard>(memnew(Blackboard));
|
||||
}
|
||||
if (blackboard_plan.is_valid()) {
|
||||
// Don't overwrite existing blackboard values as they may be initialized from code.
|
||||
blackboard_plan->populate_blackboard(blackboard, false, this, _get_scene_root());
|
||||
}
|
||||
if (behavior_tree.is_valid()) {
|
||||
_instantiate_bt();
|
||||
}
|
||||
}
|
||||
|
||||
void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
|
||||
ERR_FAIL_COND_MSG(p_bt_instance.is_null(), "BTPlayer: Failed to set behavior tree instance - instance is null.");
|
||||
ERR_FAIL_COND_MSG(!p_bt_instance->is_instance_valid(), "BTPlayer: Failed to set behavior tree instance - instance is not valid.");
|
||||
|
@ -78,6 +91,11 @@ void BTPlayer::set_bt_instance(const Ref<BTInstance> &p_bt_instance) {
|
|||
blackboard = p_bt_instance->get_blackboard();
|
||||
agent_node = p_bt_instance->get_agent()->get_path();
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
bt_instance->set_monitor_performance(monitor_performance);
|
||||
bt_instance->register_with_debugger();
|
||||
#endif // DEBUG_ENABLED
|
||||
|
||||
blackboard_plan.unref();
|
||||
behavior_tree.unref();
|
||||
}
|
||||
|
@ -104,7 +122,8 @@ void BTPlayer::set_behavior_tree(const Ref<BehaviorTree> &p_tree) {
|
|||
} else {
|
||||
behavior_tree = p_tree;
|
||||
if (get_owner() && is_inside_tree()) {
|
||||
_load_tree();
|
||||
_update_blackboard_plan();
|
||||
_initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,16 +198,7 @@ void BTPlayer::_notification(int p_notification) {
|
|||
} break;
|
||||
case NOTIFICATION_READY: {
|
||||
if (!Engine::get_singleton()->is_editor_hint()) {
|
||||
if (blackboard.is_null()) {
|
||||
blackboard = Ref<Blackboard>(memnew(Blackboard));
|
||||
}
|
||||
if (blackboard_plan.is_valid()) {
|
||||
// Don't overwrite existing blackboard values as they may be initialized from code.
|
||||
blackboard_plan->populate_blackboard(blackboard, false, this);
|
||||
}
|
||||
if (behavior_tree.is_valid()) {
|
||||
_load_tree();
|
||||
}
|
||||
_initialize();
|
||||
} else {
|
||||
_update_blackboard_plan();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_player.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -48,8 +48,10 @@ private:
|
|||
|
||||
Ref<BTInstance> bt_instance;
|
||||
|
||||
void _load_tree();
|
||||
void _instantiate_bt();
|
||||
void _update_blackboard_plan();
|
||||
void _initialize();
|
||||
_FORCE_INLINE_ Node *_get_scene_root() const { return scene_root_hint ? scene_root_hint : get_owner(); }
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_state.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -65,10 +65,14 @@ void BTState::_update_blackboard_plan() {
|
|||
}
|
||||
}
|
||||
|
||||
Node *BTState::_get_prefetch_root_for_base_plan() {
|
||||
return _get_scene_root();
|
||||
}
|
||||
|
||||
void BTState::_setup() {
|
||||
LimboState::_setup();
|
||||
ERR_FAIL_COND_MSG(behavior_tree.is_null(), "BTState: BehaviorTree is not assigned.");
|
||||
Node *scene_root = scene_root_hint ? scene_root_hint : get_owner();
|
||||
Node *scene_root = _get_scene_root();
|
||||
ERR_FAIL_NULL_MSG(scene_root, "BTState: Initialization failed - unable to establish scene root. This is likely due to BTState not being owned by a scene node. Check BTState.set_scene_root_hint().");
|
||||
bt_instance = behavior_tree->instantiate(get_agent(), get_blackboard(), this, scene_root);
|
||||
ERR_FAIL_COND_MSG(bt_instance.is_null(), "BTState: Initialization failed - failed to instantiate behavior tree.");
|
||||
|
@ -94,7 +98,7 @@ void BTState::_update(double p_delta) {
|
|||
// Bail out if a transition happened in the meantime.
|
||||
return;
|
||||
}
|
||||
ERR_FAIL_NULL(bt_instance);
|
||||
ERR_FAIL_COND(bt_instance.is_null());
|
||||
BT::Status status = bt_instance->update(p_delta);
|
||||
if (status == BTTask::SUCCESS) {
|
||||
get_root()->dispatch(success_event, Variant());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_state.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -28,6 +28,8 @@ private:
|
|||
Node *scene_root_hint = nullptr;
|
||||
bool monitor_performance = false;
|
||||
|
||||
_FORCE_INLINE_ Node *_get_scene_root() const { return scene_root_hint ? scene_root_hint : get_owner(); }
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -35,6 +37,7 @@ protected:
|
|||
|
||||
virtual bool _should_use_new_scope() const override { return true; }
|
||||
virtual void _update_blackboard_plan() override;
|
||||
virtual Node *_get_prefetch_root_for_base_plan() override;
|
||||
|
||||
virtual void _setup() override;
|
||||
virtual void _exit() override;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_check_trigger.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_check_trigger.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_check_var.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_check_var.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_set_var.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_set_var.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_action.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_action.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_comment.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -30,7 +30,7 @@ PackedStringArray BTComment::get_configuration_warnings() {
|
|||
if (get_child_count_excluding_comments() > 0) {
|
||||
warnings.append("Can only have other comment tasks as children.");
|
||||
}
|
||||
if (get_parent() == nullptr) {
|
||||
if (get_parent().is_null()) {
|
||||
warnings.append("Can't be the root task.");
|
||||
}
|
||||
return warnings;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_comment.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_composite.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_composite.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_condition.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_condition.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_decorator.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_decorator.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_task.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
@ -163,7 +163,7 @@ void BTTask::set_custom_name(const String &p_name) {
|
|||
|
||||
void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node *p_scene_root) {
|
||||
ERR_FAIL_NULL(p_agent);
|
||||
ERR_FAIL_NULL(p_blackboard);
|
||||
ERR_FAIL_COND(p_blackboard.is_null());
|
||||
ERR_FAIL_NULL(p_scene_root);
|
||||
data.agent = p_agent;
|
||||
data.blackboard = p_blackboard;
|
||||
|
@ -172,9 +172,8 @@ void BTTask::initialize(Node *p_agent, const Ref<Blackboard> &p_blackboard, Node
|
|||
get_child(i)->initialize(p_agent, p_blackboard, p_scene_root);
|
||||
}
|
||||
|
||||
if (!GDVIRTUAL_CALL(_setup)) {
|
||||
_setup();
|
||||
}
|
||||
_setup();
|
||||
GDVIRTUAL_CALL(_setup);
|
||||
}
|
||||
|
||||
Ref<BTTask> BTTask::clone() const {
|
||||
|
@ -182,60 +181,47 @@ Ref<BTTask> BTTask::clone() const {
|
|||
|
||||
// * Children are duplicated via children property. See _set_children().
|
||||
|
||||
// * Make BBParam properties unique.
|
||||
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
|
||||
#ifdef LIMBOAI_MODULE
|
||||
// Make BBParam properties unique.
|
||||
List<PropertyInfo> props;
|
||||
inst->get_property_list(&props);
|
||||
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
|
||||
for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
|
||||
if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Variant v = inst->get(E->get().name);
|
||||
|
||||
if (v.is_ref_counted()) {
|
||||
Ref<RefCounted> ref = v;
|
||||
if (ref.is_valid()) {
|
||||
Ref<Resource> res = ref;
|
||||
if (res.is_valid() && res->is_class("BBParam")) {
|
||||
if (!duplicates.has(res)) {
|
||||
duplicates[res] = res->duplicate();
|
||||
}
|
||||
res = duplicates[res];
|
||||
inst->set(E->get().name, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PropertyInfo prop = E->get();
|
||||
#elif LIMBOAI_GDEXTENSION
|
||||
// Make BBParam properties unique.
|
||||
TypedArray<Dictionary> props = inst->get_property_list();
|
||||
HashMap<Ref<Resource>, Ref<Resource>> duplicates;
|
||||
for (int i = 0; i < props.size(); i++) {
|
||||
Dictionary prop = props[i];
|
||||
if (!(int(prop["usage"]) & PROPERTY_USAGE_STORAGE)) {
|
||||
PropertyInfo prop = PropertyInfo::from_dict(props[i]);
|
||||
#endif
|
||||
if (!(prop.usage & PROPERTY_USAGE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StringName prop_name = prop["name"];
|
||||
Variant v = inst->get(prop_name);
|
||||
|
||||
if (v.get_type() == Variant::OBJECT && int(prop["hint"]) == PROPERTY_HINT_RESOURCE_TYPE) {
|
||||
Ref<RefCounted> ref = v;
|
||||
if (ref.is_valid()) {
|
||||
Ref<Resource> res = ref;
|
||||
if (res.is_valid() && res->is_class("BBParam")) {
|
||||
if (!duplicates.has(res)) {
|
||||
duplicates[res] = res->duplicate();
|
||||
Variant prop_value = inst->get(prop.name);
|
||||
Ref<Resource> res = prop_value;
|
||||
if (res.is_valid() && res->is_class("BBParam")) {
|
||||
// Duplicate BBParam
|
||||
if (!duplicates.has(res)) {
|
||||
duplicates[res] = res->duplicate();
|
||||
}
|
||||
res = duplicates[res];
|
||||
inst->set(prop.name, res);
|
||||
} else if (prop_value.get_type() == Variant::ARRAY) {
|
||||
// Duplicate BBParams instances inside an array.
|
||||
// - This code doesn't handle arrays of arrays.
|
||||
// - A partial workaround for: https://github.com/godotengine/godot/issues/74918
|
||||
// - We actually don't want to duplicate resources in clone() except for BBParam subtypes.
|
||||
Array arr = prop_value;
|
||||
if (arr.is_typed() && ClassDB::is_parent_class(arr.get_typed_class_name(), LW_NAME(BBParam))) {
|
||||
for (int j = 0; j < arr.size(); j++) {
|
||||
Ref<Resource> bb_param = arr[j];
|
||||
if (bb_param.is_valid()) {
|
||||
arr[j] = bb_param->duplicate();
|
||||
}
|
||||
res = duplicates[res];
|
||||
inst->set(prop_name, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // LIMBOAI_MODULE & LIMBOAI_GDEXTENSION
|
||||
|
||||
return inst;
|
||||
}
|
||||
|
@ -248,9 +234,9 @@ BT::Status BTTask::execute(double p_delta) {
|
|||
data.children.get(i)->abort();
|
||||
}
|
||||
}
|
||||
if (!GDVIRTUAL_CALL(_enter)) {
|
||||
_enter();
|
||||
}
|
||||
// First native, then script.
|
||||
_enter();
|
||||
GDVIRTUAL_CALL(_enter);
|
||||
} else {
|
||||
data.elapsed += p_delta;
|
||||
}
|
||||
|
@ -260,9 +246,9 @@ BT::Status BTTask::execute(double p_delta) {
|
|||
}
|
||||
|
||||
if (data.status != RUNNING) {
|
||||
if (!GDVIRTUAL_CALL(_exit)) {
|
||||
_exit();
|
||||
}
|
||||
// First script, then native.
|
||||
GDVIRTUAL_CALL(_exit);
|
||||
_exit();
|
||||
data.elapsed = 0.0;
|
||||
}
|
||||
return data.status;
|
||||
|
@ -273,9 +259,9 @@ void BTTask::abort() {
|
|||
get_child(i)->abort();
|
||||
}
|
||||
if (data.status == RUNNING) {
|
||||
if (!GDVIRTUAL_CALL(_exit)) {
|
||||
_exit();
|
||||
}
|
||||
// First script, then native.
|
||||
GDVIRTUAL_CALL(_exit);
|
||||
_exit();
|
||||
}
|
||||
data.status = FRESH;
|
||||
data.elapsed = 0.0;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_task.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_dynamic_selector.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_dynamic_selector.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_dynamic_sequence.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_dynamic_sequence.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_parallel.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_parallel.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_probability_selector.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_probability_selector.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_random_selector.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_random_selector.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_random_sequence.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_random_sequence.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_selector.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_selector.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_sequence.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_sequence.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_always_fail.cpp
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* bt_always_fail.h
|
||||
* =============================================================================
|
||||
* Copyright 2021-2024 Serhii Snitsaruk
|
||||
* Copyright (c) 2023-present Serhii Snitsaruk and the LimboAI contributors.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style
|
||||
* license that can be found in the LICENSE file or at
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue