diff --git a/addons/beehave/blackboard.gd b/addons/beehave/blackboard.gd new file mode 100644 index 0000000..4cff1ce --- /dev/null +++ b/addons/beehave/blackboard.gd @@ -0,0 +1,24 @@ +extends Reference + +var blackboard = {} + +func set(key, value, blackboard_name = 'default'): + if not blackboard.has(blackboard_name): + blackboard[blackboard_name] = {} + + blackboard[blackboard_name][key] = value + + +func get(key, default_value = null, blackboard_name = 'default'): + if has(key, blackboard_name): + return blackboard[blackboard_name].get(key, default_value) + return default_value + + +func has(key, blackboard_name = 'default'): + return blackboard.has(blackboard_name) and blackboard[blackboard_name].has(key) and blackboard[blackboard_name][key] != null + + +func erase(key, blackboard_name = 'default'): + if blackboard.has(blackboard_name): + blackboard[blackboard_name][key] = null diff --git a/addons/beehave/icons/action.svg b/addons/beehave/icons/action.svg new file mode 100644 index 0000000..7c224d5 --- /dev/null +++ b/addons/beehave/icons/action.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/action.svg.import b/addons/beehave/icons/action.svg.import new file mode 100644 index 0000000..ee085b3 --- /dev/null +++ b/addons/beehave/icons/action.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/action.svg-e8a91246d0ba9ba3cf84290d65648f06.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/action.svg" +dest_files=[ "res://.import/action.svg-e8a91246d0ba9ba3cf84290d65648f06.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/blackboard.svg b/addons/beehave/icons/blackboard.svg new file mode 100644 index 0000000..af009c6 --- /dev/null +++ b/addons/beehave/icons/blackboard.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/blackboard.svg.import b/addons/beehave/icons/blackboard.svg.import new file mode 100644 index 0000000..fd5d540 --- /dev/null +++ b/addons/beehave/icons/blackboard.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/blackboard.svg-18d4dfd4f6de558de250b67251ff1e69.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/blackboard.svg" +dest_files=[ "res://.import/blackboard.svg-18d4dfd4f6de558de250b67251ff1e69.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/category_bt.svg b/addons/beehave/icons/category_bt.svg new file mode 100644 index 0000000..ab92d03 --- /dev/null +++ b/addons/beehave/icons/category_bt.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/category_bt.svg.import b/addons/beehave/icons/category_bt.svg.import new file mode 100644 index 0000000..f8400a5 --- /dev/null +++ b/addons/beehave/icons/category_bt.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/category_bt.svg-8537bebd1c5f62dca3d7ee7f17efeed4.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/category_bt.svg" +dest_files=[ "res://.import/category_bt.svg-8537bebd1c5f62dca3d7ee7f17efeed4.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/category_composite.svg b/addons/beehave/icons/category_composite.svg new file mode 100644 index 0000000..0f157de --- /dev/null +++ b/addons/beehave/icons/category_composite.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/category_composite.svg.import b/addons/beehave/icons/category_composite.svg.import new file mode 100644 index 0000000..75f2a39 --- /dev/null +++ b/addons/beehave/icons/category_composite.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/category_composite.svg-43f66e63a7ccfa5ac8ec6da0583b3246.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/category_composite.svg" +dest_files=[ "res://.import/category_composite.svg-43f66e63a7ccfa5ac8ec6da0583b3246.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/category_decorator.svg b/addons/beehave/icons/category_decorator.svg new file mode 100644 index 0000000..02c0375 --- /dev/null +++ b/addons/beehave/icons/category_decorator.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/category_decorator.svg.import b/addons/beehave/icons/category_decorator.svg.import new file mode 100644 index 0000000..b4687fd --- /dev/null +++ b/addons/beehave/icons/category_decorator.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/category_decorator.svg-79d598d6456f32724156248e09d6eaf3.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/category_decorator.svg" +dest_files=[ "res://.import/category_decorator.svg-79d598d6456f32724156248e09d6eaf3.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/condition.svg b/addons/beehave/icons/condition.svg new file mode 100644 index 0000000..5d7bbb0 --- /dev/null +++ b/addons/beehave/icons/condition.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/condition.svg.import b/addons/beehave/icons/condition.svg.import new file mode 100644 index 0000000..9e499d7 --- /dev/null +++ b/addons/beehave/icons/condition.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/condition.svg-57892684b10a64086f68c09c388b17e5.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/condition.svg" +dest_files=[ "res://.import/condition.svg-57892684b10a64086f68c09c388b17e5.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/fail.svg b/addons/beehave/icons/fail.svg new file mode 100644 index 0000000..d96bb98 --- /dev/null +++ b/addons/beehave/icons/fail.svg @@ -0,0 +1,66 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/fail.svg.import b/addons/beehave/icons/fail.svg.import new file mode 100644 index 0000000..103fcc3 --- /dev/null +++ b/addons/beehave/icons/fail.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/fail.svg-85247bd8065819a11b971d222d3d43bb.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/fail.svg" +dest_files=[ "res://.import/fail.svg-85247bd8065819a11b971d222d3d43bb.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/inverter.svg b/addons/beehave/icons/inverter.svg new file mode 100644 index 0000000..45b8e97 --- /dev/null +++ b/addons/beehave/icons/inverter.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/inverter.svg.import b/addons/beehave/icons/inverter.svg.import new file mode 100644 index 0000000..a3b53d7 --- /dev/null +++ b/addons/beehave/icons/inverter.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/inverter.svg-1f1b976d95de42c4ad99a92fa9a6c5d0.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/inverter.svg" +dest_files=[ "res://.import/inverter.svg-1f1b976d95de42c4ad99a92fa9a6c5d0.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/limiter.svg b/addons/beehave/icons/limiter.svg new file mode 100644 index 0000000..2d6bbb6 --- /dev/null +++ b/addons/beehave/icons/limiter.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/limiter.svg.import b/addons/beehave/icons/limiter.svg.import new file mode 100644 index 0000000..8a02cf0 --- /dev/null +++ b/addons/beehave/icons/limiter.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/limiter.svg-b4c7646605c46f53c5e403fe21d8f584.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/limiter.svg" +dest_files=[ "res://.import/limiter.svg-b4c7646605c46f53c5e403fe21d8f584.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/selector.svg b/addons/beehave/icons/selector.svg new file mode 100644 index 0000000..01b107a --- /dev/null +++ b/addons/beehave/icons/selector.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/selector.svg.import b/addons/beehave/icons/selector.svg.import new file mode 100644 index 0000000..05bed9c --- /dev/null +++ b/addons/beehave/icons/selector.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/selector.svg-78bccfc448bd1676b5a29bfde4b08e5b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/selector.svg" +dest_files=[ "res://.import/selector.svg-78bccfc448bd1676b5a29bfde4b08e5b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/selector_star.svg b/addons/beehave/icons/selector_star.svg new file mode 100644 index 0000000..e112337 --- /dev/null +++ b/addons/beehave/icons/selector_star.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/addons/beehave/icons/selector_star.svg.import b/addons/beehave/icons/selector_star.svg.import new file mode 100644 index 0000000..2b6ac98 --- /dev/null +++ b/addons/beehave/icons/selector_star.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/selector_star.svg-368af7abfb9842c3f4258786871d1f03.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/selector_star.svg" +dest_files=[ "res://.import/selector_star.svg-368af7abfb9842c3f4258786871d1f03.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/addons/beehave/icons/sequencer.svg b/addons/beehave/icons/sequencer.svg new file mode 100644 index 0000000..1304ab0 --- /dev/null +++ b/addons/beehave/icons/sequencer.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/sequencer.svg.import b/addons/beehave/icons/sequencer.svg.import new file mode 100644 index 0000000..c4358f4 --- /dev/null +++ b/addons/beehave/icons/sequencer.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/sequencer.svg-a7b0e1cc6b00c0067836f9a81d0b2f9b.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/sequencer.svg" +dest_files=[ "res://.import/sequencer.svg-a7b0e1cc6b00c0067836f9a81d0b2f9b.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/sequencer_star.svg b/addons/beehave/icons/sequencer_star.svg new file mode 100644 index 0000000..66efd5c --- /dev/null +++ b/addons/beehave/icons/sequencer_star.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/addons/beehave/icons/sequencer_star.svg.import b/addons/beehave/icons/sequencer_star.svg.import new file mode 100644 index 0000000..6bfbf77 --- /dev/null +++ b/addons/beehave/icons/sequencer_star.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/sequencer_star.svg-2385cbba0c38b4d4ec43e0996f8a3493.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/sequencer_star.svg" +dest_files=[ "res://.import/sequencer_star.svg-2385cbba0c38b4d4ec43e0996f8a3493.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=false +svg/scale=1.0 diff --git a/addons/beehave/icons/succeed.svg b/addons/beehave/icons/succeed.svg new file mode 100644 index 0000000..d8c5133 --- /dev/null +++ b/addons/beehave/icons/succeed.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/succeed.svg.import b/addons/beehave/icons/succeed.svg.import new file mode 100644 index 0000000..0b98563 --- /dev/null +++ b/addons/beehave/icons/succeed.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/succeed.svg-c70f0a6f3d9b2864e4771942f0762307.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/succeed.svg" +dest_files=[ "res://.import/succeed.svg-c70f0a6f3d9b2864e4771942f0762307.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/icons/tree.svg b/addons/beehave/icons/tree.svg new file mode 100644 index 0000000..26dac9f --- /dev/null +++ b/addons/beehave/icons/tree.svg @@ -0,0 +1,61 @@ + + + + + + image/svg+xml + + + + + + + + + + diff --git a/addons/beehave/icons/tree.svg.import b/addons/beehave/icons/tree.svg.import new file mode 100644 index 0000000..028a5a1 --- /dev/null +++ b/addons/beehave/icons/tree.svg.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/tree.svg-c0b20ed88b2fe300c0296f7236049076.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://addons/beehave/icons/tree.svg" +dest_files=[ "res://.import/tree.svg-c0b20ed88b2fe300c0296f7236049076.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/addons/beehave/nodes/beehave_node.gd b/addons/beehave/nodes/beehave_node.gd new file mode 100644 index 0000000..d52e67b --- /dev/null +++ b/addons/beehave/nodes/beehave_node.gd @@ -0,0 +1,8 @@ +extends BeehaveTree + +class_name BeehaveNode, "../icons/action.svg" + +enum { SUCCESS, FAILURE, RUNNING } + +func tick(actor, blackboard): + pass diff --git a/addons/beehave/nodes/beehave_root.gd b/addons/beehave/nodes/beehave_root.gd new file mode 100644 index 0000000..5201cc7 --- /dev/null +++ b/addons/beehave/nodes/beehave_root.gd @@ -0,0 +1,84 @@ +extends BeehaveTree + +class_name BeehaveRoot, "../icons/tree.svg" + +const Blackboard = preload("../blackboard.gd") +const SUCCESS = 0 +const FAILURE = 1 +const RUNNING = 2 + +enum ProcessMode { + PHYSICS_PROCESS, + IDLE, + MANUAL +} + +export (ProcessMode) var process_mode = ProcessMode.PHYSICS_PROCESS setget set_process_mode +export (bool) var enabled = true + +export (NodePath) var actor_node_path + +var actor : Node + +onready var blackboard = Blackboard.new() + +func _ready(): + if self.get_child_count() != 1: + push_error("Beehave error: Root %s should have one child (NodePath: %s)" % [self.name, self.get_path()]) + disable() + return + + actor = get_parent() + if actor_node_path: + actor = get_node(actor_node_path) + + set_process_mode(self.process_mode) + +func _process(delta): + tick(delta) + +func _physics_process(delta): + tick(delta) + +func tick(delta): + blackboard.set("delta", delta) + + var status = self.get_child(0).tick(actor, blackboard) + + if status != RUNNING: + blackboard.set("running_action", null) + +func get_running_action(): + if blackboard.has("running_action"): + return blackboard.get("running_action") + return null + +func get_last_condition(): + if blackboard.has("last_condition"): + return blackboard.get("last_condition") + return null + +func get_last_condition_status(): + if blackboard.has("last_condition_status"): + var status = blackboard.get("last_condition_status") + if status == SUCCESS: + return "SUCCESS" + elif status == FAILURE: + return "FAILURE" + else: + return "RUNNING" + return "" + +func enable(): + self.enabled = true + set_process_mode(self.process_mode) + +func disable(): + self.enabled = false + set_process(self.enabled) + set_physics_process(self.enabled) + +func set_process_mode(value): + process_mode = value + set_process(process_mode == ProcessMode.IDLE) + set_physics_process(process_mode == ProcessMode.PHYSICS_PROCESS) diff --git a/addons/beehave/nodes/beehave_tree.gd b/addons/beehave/nodes/beehave_tree.gd new file mode 100644 index 0000000..9def663 --- /dev/null +++ b/addons/beehave/nodes/beehave_tree.gd @@ -0,0 +1,3 @@ +extends Node + +class_name BeehaveTree diff --git a/addons/beehave/nodes/composites/composite.gd b/addons/beehave/nodes/composites/composite.gd new file mode 100644 index 0000000..5a691f9 --- /dev/null +++ b/addons/beehave/nodes/composites/composite.gd @@ -0,0 +1,8 @@ +extends BeehaveNode + +class_name Composite, "../../icons/category_composite.svg" + + +func _ready(): + if self.get_child_count() < 1: + push_error("BehaviorTree Error: Composite %s should have at least one child (NodePath: %s)" % [self.name, self.get_path()]) diff --git a/addons/beehave/nodes/composites/selector.gd b/addons/beehave/nodes/composites/selector.gd new file mode 100644 index 0000000..f78be66 --- /dev/null +++ b/addons/beehave/nodes/composites/selector.gd @@ -0,0 +1,18 @@ +extends Composite + +class_name SelectorComposite, "../../icons/selector.svg" + +func tick(actor, blackboard): + for c in get_children(): + var response = c.tick(actor, blackboard) + + if c is ConditionLeaf: + blackboard.set("last_condition", c) + blackboard.set("last_condition_status", response) + + if response != FAILURE: + if c is ActionLeaf and response == RUNNING: + blackboard.set("running_action", c) + return response + + return FAILURE diff --git a/addons/beehave/nodes/composites/selector_star.gd b/addons/beehave/nodes/composites/selector_star.gd new file mode 100644 index 0000000..0a272b5 --- /dev/null +++ b/addons/beehave/nodes/composites/selector_star.gd @@ -0,0 +1,33 @@ +# Special implementation of a selector that will +# "wait" for running nodes and will not re-attempt +# to execute previous nodes until that node is either +# FAILED or SUCCEEDED +extends Composite + +class_name SelectorStarComposite, "../../icons/selector_star.svg" + + +var last_execution_index = 0 + +func tick(actor, blackboard): + for c in get_children(): + if c.get_index() < last_execution_index: + continue + + var response = c.tick(actor, blackboard) + + if c is ConditionLeaf: + blackboard.set("last_condition", c) + blackboard.set("last_condition_status", response) + + if response != FAILURE: + if c is ActionLeaf and response == RUNNING: + blackboard.set("running_action", c) + if response == SUCCESS: + last_execution_index = 0 + return response + else: + last_execution_index += 1 + + last_execution_index = 0 + return FAILURE diff --git a/addons/beehave/nodes/composites/sequence.gd b/addons/beehave/nodes/composites/sequence.gd new file mode 100644 index 0000000..52d401d --- /dev/null +++ b/addons/beehave/nodes/composites/sequence.gd @@ -0,0 +1,18 @@ +extends Composite + +class_name SequenceComposite, "../../icons/sequencer.svg" + +func tick(actor, blackboard): + for c in get_children(): + var response = c.tick(actor, blackboard) + + if c is ConditionLeaf: + blackboard.set("last_condition", c) + blackboard.set("last_condition_status", response) + + if response != SUCCESS: + if c is ActionLeaf and response == RUNNING: + blackboard.set("running_action", c) + return response + + return SUCCESS diff --git a/addons/beehave/nodes/composites/sequence_star.gd b/addons/beehave/nodes/composites/sequence_star.gd new file mode 100644 index 0000000..f0ae03f --- /dev/null +++ b/addons/beehave/nodes/composites/sequence_star.gd @@ -0,0 +1,35 @@ +# Special implementation of sequencer who will execute +# successful nodes only once until all nodes were successful + +extends Composite + +class_name SequenceStarComposite, "../../icons/sequencer_star.svg" + +var successful_index = 0 + +func tick(actor, blackboard): + for c in get_children(): + if c.get_index() < successful_index: + continue + + var response = c.tick(actor, blackboard) + + if c is ConditionLeaf: + blackboard.set("last_condition", c) + blackboard.set("last_condition_status", response) + + if response != SUCCESS: + if response == FAILURE: + successful_index = 0 + if c is ActionLeaf and response == RUNNING: + blackboard.set("running_action", c) + return response + else: + successful_index += 1 + + if successful_index == get_child_count(): + successful_index = 0 + return SUCCESS + else: + successful_index = 0 + return FAILURE diff --git a/addons/beehave/nodes/decorators/decorator.gd b/addons/beehave/nodes/decorators/decorator.gd new file mode 100644 index 0000000..b0568d5 --- /dev/null +++ b/addons/beehave/nodes/decorators/decorator.gd @@ -0,0 +1,8 @@ +extends BeehaveNode + +class_name Decorator, "../../icons/category_decorator.svg" + + +func _ready(): + if self.get_child_count() != 1: + push_error("Beehave Error: Decorator %s should have only one child (NodePath: %s)" % [self.name, self.get_path()]) diff --git a/addons/beehave/nodes/decorators/failer.gd b/addons/beehave/nodes/decorators/failer.gd new file mode 100644 index 0000000..15dfef4 --- /dev/null +++ b/addons/beehave/nodes/decorators/failer.gd @@ -0,0 +1,11 @@ +extends Decorator + +class_name AlwaysFailDecorator, "../../icons/fail.svg" + + +func tick(action, blackboard): + for c in get_children(): + var response = c.tick(action, blackboard) + if response == RUNNING: + return RUNNING + return FAILURE diff --git a/addons/beehave/nodes/decorators/inverter.gd b/addons/beehave/nodes/decorators/inverter.gd new file mode 100644 index 0000000..e1e70ea --- /dev/null +++ b/addons/beehave/nodes/decorators/inverter.gd @@ -0,0 +1,17 @@ +extends Decorator + +class_name InverterDecorator, "../../icons/inverter.svg" + + +func tick(action, blackboard): + for c in get_children(): + var response = c.tick(action, blackboard) + + if response == SUCCESS: + return FAILURE + if response == FAILURE: + return SUCCESS + + if c is Leaf and response == RUNNING: + blackboard.set("running_action", c) + return RUNNING diff --git a/addons/beehave/nodes/decorators/limiter.gd b/addons/beehave/nodes/decorators/limiter.gd new file mode 100644 index 0000000..725f784 --- /dev/null +++ b/addons/beehave/nodes/decorators/limiter.gd @@ -0,0 +1,19 @@ +extends Decorator + +class_name LimiterDecorator, "../../icons/limiter.svg" + +onready var cache_key = 'limiter_%s' % self.get_instance_id() + +export (float) var max_count = 0 + +func tick(actor, blackboard): + var current_count = blackboard.get(cache_key) + + if current_count == null: + current_count = 0 + + if current_count <= max_count: + blackboard.set(cache_key, current_count + 1) + return self.get_child(0).tick(actor, blackboard) + else: + return FAILED diff --git a/addons/beehave/nodes/decorators/succeeder.gd b/addons/beehave/nodes/decorators/succeeder.gd new file mode 100644 index 0000000..1a7bacf --- /dev/null +++ b/addons/beehave/nodes/decorators/succeeder.gd @@ -0,0 +1,11 @@ +extends Decorator + +class_name AlwaysSucceedDecorator, "../../icons/succeed.svg" + + +func tick(action, blackboard): + for c in get_children(): + var response = c.tick(action, blackboard) + if response == RUNNING: + return RUNNING + return SUCCESS diff --git a/addons/beehave/nodes/leaves/action.gd b/addons/beehave/nodes/leaves/action.gd new file mode 100644 index 0000000..a30041d --- /dev/null +++ b/addons/beehave/nodes/leaves/action.gd @@ -0,0 +1,3 @@ +extends Leaf + +class_name ActionLeaf, "../../icons/action.svg" diff --git a/addons/beehave/nodes/leaves/condition.gd b/addons/beehave/nodes/leaves/condition.gd new file mode 100644 index 0000000..d91ff37 --- /dev/null +++ b/addons/beehave/nodes/leaves/condition.gd @@ -0,0 +1,3 @@ +extends Leaf + +class_name ConditionLeaf, "../../icons/condition.svg" diff --git a/addons/beehave/nodes/leaves/leaf.gd b/addons/beehave/nodes/leaves/leaf.gd new file mode 100644 index 0000000..503fa1b --- /dev/null +++ b/addons/beehave/nodes/leaves/leaf.gd @@ -0,0 +1,3 @@ +extends BeehaveNode + +class_name Leaf, "../../icons/action.svg" diff --git a/addons/beehave/plugin.cfg b/addons/beehave/plugin.cfg new file mode 100644 index 0000000..7a1b19b --- /dev/null +++ b/addons/beehave/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="Beehave" +description="🐝 Behaviour Tree addon for Godot Engine" +author="bitbrain" +version="1.2.0" +script="plugin.gd" diff --git a/addons/beehave/plugin.gd b/addons/beehave/plugin.gd new file mode 100644 index 0000000..d670e1b --- /dev/null +++ b/addons/beehave/plugin.gd @@ -0,0 +1,5 @@ +tool +extends EditorPlugin + +func _init(): + print("Beehave initialized!") diff --git a/project.godot b/project.godot index 9db388f..207342a 100644 --- a/project.godot +++ b/project.godot @@ -8,6 +8,106 @@ config_version=4 +_global_script_classes=[ { +"base": "Leaf", +"class": "ActionLeaf", +"language": "GDScript", +"path": "res://addons/beehave/nodes/leaves/action.gd" +}, { +"base": "Decorator", +"class": "AlwaysFailDecorator", +"language": "GDScript", +"path": "res://addons/beehave/nodes/decorators/failer.gd" +}, { +"base": "Decorator", +"class": "AlwaysSucceedDecorator", +"language": "GDScript", +"path": "res://addons/beehave/nodes/decorators/succeeder.gd" +}, { +"base": "BeehaveTree", +"class": "BeehaveNode", +"language": "GDScript", +"path": "res://addons/beehave/nodes/beehave_node.gd" +}, { +"base": "BeehaveTree", +"class": "BeehaveRoot", +"language": "GDScript", +"path": "res://addons/beehave/nodes/beehave_root.gd" +}, { +"base": "Node", +"class": "BeehaveTree", +"language": "GDScript", +"path": "res://addons/beehave/nodes/beehave_tree.gd" +}, { +"base": "BeehaveNode", +"class": "Composite", +"language": "GDScript", +"path": "res://addons/beehave/nodes/composites/composite.gd" +}, { +"base": "Leaf", +"class": "ConditionLeaf", +"language": "GDScript", +"path": "res://addons/beehave/nodes/leaves/condition.gd" +}, { +"base": "BeehaveNode", +"class": "Decorator", +"language": "GDScript", +"path": "res://addons/beehave/nodes/decorators/decorator.gd" +}, { +"base": "Decorator", +"class": "InverterDecorator", +"language": "GDScript", +"path": "res://addons/beehave/nodes/decorators/inverter.gd" +}, { +"base": "BeehaveNode", +"class": "Leaf", +"language": "GDScript", +"path": "res://addons/beehave/nodes/leaves/leaf.gd" +}, { +"base": "Decorator", +"class": "LimiterDecorator", +"language": "GDScript", +"path": "res://addons/beehave/nodes/decorators/limiter.gd" +}, { +"base": "Composite", +"class": "SelectorComposite", +"language": "GDScript", +"path": "res://addons/beehave/nodes/composites/selector.gd" +}, { +"base": "Composite", +"class": "SelectorStarComposite", +"language": "GDScript", +"path": "res://addons/beehave/nodes/composites/selector_star.gd" +}, { +"base": "Composite", +"class": "SequenceComposite", +"language": "GDScript", +"path": "res://addons/beehave/nodes/composites/sequence.gd" +}, { +"base": "Composite", +"class": "SequenceStarComposite", +"language": "GDScript", +"path": "res://addons/beehave/nodes/composites/sequence_star.gd" +} ] +_global_script_class_icons={ +"ActionLeaf": "res://addons/beehave/icons/action.svg", +"AlwaysFailDecorator": "res://addons/beehave/icons/fail.svg", +"AlwaysSucceedDecorator": "res://addons/beehave/icons/succeed.svg", +"BeehaveNode": "res://addons/beehave/icons/action.svg", +"BeehaveRoot": "res://addons/beehave/icons/tree.svg", +"BeehaveTree": "", +"Composite": "res://addons/beehave/icons/category_composite.svg", +"ConditionLeaf": "res://addons/beehave/icons/condition.svg", +"Decorator": "res://addons/beehave/icons/category_decorator.svg", +"InverterDecorator": "res://addons/beehave/icons/inverter.svg", +"Leaf": "res://addons/beehave/icons/action.svg", +"LimiterDecorator": "res://addons/beehave/icons/limiter.svg", +"SelectorComposite": "res://addons/beehave/icons/selector.svg", +"SelectorStarComposite": "res://addons/beehave/icons/selector_star.svg", +"SequenceComposite": "res://addons/beehave/icons/sequencer.svg", +"SequenceStarComposite": "res://addons/beehave/icons/sequencer_star.svg" +} + [application] config/name="City Limits" @@ -32,7 +132,7 @@ window/stretch/aspect="keep" [editor_plugins] -enabled=PoolStringArray( ) +enabled=PoolStringArray( "res://addons/beehave/plugin.cfg" ) [gdnative] @@ -66,8 +166,8 @@ ui_down={ } ui_cheats={ "deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":false,"meta":true,"command":true,"pressed":false,"scancode":67,"physical_scancode":0,"unicode":0,"echo":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":true,"command":true,"pressed":false,"scancode":88,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":true,"meta":true,"command":true,"pressed":false,"scancode":67,"physical_scancode":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":true,"meta":true,"command":true,"pressed":false,"scancode":88,"physical_scancode":0,"unicode":0,"echo":false,"script":null) ] }