// ============================================================
// Advanced Nodes: Delay, WaitUntil, LimitedSequence
// ============================================================
///|
pub fn delay_node(child : Node, delay_ticks : Int) -> Node {
let current_delay : Ref[Int] = Ref::new(0)
let tick = fn(bb) {
if current_delay.get() < delay_ticks {
current_delay.set(current_delay.get() + 1)
return Status::BTRunning
}
let status = child.tick(bb)
if status != Status::BTRunning {
current_delay.set(0)
}
status
}
let reset = fn() {
current_delay.set(0)
child.reset()
}
Node::new(tick, reset)
}
///|
pub fn wait_until_node(condition : (Blackboard) -> Bool) -> Node {
let tick = fn(bb) {
if condition(bb) {
Status::BTSuccess
} else {
Status::BTRunning
}
}
let reset = fn() { () }
Node::new(tick, reset)
}
///|
pub fn limited_sequence(children : Array[Node], limit : Int) -> Node {
let count : Ref[Int] = Ref::new(0)
let running_child : Ref[Int] = Ref::new(0)
let tick = fn(bb) {
if count.get() >= limit {
return Status::BTFailure
}
let mut i = running_child.get()
while i < children.length() {
let child = children[i]
let status = child.tick(bb)
match status {
Status::BTRunning => {
running_child.set(i)
return Status::BTRunning
}
Status::BTFailure => {
for c in children {
c.reset()
}
running_child.set(0)
return Status::BTFailure
}
Status::BTSuccess => i = i + 1
}
}
running_child.set(0)
count.set(count.get() + 1)
Status::BTSuccess
}
let reset = fn() {
count.set(0)
running_child.set(0)
for c in children {
c.reset()
}
}
Node::new(tick, reset)
}