mirror of
https://github.com/TangentFoxy/Behave.git
synced 2024-11-15 11:04:21 +00:00
rewrite to use objects for data storage
This commit is contained in:
parent
43e8048341
commit
6a61891ade
@ -84,11 +84,12 @@ after the entire tree has been processed.
|
|||||||
|
|
||||||
## Decorator Nodes
|
## Decorator Nodes
|
||||||
|
|
||||||
Pass a single node to these, except for `Repeat`, which needs a number & a node.
|
Pass a single node to these, except for `Repeat`, which needs a number followed
|
||||||
All decorator nodes (except `RunOnce`) repeat after the entire tree has been
|
by a node. All decorator nodes (except `RunOnce`) repeat after the entire tree
|
||||||
processed.
|
has been processed.
|
||||||
|
|
||||||
- Repeat: Repeats a node a specified number of times, fails if the node fails.
|
- Repeat: Repeats a node a specified number of times, fails if the node fails.
|
||||||
|
- Decorator: Does nothing except return the result of its child node.
|
||||||
- Succeed: Runs a node and returns success.
|
- Succeed: Runs a node and returns success.
|
||||||
- Fail: Runs a node and returns failure.
|
- Fail: Runs a node and returns failure.
|
||||||
- Invert: Runs a node, reporting a success on fail, and failure on success.
|
- Invert: Runs a node, reporting a success on fail, and failure on success.
|
||||||
|
387
behave.lua
387
behave.lua
@ -17,23 +17,28 @@ local Node
|
|||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
|
addObject = function(self, obj)
|
||||||
|
obj[self.u] = {
|
||||||
|
started = false
|
||||||
|
}
|
||||||
|
end,
|
||||||
run = function(self)
|
run = function(self)
|
||||||
return success
|
return success
|
||||||
end,
|
end,
|
||||||
update = function(self, ...)
|
update = function(self, obj, ...)
|
||||||
local result = success
|
local result = success
|
||||||
if not self.started and self.start then
|
if not obj[self.u].started and self.start then
|
||||||
result = self:start(...)
|
result = self:start(obj, ...)
|
||||||
self.started = true
|
obj[self.u].started = true
|
||||||
end
|
end
|
||||||
if result == success then
|
if result == success then
|
||||||
result = self:run(...)
|
result = self:run(obj, ...)
|
||||||
end
|
end
|
||||||
if result == success then
|
if result == success then
|
||||||
if self.finish then
|
if self.finish then
|
||||||
result = self:finish(...)
|
result = self:finish(obj, ...)
|
||||||
end
|
end
|
||||||
self.started = false
|
obj[self.u].started = false
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
@ -50,7 +55,7 @@ do
|
|||||||
self.success = success
|
self.success = success
|
||||||
self.running = running
|
self.running = running
|
||||||
self.fail = fail
|
self.fail = fail
|
||||||
self.started = false
|
self.u = { }
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Node"
|
__name = "Node"
|
||||||
@ -70,22 +75,28 @@ do
|
|||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
addObject = function(self, obj)
|
||||||
|
obj[self.u] = {
|
||||||
|
index = 0,
|
||||||
|
running = 0
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
update = function(self, obj, ...)
|
||||||
local result = success
|
local result = success
|
||||||
if self._running then
|
if obj[self.u].running then
|
||||||
result = self._running:update(...)
|
result = obj[self.u].running:update(obj, ...)
|
||||||
if not (result == running) then
|
if not (result == running) then
|
||||||
self._running = false
|
obj[self.u].running = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
while result == success and self.index < #self.nodes do
|
while result == success and obj[self.u].index < #self.nodes do
|
||||||
self.index = self.index + 1
|
obj[self.u].index = obj[self.u].index + 1
|
||||||
result = self.nodes[self.index]:update(...)
|
result = self.nodes[obj[self.u].index]:update(obj, ...)
|
||||||
end
|
end
|
||||||
if result == running then
|
if result == running then
|
||||||
self._running = self.nodes[self.index]
|
obj[self.u].running = self.nodes[obj[self.u].index]
|
||||||
else
|
else
|
||||||
self.index = 0
|
obj[self.u].index = 0
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
@ -98,9 +109,7 @@ do
|
|||||||
nodes = { }
|
nodes = { }
|
||||||
end
|
end
|
||||||
self.nodes = nodes
|
self.nodes = nodes
|
||||||
_class_0.__parent.__init(self)
|
return _class_0.__parent.__init(self)
|
||||||
self.index = 0
|
|
||||||
self._running = false
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Sequence",
|
__name = "Sequence",
|
||||||
@ -134,22 +143,28 @@ do
|
|||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
addObject = function(self, obj)
|
||||||
|
obj[self.u] = {
|
||||||
|
index = 0,
|
||||||
|
running = 0
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
update = function(self, obj, ...)
|
||||||
local result = fail
|
local result = fail
|
||||||
if self._running then
|
if obj[self.u].running then
|
||||||
result = self._running:update(...)
|
result = obj[self.u].running:update(obj, ...)
|
||||||
if not (result == running) then
|
if not (result == running) then
|
||||||
self._running = false
|
obj[self.u].running = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
while result == fail and self.index < #self.nodes do
|
while result == fail and obj[self.u].index < #self.nodes do
|
||||||
self.index = self.index + 1
|
obj[self.u].index = obj[self.u].index + 1
|
||||||
result = self.nodes[self.index]:update(...)
|
result = self.nodes[obj[self.u].index]:update(obj, ...)
|
||||||
end
|
end
|
||||||
if result == running then
|
if result == running then
|
||||||
self._running = self.nodes[self.index]
|
obj[self.u].running = self.nodes[obj[self.u].index]
|
||||||
else
|
else
|
||||||
self.index = 0
|
obj[self.u].index = 0
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
@ -162,9 +177,7 @@ do
|
|||||||
nodes = { }
|
nodes = { }
|
||||||
end
|
end
|
||||||
self.nodes = nodes
|
self.nodes = nodes
|
||||||
_class_0.__parent.__init(self)
|
return _class_0.__parent.__init(self)
|
||||||
self.index = 0
|
|
||||||
self._running = false
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Selector",
|
__name = "Selector",
|
||||||
@ -198,9 +211,9 @@ do
|
|||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
update = function(self, obj, ...)
|
||||||
local index = math.floor(math.random() * #self.nodes + 1)
|
local index = math.floor(math.random() * #self.nodes + 1)
|
||||||
return self.nodes[index]:update(...)
|
return self.nodes[index]:update(obj, ...)
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
@ -240,40 +253,26 @@ do
|
|||||||
end
|
end
|
||||||
Random = _class_0
|
Random = _class_0
|
||||||
end
|
end
|
||||||
local RandomSequence
|
local Randomizer
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
shuffle = function(self)
|
addObject = function(self, obj)
|
||||||
self._shuffled = { }
|
obj[self.u] = {
|
||||||
|
running = false
|
||||||
|
}
|
||||||
|
return self:shuffle(obj)
|
||||||
|
end,
|
||||||
|
shuffle = function(self, obj)
|
||||||
|
obj[self.u].shuffledNodes = { }
|
||||||
for i = 1, #self.nodes do
|
for i = 1, #self.nodes do
|
||||||
local r = math.random(i)
|
local r = math.random(i)
|
||||||
if not (r == i) then
|
if not (r == i) then
|
||||||
self._shuffled[i] = self._shuffled[r]
|
obj[self.u].shuffledNodes[i] = obj[self.u].shuffledNodes[r]
|
||||||
end
|
end
|
||||||
self._shuffled[r] = self.nodes[i]
|
obj[self.u].shuffledNodes[r] = self.nodes[i]
|
||||||
end
|
end
|
||||||
end,
|
|
||||||
update = function(self, ...)
|
|
||||||
local result = success
|
|
||||||
if self._running then
|
|
||||||
result = self._running:update(...)
|
|
||||||
if not (result == running) then
|
|
||||||
self._running = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local tmp
|
|
||||||
while result == success and #self._shuffled > 0 do
|
|
||||||
result = self._shuffled[1]:update(...)
|
|
||||||
tmp = table.remove(self._shuffled, 1)
|
|
||||||
end
|
|
||||||
if result == running then
|
|
||||||
self._running = tmp
|
|
||||||
else
|
|
||||||
self:shuffle()
|
|
||||||
end
|
|
||||||
return result
|
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
@ -284,9 +283,66 @@ do
|
|||||||
nodes = { }
|
nodes = { }
|
||||||
end
|
end
|
||||||
self.nodes = nodes
|
self.nodes = nodes
|
||||||
_class_0.__parent.__init(self)
|
return _class_0.__parent.__init(self)
|
||||||
self._running = false
|
end,
|
||||||
return self:shuffle()
|
__base = _base_0,
|
||||||
|
__name = "Randomizer",
|
||||||
|
__parent = _parent_0
|
||||||
|
}, {
|
||||||
|
__index = function(cls, name)
|
||||||
|
local val = rawget(_base_0, name)
|
||||||
|
if val == nil then
|
||||||
|
local parent = rawget(cls, "__parent")
|
||||||
|
if parent then
|
||||||
|
return parent[name]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__call = function(cls, ...)
|
||||||
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
|
cls.__init(_self_0, ...)
|
||||||
|
return _self_0
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_base_0.__class = _class_0
|
||||||
|
if _parent_0.__inherited then
|
||||||
|
_parent_0.__inherited(_parent_0, _class_0)
|
||||||
|
end
|
||||||
|
Randomizer = _class_0
|
||||||
|
end
|
||||||
|
local RandomSequence
|
||||||
|
do
|
||||||
|
local _class_0
|
||||||
|
local _parent_0 = Randomizer
|
||||||
|
local _base_0 = {
|
||||||
|
update = function(self, obj, ...)
|
||||||
|
local result = success
|
||||||
|
if obj[self.u].running then
|
||||||
|
result = obj[self.u].running:update(obj, ...)
|
||||||
|
if not (result == running) then
|
||||||
|
obj[self.u].running = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local tmp
|
||||||
|
while result == success and #obj[self.u].shuffledNodes > 0 do
|
||||||
|
result = obj[self.u].shuffledNodes[1]:update(obj, ...)
|
||||||
|
tmp = table.remove(obj[self.u].shuffledNodes, 1)
|
||||||
|
end
|
||||||
|
if result == running then
|
||||||
|
obj[self.u].running = tmp
|
||||||
|
else
|
||||||
|
self:shuffle(obj)
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
}
|
||||||
|
_base_0.__index = _base_0
|
||||||
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
|
_class_0 = setmetatable({
|
||||||
|
__init = function(self, ...)
|
||||||
|
return _class_0.__parent.__init(self, ...)
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "RandomSequence",
|
__name = "RandomSequence",
|
||||||
@ -318,33 +374,23 @@ end
|
|||||||
local RandomSelector
|
local RandomSelector
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Randomizer
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
shuffle = function(self)
|
update = function(self, obj, ...)
|
||||||
self._shuffled = { }
|
|
||||||
for i = 1, #self.nodes do
|
|
||||||
local r = math.random(i)
|
|
||||||
if not (r == i) then
|
|
||||||
self._shuffled[i] = self._shuffled[r]
|
|
||||||
end
|
|
||||||
self._shuffled[r] = self.nodes[i]
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
update = function(self, ...)
|
|
||||||
local result = fail
|
local result = fail
|
||||||
if self._running then
|
if obj[self.u].running then
|
||||||
result = self._running:update(...)
|
result = obj[self.u].running:update(obj, ...)
|
||||||
if not (result == running) then
|
if not (result == running) then
|
||||||
self._running = false
|
obj[self.u].running = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local tmp
|
local tmp
|
||||||
while result == fail and #self._shuffled > 0 do
|
while result == fail and #obj[self.u].shuffledNodes > 0 do
|
||||||
result = self._shuffled[1]:update(...)
|
result = obj[self.u].shuffledNodes[1]:update(obj, ...)
|
||||||
tmp = table.remove(self._shuffled, 1)
|
tmp = table.remove(obj[self.u].shuffledNodes, 1)
|
||||||
end
|
end
|
||||||
if result == running then
|
if result == running then
|
||||||
self._running = tmp
|
obj[self.u].running = tmp
|
||||||
else
|
else
|
||||||
self:shuffle()
|
self:shuffle()
|
||||||
end
|
end
|
||||||
@ -354,14 +400,8 @@ do
|
|||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, nodes)
|
__init = function(self, ...)
|
||||||
if nodes == nil then
|
return _class_0.__parent.__init(self, ...)
|
||||||
nodes = { }
|
|
||||||
end
|
|
||||||
self.nodes = nodes
|
|
||||||
_class_0.__parent.__init(self)
|
|
||||||
self._running = false
|
|
||||||
return self:shuffle()
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "RandomSelector",
|
__name = "RandomSelector",
|
||||||
@ -395,22 +435,28 @@ do
|
|||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
addObject = function(self, obj)
|
||||||
|
obj[self.u] = {
|
||||||
|
counter = 1,
|
||||||
|
running = false
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
update = function(self, obj, ...)
|
||||||
local result = success
|
local result = success
|
||||||
if self._running then
|
if obj[self.u].running then
|
||||||
result = self.node:update(...)
|
result = self.node:update(obj, ...)
|
||||||
if not (result == running) then
|
if not (result == running) then
|
||||||
self._running = false
|
obj[self.u].running = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
while result == success and self.counter < self.cycles do
|
while result == success and obj[self.u].counter < self.cycles do
|
||||||
self.counter = self.counter + 1
|
obj[self.u].counter = obj[self.u].counter + 1
|
||||||
result = self.node:update(...)
|
result = self.node:update(obj, ...)
|
||||||
end
|
end
|
||||||
if result == running then
|
if result == running then
|
||||||
self._running = true
|
obj[self.u].running = true
|
||||||
else
|
else
|
||||||
self.counter = 1
|
obj[self.u].counter = 1
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
@ -426,9 +472,7 @@ do
|
|||||||
node = Node()
|
node = Node()
|
||||||
end
|
end
|
||||||
self.cycles, self.node = cycles, node
|
self.cycles, self.node = cycles, node
|
||||||
_class_0.__parent.__init(self)
|
return _class_0.__parent.__init(self)
|
||||||
self.counter = 1
|
|
||||||
self._running = false
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Repeat",
|
__name = "Repeat",
|
||||||
@ -457,17 +501,13 @@ do
|
|||||||
end
|
end
|
||||||
Repeat = _class_0
|
Repeat = _class_0
|
||||||
end
|
end
|
||||||
local Succeed
|
local Decorator
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Node
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
update = function(self, obj, ...)
|
||||||
if running == self.node:update(...) then
|
return self.node:update(obj, ...)
|
||||||
return running
|
|
||||||
else
|
|
||||||
return success
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
@ -481,6 +521,52 @@ do
|
|||||||
return _class_0.__parent.__init(self)
|
return _class_0.__parent.__init(self)
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
|
__name = "Decorator",
|
||||||
|
__parent = _parent_0
|
||||||
|
}, {
|
||||||
|
__index = function(cls, name)
|
||||||
|
local val = rawget(_base_0, name)
|
||||||
|
if val == nil then
|
||||||
|
local parent = rawget(cls, "__parent")
|
||||||
|
if parent then
|
||||||
|
return parent[name]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return val
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
__call = function(cls, ...)
|
||||||
|
local _self_0 = setmetatable({}, _base_0)
|
||||||
|
cls.__init(_self_0, ...)
|
||||||
|
return _self_0
|
||||||
|
end
|
||||||
|
})
|
||||||
|
_base_0.__class = _class_0
|
||||||
|
if _parent_0.__inherited then
|
||||||
|
_parent_0.__inherited(_parent_0, _class_0)
|
||||||
|
end
|
||||||
|
Decorator = _class_0
|
||||||
|
end
|
||||||
|
local Succeed
|
||||||
|
do
|
||||||
|
local _class_0
|
||||||
|
local _parent_0 = Decorator
|
||||||
|
local _base_0 = {
|
||||||
|
update = function(self, obj, ...)
|
||||||
|
if running == self.node:update(obj, ...) then
|
||||||
|
return running
|
||||||
|
else
|
||||||
|
return success
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
_base_0.__index = _base_0
|
||||||
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
|
_class_0 = setmetatable({
|
||||||
|
__init = function(self, ...)
|
||||||
|
return _class_0.__parent.__init(self, ...)
|
||||||
|
end,
|
||||||
|
__base = _base_0,
|
||||||
__name = "Succeed",
|
__name = "Succeed",
|
||||||
__parent = _parent_0
|
__parent = _parent_0
|
||||||
}, {
|
}, {
|
||||||
@ -510,10 +596,10 @@ end
|
|||||||
local Fail
|
local Fail
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Decorator
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
update = function(self, obj, ...)
|
||||||
if running == self.node:update(...) then
|
if running == self.node:update(obj, ...) then
|
||||||
return running
|
return running
|
||||||
else
|
else
|
||||||
return fail
|
return fail
|
||||||
@ -523,12 +609,8 @@ do
|
|||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, node)
|
__init = function(self, ...)
|
||||||
if node == nil then
|
return _class_0.__parent.__init(self, ...)
|
||||||
node = Node()
|
|
||||||
end
|
|
||||||
self.node = node
|
|
||||||
return _class_0.__parent.__init(self)
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Fail",
|
__name = "Fail",
|
||||||
@ -560,10 +642,10 @@ end
|
|||||||
local Invert
|
local Invert
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Decorator
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
update = function(self, obj, ...)
|
||||||
local result = self.node:update(...)
|
local result = self.node:update(obj, ...)
|
||||||
if result == running then
|
if result == running then
|
||||||
return running
|
return running
|
||||||
elseif result == success then
|
elseif result == success then
|
||||||
@ -576,12 +658,8 @@ do
|
|||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, node)
|
__init = function(self, ...)
|
||||||
if node == nil then
|
return _class_0.__parent.__init(self, ...)
|
||||||
node = Node()
|
|
||||||
end
|
|
||||||
self.node = node
|
|
||||||
return _class_0.__parent.__init(self)
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "Invert",
|
__name = "Invert",
|
||||||
@ -613,13 +691,18 @@ end
|
|||||||
local RunOnce
|
local RunOnce
|
||||||
do
|
do
|
||||||
local _class_0
|
local _class_0
|
||||||
local _parent_0 = Node
|
local _parent_0 = Decorator
|
||||||
local _base_0 = {
|
local _base_0 = {
|
||||||
update = function(self, ...)
|
addObject = function(self, obj)
|
||||||
if not (self.ran) then
|
obj[self.u] = {
|
||||||
local result = self.node:update(...)
|
ran = false
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
update = function(self, obj, ...)
|
||||||
|
if not (obj[self.u].ran) then
|
||||||
|
local result = self.node:update(obj, ...)
|
||||||
if not (result == running) then
|
if not (result == running) then
|
||||||
self.run = true
|
obj[self.u].ran = true
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
else
|
else
|
||||||
@ -630,13 +713,8 @@ do
|
|||||||
_base_0.__index = _base_0
|
_base_0.__index = _base_0
|
||||||
setmetatable(_base_0, _parent_0.__base)
|
setmetatable(_base_0, _parent_0.__base)
|
||||||
_class_0 = setmetatable({
|
_class_0 = setmetatable({
|
||||||
__init = function(self, node)
|
__init = function(self, ...)
|
||||||
if node == nil then
|
return _class_0.__parent.__init(self, ...)
|
||||||
node = Node()
|
|
||||||
end
|
|
||||||
self.node = node
|
|
||||||
_class_0.__parent.__init(self)
|
|
||||||
self.ran = false
|
|
||||||
end,
|
end,
|
||||||
__base = _base_0,
|
__base = _base_0,
|
||||||
__name = "RunOnce",
|
__name = "RunOnce",
|
||||||
@ -672,19 +750,19 @@ Class = function(name, parent)
|
|||||||
__index = base,
|
__index = base,
|
||||||
__class = newClass
|
__class = newClass
|
||||||
}
|
}
|
||||||
newClass = setmetable({
|
newClass = setmetatable({
|
||||||
__init = function() end,
|
__init = function() end,
|
||||||
__base = base,
|
__base = base,
|
||||||
__name = name
|
__name = name
|
||||||
}, {
|
}, {
|
||||||
__call = function(cls, ...)
|
__call = function(cls, ...)
|
||||||
local self = setmetable({ }, base)
|
local self = setmetatable({ }, base)
|
||||||
cls.__init(self, ...)
|
cls.__init(self, ...)
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
if parent then
|
if parent then
|
||||||
setmetable(base, {
|
setmetatable(base, {
|
||||||
__parent = parent.__base
|
__parent = parent.__base
|
||||||
})
|
})
|
||||||
newClass.__parent = parent
|
newClass.__parent = parent
|
||||||
@ -702,13 +780,14 @@ Class = function(name, parent)
|
|||||||
end
|
end
|
||||||
return newClass, base
|
return newClass, base
|
||||||
end
|
end
|
||||||
local behave = {
|
return setmetatable({
|
||||||
Node = Node,
|
Node = Node,
|
||||||
Sequence = Sequence,
|
Sequence = Sequence,
|
||||||
Selector = Selector,
|
Selector = Selector,
|
||||||
Random = Random,
|
Random = Random,
|
||||||
RandomSequence = RandomSequence,
|
RandomSequence = RandomSequence,
|
||||||
RandomSelector = RandomSelector,
|
RandomSelector = RandomSelector,
|
||||||
|
Decorator = Decorator,
|
||||||
Repeat = Repeat,
|
Repeat = Repeat,
|
||||||
Succeed = Succeed,
|
Succeed = Succeed,
|
||||||
Fail = Fail,
|
Fail = Fail,
|
||||||
@ -718,24 +797,8 @@ local behave = {
|
|||||||
running = running,
|
running = running,
|
||||||
fail = fail,
|
fail = fail,
|
||||||
Class = Class
|
Class = Class
|
||||||
}
|
}, {
|
||||||
behave.clone = function(object)
|
__call = function(bt, ...)
|
||||||
local new
|
return bt.Sequence(...)
|
||||||
local cls = getmetatable(object).__class.__name
|
|
||||||
if cls == "Repeat" then
|
|
||||||
new = behave[cls](object.cycles, object)
|
|
||||||
else
|
|
||||||
new = behave[cls](object)
|
|
||||||
end
|
end
|
||||||
if object.nodes then
|
})
|
||||||
local nodes = { }
|
|
||||||
for k, v in pairs(object.nodes) do
|
|
||||||
nodes[k] = behave.clone(v)
|
|
||||||
end
|
|
||||||
new.nodes = nodes
|
|
||||||
elseif object.node then
|
|
||||||
new.node = behave.clone(object.node)
|
|
||||||
end
|
|
||||||
return new
|
|
||||||
end
|
|
||||||
return behave
|
|
||||||
|
251
behave.moon
251
behave.moon
@ -11,21 +11,26 @@ class Node
|
|||||||
@running = running
|
@running = running
|
||||||
@fail = fail
|
@fail = fail
|
||||||
|
|
||||||
@started = false
|
@u = {}
|
||||||
|
|
||||||
|
addObject: (obj) =>
|
||||||
|
obj[@u] = {
|
||||||
|
started: false
|
||||||
|
}
|
||||||
|
|
||||||
run: =>
|
run: =>
|
||||||
return success
|
return success
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
result = success
|
result = success
|
||||||
if not @started and @start
|
if not obj[@u].started and @start
|
||||||
result = @\start ...
|
result = @\start obj, ...
|
||||||
@started = true
|
obj[@u].started = true
|
||||||
if result == success
|
if result == success
|
||||||
result = @\run ...
|
result = @\run obj, ...
|
||||||
if result == success
|
if result == success
|
||||||
result = @\finish(...) if @finish
|
result = @\finish(obj, ...) if @finish
|
||||||
@started = false
|
obj[@u].started = false
|
||||||
return result
|
return result
|
||||||
|
|
||||||
-- Runs children in order until one returns fail, or all succeed.
|
-- Runs children in order until one returns fail, or all succeed.
|
||||||
@ -33,25 +38,28 @@ class Sequence extends Node
|
|||||||
new: (@nodes={}) =>
|
new: (@nodes={}) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
@index = 0
|
addObject: (obj) =>
|
||||||
@_running = false
|
obj[@u] = {
|
||||||
|
index: 0
|
||||||
|
running: 0
|
||||||
|
}
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
result = success
|
result = success
|
||||||
|
|
||||||
if @_running
|
if obj[@u].running
|
||||||
result = @_running\update ...
|
result = obj[@u].running\update obj, ...
|
||||||
unless result == running
|
unless result == running
|
||||||
@_running = false
|
obj[@u].running = false
|
||||||
|
|
||||||
while result == success and @index < #@nodes
|
while result == success and obj[@u].index < #@nodes
|
||||||
@index += 1
|
obj[@u].index += 1
|
||||||
result = @nodes[@index]\update ...
|
result = @nodes[obj[@u].index]\update obj, ...
|
||||||
|
|
||||||
if result == running
|
if result == running
|
||||||
@_running = @nodes[@index]
|
obj[@u].running = @nodes[obj[@u].index]
|
||||||
else
|
else
|
||||||
@index = 0
|
obj[@u].index = 0
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -60,24 +68,27 @@ class Selector extends Node
|
|||||||
new: (@nodes={}) =>
|
new: (@nodes={}) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
@index = 0
|
addObject: (obj) =>
|
||||||
@_running = false
|
obj[@u] = {
|
||||||
|
index: 0
|
||||||
|
running: 0
|
||||||
|
}
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
result = fail
|
result = fail
|
||||||
if @_running
|
if obj[@u].running
|
||||||
result = @_running\update ...
|
result = obj[@u].running\update obj, ...
|
||||||
unless result == running
|
unless result == running
|
||||||
@_running = false
|
obj[@u].running = false
|
||||||
|
|
||||||
while result == fail and @index < #@nodes
|
while result == fail and obj[@u].index < #@nodes
|
||||||
@index += 1
|
obj[@u].index += 1
|
||||||
result = @nodes[@index]\update ...
|
result = @nodes[obj[@u].index]\update obj, ...
|
||||||
|
|
||||||
if result == running
|
if result == running
|
||||||
@_running = @nodes[@index]
|
obj[@u].running = @nodes[obj[@u].index]
|
||||||
else
|
else
|
||||||
@index = 0
|
obj[@u].index = 0
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -86,77 +97,67 @@ class Random extends Node
|
|||||||
new: (@nodes={}) =>
|
new: (@nodes={}) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
index = math.floor math.random! * #@nodes + 1
|
index = math.floor math.random! * #@nodes + 1
|
||||||
return @nodes[index]\update ...
|
return @nodes[index]\update obj, ...
|
||||||
|
|
||||||
-- Randomizes order of nodes in between complete runs of them as a Sequence.
|
class Randomizer extends Node
|
||||||
class RandomSequence extends Node
|
|
||||||
new: (@nodes={}) =>
|
new: (@nodes={}) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
@_running = false
|
addObject: (obj) =>
|
||||||
@shuffle!
|
obj[@u] = {
|
||||||
|
running: false
|
||||||
|
}
|
||||||
|
@shuffle obj
|
||||||
|
|
||||||
shuffle: =>
|
shuffle: (obj) =>
|
||||||
@_shuffled = {}
|
obj[@u].shuffledNodes = {}
|
||||||
for i = 1, #@nodes
|
for i = 1, #@nodes
|
||||||
r = math.random i
|
r = math.random i
|
||||||
unless r == i
|
unless r == i
|
||||||
@_shuffled[i] = @_shuffled[r]
|
obj[@u].shuffledNodes[i] = obj[@u].shuffledNodes[r]
|
||||||
@_shuffled[r] = @nodes[i]
|
obj[@u].shuffledNodes[r] = @nodes[i]
|
||||||
|
|
||||||
update: (...) =>
|
-- Randomizes order of nodes in between complete runs of them as a Sequence.
|
||||||
|
class RandomSequence extends Randomizer
|
||||||
|
update: (obj, ...) =>
|
||||||
result = success
|
result = success
|
||||||
|
|
||||||
if @_running
|
if obj[@u].running
|
||||||
result = @_running\update ...
|
result = obj[@u].running\update obj, ...
|
||||||
unless result == running
|
unless result == running
|
||||||
@_running = false
|
obj[@u].running = false
|
||||||
|
|
||||||
local tmp
|
local tmp
|
||||||
while result == success and #@_shuffled > 0
|
while result == success and #obj[@u].shuffledNodes > 0
|
||||||
result = @_shuffled[1]\update ...
|
result = obj[@u].shuffledNodes[1]\update obj, ...
|
||||||
tmp = table.remove @_shuffled, 1
|
tmp = table.remove obj[@u].shuffledNodes, 1
|
||||||
|
|
||||||
if result == running
|
if result == running
|
||||||
@_running = tmp
|
obj[@u].running = tmp
|
||||||
else
|
else
|
||||||
@shuffle!
|
@shuffle obj
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
-- Randomizes order of nodes in between complete runs of them as a Selector.
|
-- Randomizes order of nodes in between complete runs of them as a Selector.
|
||||||
class RandomSelector extends Node
|
class RandomSelector extends Randomizer
|
||||||
new: (@nodes={}) =>
|
update: (obj, ...) =>
|
||||||
super!
|
|
||||||
|
|
||||||
@_running = false
|
|
||||||
@shuffle!
|
|
||||||
|
|
||||||
shuffle: =>
|
|
||||||
@_shuffled = {}
|
|
||||||
for i = 1, #@nodes
|
|
||||||
r = math.random i
|
|
||||||
unless r == i
|
|
||||||
@_shuffled[i] = @_shuffled[r]
|
|
||||||
@_shuffled[r] = @nodes[i]
|
|
||||||
|
|
||||||
update: (...) =>
|
|
||||||
result = fail
|
result = fail
|
||||||
|
|
||||||
if @_running
|
if obj[@u].running
|
||||||
result = @_running\update ...
|
result = obj[@u].running\update obj, ...
|
||||||
unless result == running
|
unless result == running
|
||||||
@_running = false
|
obj[@u].running = false
|
||||||
|
|
||||||
local tmp
|
local tmp
|
||||||
while result == fail and #@_shuffled > 0
|
while result == fail and #obj[@u].shuffledNodes > 0
|
||||||
result = @_shuffled[1]\update ...
|
result = obj[@u].shuffledNodes[1]\update obj, ...
|
||||||
tmp = table.remove @_shuffled, 1
|
tmp = table.remove obj[@u].shuffledNodes, 1
|
||||||
|
|
||||||
if result == running
|
if result == running
|
||||||
@_running = tmp
|
obj[@u].running = tmp
|
||||||
else
|
else
|
||||||
@shuffle!
|
@shuffle!
|
||||||
|
|
||||||
@ -167,57 +168,58 @@ class Repeat extends Node
|
|||||||
new: (@cycles=2, @node=Node!) =>
|
new: (@cycles=2, @node=Node!) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
@counter = 1
|
addObject: (obj) =>
|
||||||
@_running = false
|
obj[@u] = {
|
||||||
|
counter: 1
|
||||||
|
running: false
|
||||||
|
}
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
result = success
|
result = success
|
||||||
|
|
||||||
if @_running
|
if obj[@u].running
|
||||||
result = @node\update ...
|
result = @node\update obj, ...
|
||||||
unless result == running
|
unless result == running
|
||||||
@_running = false
|
obj[@u].running = false
|
||||||
|
|
||||||
while result == success and @counter < @cycles
|
while result == success and obj[@u].counter < @cycles
|
||||||
@counter += 1
|
obj[@u].counter += 1
|
||||||
result = @node\update ...
|
result = @node\update obj, ...
|
||||||
|
|
||||||
if result == running
|
if result == running
|
||||||
@_running = true
|
obj[@u].running = true
|
||||||
else
|
else
|
||||||
@counter = 1
|
obj[@u].counter = 1
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
-- Returns success whether or not the node succeeds.
|
class Decorator extends Node
|
||||||
class Succeed extends Node
|
|
||||||
new: (@node=Node!) =>
|
new: (@node=Node!) =>
|
||||||
super!
|
super!
|
||||||
|
|
||||||
update: (...) =>
|
update: (obj, ...) =>
|
||||||
if running == @node\update ...
|
return @node\update obj, ...
|
||||||
|
|
||||||
|
-- Returns success whether or not the node succeeds.
|
||||||
|
class Succeed extends Decorator
|
||||||
|
update: (obj, ...) =>
|
||||||
|
if running == @node\update obj, ...
|
||||||
return running
|
return running
|
||||||
else
|
else
|
||||||
return success
|
return success
|
||||||
|
|
||||||
-- Returns fail whether or not the node fails.
|
-- Returns fail whether or not the node fails.
|
||||||
class Fail extends Node
|
class Fail extends Decorator
|
||||||
new: (@node=Node!) =>
|
update: (obj, ...) =>
|
||||||
super!
|
if running == @node\update obj, ...
|
||||||
|
|
||||||
update: (...) =>
|
|
||||||
if running == @node\update ...
|
|
||||||
return running
|
return running
|
||||||
else
|
else
|
||||||
return fail
|
return fail
|
||||||
|
|
||||||
-- Returns success when the node fails, and failure on success.
|
-- Returns success when the node fails, and failure on success.
|
||||||
class Invert extends Node
|
class Invert extends Decorator
|
||||||
new: (@node=Node!) =>
|
update: (obj, ...) =>
|
||||||
super!
|
result = @node\update obj, ...
|
||||||
|
|
||||||
update: (...) =>
|
|
||||||
result = @node\update ...
|
|
||||||
if result == running
|
if result == running
|
||||||
return running
|
return running
|
||||||
elseif result == success
|
elseif result == success
|
||||||
@ -226,17 +228,17 @@ class Invert extends Node
|
|||||||
return success
|
return success
|
||||||
|
|
||||||
-- Only runs children once, and returns fail from then on.
|
-- Only runs children once, and returns fail from then on.
|
||||||
class RunOnce extends Node
|
class RunOnce extends Decorator
|
||||||
new: (@node=Node!) =>
|
addObject: (obj) =>
|
||||||
super!
|
obj[@u] = {
|
||||||
|
ran: false
|
||||||
|
}
|
||||||
|
|
||||||
@ran = false
|
update: (obj, ...) =>
|
||||||
|
unless obj[@u].ran
|
||||||
update: (...) =>
|
result = @node\update obj, ...
|
||||||
unless @ran
|
|
||||||
result = @node\update ...
|
|
||||||
unless result == running
|
unless result == running
|
||||||
@run = true
|
obj[@u].ran = true
|
||||||
return result
|
return result
|
||||||
else
|
else
|
||||||
return fail
|
return fail
|
||||||
@ -249,19 +251,19 @@ Class = (name, parent) ->
|
|||||||
__class: newClass
|
__class: newClass
|
||||||
}
|
}
|
||||||
|
|
||||||
newClass = setmetable {
|
newClass = setmetatable {
|
||||||
__init: ->
|
__init: ->
|
||||||
__base: base
|
__base: base
|
||||||
__name: name
|
__name: name
|
||||||
}, {
|
}, {
|
||||||
__call: (cls, ...) ->
|
__call: (cls, ...) ->
|
||||||
@ = setmetable({}, base)
|
@ = setmetatable({}, base)
|
||||||
cls.__init(@, ...)
|
cls.__init(@, ...)
|
||||||
return @
|
return @
|
||||||
}
|
}
|
||||||
|
|
||||||
if parent
|
if parent
|
||||||
setmetable base, {
|
setmetatable base, {
|
||||||
__parent: parent.__base
|
__parent: parent.__base
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +280,7 @@ Class = (name, parent) ->
|
|||||||
|
|
||||||
return newClass, base
|
return newClass, base
|
||||||
|
|
||||||
behave = {
|
setmetatable {
|
||||||
-- Leaf Node
|
-- Leaf Node
|
||||||
:Node
|
:Node
|
||||||
|
|
||||||
@ -290,6 +292,7 @@ behave = {
|
|||||||
:RandomSelector
|
:RandomSelector
|
||||||
|
|
||||||
-- Decorator Nodes
|
-- Decorator Nodes
|
||||||
|
:Decorator
|
||||||
:Repeat
|
:Repeat
|
||||||
:Succeed
|
:Succeed
|
||||||
:Fail
|
:Fail
|
||||||
@ -303,25 +306,7 @@ behave = {
|
|||||||
|
|
||||||
-- Utility Fns
|
-- Utility Fns
|
||||||
:Class
|
:Class
|
||||||
|
}, {
|
||||||
|
__call: (bt, ...) ->
|
||||||
|
bt.Sequence ...
|
||||||
}
|
}
|
||||||
|
|
||||||
behave.clone = (object) ->
|
|
||||||
local new
|
|
||||||
cls = getmetatable(object).__class.__name
|
|
||||||
|
|
||||||
if cls == "Repeat"
|
|
||||||
new = behave[cls] object.cycles, object
|
|
||||||
else
|
|
||||||
new = behave[cls] object
|
|
||||||
|
|
||||||
if object.nodes
|
|
||||||
nodes = {}
|
|
||||||
for k,v in pairs object.nodes
|
|
||||||
nodes[k] = behave.clone v
|
|
||||||
new.nodes = nodes
|
|
||||||
elseif object.node
|
|
||||||
new.node = behave.clone object.node
|
|
||||||
|
|
||||||
return new
|
|
||||||
|
|
||||||
return behave
|
|
||||||
|
Loading…
Reference in New Issue
Block a user