You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			93 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			GDScript
		
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			GDScript
		
	
| ## 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
 | |
| @icon("../../icons/sequence_random.svg")
 | |
| class_name SequenceRandomComposite extends RandomizedComposite
 | |
| 
 | |
| # Emitted whenever the children are shuffled.
 | |
| signal reset(new_order: Array[Node])
 | |
| 
 | |
| ## 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 _ready() -> void:
 | |
| 	super()
 | |
| 	if random_seed == 0:
 | |
| 		randomize()
 | |
| 
 | |
| 
 | |
| 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]
 | |
| 
 | |
| 		if c != running_child:
 | |
| 			c.before_run(actor, blackboard)
 | |
| 
 | |
| 		var response = c.tick(actor, blackboard)
 | |
| 		if can_send_message(blackboard):
 | |
| 			BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response)
 | |
| 
 | |
| 		if c is ConditionLeaf:
 | |
| 			blackboard.set_value("last_condition", c, str(actor.get_instance_id()))
 | |
| 			blackboard.set_value("last_condition_status", response, str(actor.get_instance_id()))
 | |
| 
 | |
| 		match response:
 | |
| 			SUCCESS:
 | |
| 				_children_bag.erase(c)
 | |
| 				c.after_run(actor, blackboard)
 | |
| 			FAILURE:
 | |
| 				_children_bag.erase(c)
 | |
| 				c.after_run(actor, blackboard)
 | |
| 				return FAILURE
 | |
| 			RUNNING:
 | |
| 				running_child = c
 | |
| 				if c is ActionLeaf:
 | |
| 					blackboard.set_value("running_action", c, str(actor.get_instance_id()))
 | |
| 				return RUNNING
 | |
| 
 | |
| 	return SUCCESS
 | |
| 
 | |
| 
 | |
| func after_run(actor: Node, blackboard: Blackboard) -> void:
 | |
| 	if not resume_on_failure:
 | |
| 		_reset()
 | |
| 	super(actor, blackboard)
 | |
| 
 | |
| 
 | |
| func interrupt(actor: Node, blackboard: Blackboard) -> void:
 | |
| 	if not resume_on_interrupt:
 | |
| 		_reset()
 | |
| 	super(actor, blackboard)
 | |
| 
 | |
| 
 | |
| func _get_reversed_indexes() -> Array[int]:
 | |
| 	var reversed: Array[int]
 | |
| 	reversed.assign(range(_children_bag.size()))
 | |
| 	reversed.reverse()
 | |
| 	return reversed
 | |
| 
 | |
| 
 | |
| func _reset() -> void:
 | |
| 	var new_order = get_shuffled_children()
 | |
| 	_children_bag = new_order.duplicate()
 | |
| 	_children_bag.reverse() # It needs to run the children in reverse order.
 | |
| 	reset.emit(new_order)
 | |
| 
 | |
| 
 | |
| func get_class_name() -> Array[StringName]:
 | |
| 	var classes := super()
 | |
| 	classes.push_back(&"SequenceRandomComposite")
 | |
| 	return classes
 |