Add addons

This commit is contained in:
Joey Yakimowich-Payne 2023-01-03 16:53:53 -07:00
commit 3367bad24f
No known key found for this signature in database
GPG key ID: 6BFE655FA5ABD1E1
527 changed files with 36197 additions and 0 deletions

View file

@ -0,0 +1,30 @@
## A Composite node controls the flow of execution of its children in a specific manner.
@tool
class_name Composite extends BeehaveNode
@icon("../../icons/category_composite.svg")
var running_child: BeehaveNode = null
func _ready():
if Engine.is_editor_hint():
return
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()])
func _get_configuration_warnings() -> PackedStringArray:
var warnings: PackedStringArray = super._get_configuration_warnings()
if get_children().filter(func(x): return x is BeehaveNode).size() < 2:
warnings.append("Any composite node should have at least two children. Otherwise it is not useful.")
return warnings
func interrupt(actor: Node, blackboard: Blackboard) -> void:
if running_child != null:
running_child.interrupt(actor, blackboard)
running_child = null

View file

@ -0,0 +1,25 @@
## Selector nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`. This node will attempt to process all its children every
## single tick, even if one of them is currently `RUNNING` already.
@tool
class_name SelectorComposite extends Composite
@icon("../../icons/selector.svg")
func tick(actor: Node, blackboard: Blackboard) -> int:
for c in get_children():
var response = c.tick(actor, blackboard)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response != FAILURE:
if response == SUCCESS:
# Interrupt any child that was RUNNING before.
interrupt(actor, blackboard)
else: # RUNNING
running_child = c
return response
return FAILURE

View file

@ -0,0 +1,54 @@
## This node will attempt to execute all of its children just like a
## [code]SelectorStar[/code] would, with the exception that the children
## will be executed in a random order.
@tool
class_name SelectorRandomComposite extends Composite
@icon("../../icons/selector_random.svg")
## A shuffled list of the children that will be executed in reverse order.
var _children_bag: Array[Node] = []
var c: Node
func tick(actor: Node, blackboard: Blackboard) -> int:
if _children_bag.is_empty():
_reset()
# We need to traverse the array in reverse since we will be manipulating it.
for i in _get_reversed_indexes():
c = _children_bag[i]
var response = c.tick(actor, blackboard)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response == RUNNING:
running_child = c
else:
_children_bag.erase(c)
if response != FAILURE:
if response == SUCCESS:
_reset()
return response
return FAILURE
func interrupt(actor: Node, blackboard: Blackboard) -> void:
_reset()
super(actor, blackboard)
func _get_reversed_indexes() -> Array[int]:
var reversed = range(_children_bag.size())
reversed.reverse()
return reversed
## Generates a new shuffled list of the children.
func _reset() -> void:
_children_bag = get_children().duplicate()
_children_bag.shuffle()

View file

@ -0,0 +1,32 @@
## Selector Star nodes will attempt to execute each of its children until one of
## them return `SUCCESS`. If all children return `FAILURE`, this node will also
## return `FAILURE`. This node will skip all previous child nodes that were
## executed prior, in case one of the children is currently in `RUNNING` state.
@tool
class_name SelectorStarComposite extends Composite
@icon("../../icons/selector_reactive.svg")
var last_execution_index = 0
func tick(actor: Node, blackboard: Blackboard) -> int:
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_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response != FAILURE:
if response == SUCCESS:
last_execution_index = 0
else: # RUNNING
running_child = c
return response
else:
last_execution_index += 1
last_execution_index = 0
return FAILURE

View file

@ -0,0 +1,26 @@
## Sequence nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE`. This node will attempt to process all its children every
## single tick, even if one of them is currently `RUNNING` already.
@tool
class_name SequenceComposite extends Composite
@icon("../../icons/sequence.svg")
func tick(actor: Node, blackboard: Blackboard) -> int:
for c in get_children():
var response = c.tick(actor, blackboard)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response != SUCCESS:
if response == FAILURE:
# Interrupt any child that was RUNNING before.
interrupt(actor, blackboard)
else: # RUNNING
running_child = c
return response
return SUCCESS

View file

@ -0,0 +1,60 @@
## This node will attempt to execute all of its children just like a
## [code]SequenceStar[/code] would, with the exception that the children
## will be executed in a random order.
@tool
class_name SequenceRandomComposite extends Composite
@icon("../../icons/sequence_random.svg")
## Whether the sequence should start where it left off after a previous failure.
@export var resume_on_failure: bool = false
## Whether the sequence should start where it left off after a previous interruption.
@export var resume_on_interrupt: bool = false
## A shuffled list of the children that will be executed in reverse order.
var _children_bag: Array[Node] = []
var c: Node
func tick(actor: Node, blackboard: Blackboard) -> int:
if _children_bag.is_empty():
_reset()
# We need to traverse the array in reverse since we will be manipulating it.
for i in _get_reversed_indexes():
c = _children_bag[i]
var response = c.tick(actor, blackboard)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response == RUNNING:
running_child = c
else:
_children_bag.erase(c)
if response != SUCCESS:
if not resume_on_failure and response == FAILURE:
_reset()
return response
return SUCCESS
func interrupt(actor: Node, blackboard: Blackboard) -> void:
if not resume_on_interrupt:
_reset()
super(actor, blackboard)
func _get_reversed_indexes() -> Array[int]:
var reversed = range(_children_bag.size())
reversed.reverse()
return reversed
## Generates a new shuffled list of the children.
func _reset() -> void:
_children_bag = get_children().duplicate()
_children_bag.shuffle()

View file

@ -0,0 +1,37 @@
## Sequence Star nodes will attempt to execute all of its children and report
## `SUCCESS` in case all of the children report a `SUCCESS` status code.
## If at least one child reports a `FAILURE` status code, this node will also
## return `FAILURE`. This node will skip all previous child nodes that succeeded
## prior, in case one of the children is currently in `RUNNING` state
@tool
class_name SequenceStarComposite extends Composite
@icon("../../icons/sequence_reactive.svg")
var successful_index = 0
func tick(actor: Node, blackboard: Blackboard) -> int:
for c in get_children():
if c.get_index() < successful_index:
continue
var response = c.tick(actor, blackboard)
if c is ConditionLeaf:
blackboard.set_value("last_condition", c)
blackboard.set_value("last_condition_status", response)
if response != SUCCESS:
if response == FAILURE:
successful_index = 0
else: # RUNNING
running_child = c
return response
else:
successful_index += 1
if successful_index == get_child_count():
successful_index = 0
return SUCCESS
else:
successful_index = 0
return FAILURE