Rework sequence and selector nodes to run every child, instead of one per update
This commit is contained in:
parent
28a181e2d4
commit
22932dce05
89
init.lua
89
init.lua
@ -1,6 +1,11 @@
|
||||
local Tactree = {}
|
||||
local Nodes = {}
|
||||
|
||||
local function NodeReset(node)
|
||||
node:_finish()
|
||||
node._started = false
|
||||
end
|
||||
|
||||
local function NodeStart(node, args)
|
||||
-- don't start again if started
|
||||
if node._started then return end
|
||||
@ -14,14 +19,27 @@ end
|
||||
|
||||
local function NodeUpdate(node, ...)
|
||||
-- automatically start if not started
|
||||
if not node._started then NodeStart(node) end
|
||||
if not node._started then
|
||||
NodeStart(node)
|
||||
end
|
||||
|
||||
-- mark node as run and unmark children
|
||||
node._ran = true
|
||||
for _, child in ipairs(node.children) do
|
||||
child._ran = false
|
||||
end
|
||||
|
||||
local result = node:_tick(...)
|
||||
|
||||
if type(result) == 'boolean' then
|
||||
node:_finish()
|
||||
if result ~= nil then
|
||||
NodeReset(node)
|
||||
end
|
||||
|
||||
node._started = false
|
||||
-- reset unrun children
|
||||
for _, child in ipairs(node.children) do
|
||||
if not child._ran and child._started then
|
||||
NodeReset(child)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
@ -85,8 +103,8 @@ local function tree_by_name(name, depth)
|
||||
node.update = NodeUpdate
|
||||
node.private = NodePrivateData
|
||||
|
||||
-- this will crash if there is a recursive structure
|
||||
-- find a way to prevent this?
|
||||
-- this will crash if there is a recursive structure; find a way to prevent this?
|
||||
-- does my API even allow declaring recursive structures?
|
||||
if Nodes[name].children then
|
||||
for _, child in ipairs(Nodes[name].children) do
|
||||
local cn = tree_by_name(child, depth + 1)
|
||||
@ -137,6 +155,20 @@ function Tactree.Tree(name)
|
||||
end
|
||||
|
||||
Tactree.Leaf 'Sequence'
|
||||
{
|
||||
function(node, ...)
|
||||
local child = 1
|
||||
local result
|
||||
repeat
|
||||
result = node.children[child]:update(...)
|
||||
child = child + 1
|
||||
until (not result) or (child > #node.children)
|
||||
|
||||
return result
|
||||
end
|
||||
}
|
||||
|
||||
Tactree.Leaf 'StepSequence'
|
||||
{
|
||||
start = function(node)
|
||||
node:private().current_child = 1
|
||||
@ -145,9 +177,7 @@ Tactree.Leaf 'Sequence'
|
||||
local result
|
||||
repeat
|
||||
result = node.children[node:private().current_child]:update(...)
|
||||
if result then
|
||||
node:private().current_child = node:private().current_child + 1
|
||||
end
|
||||
if result ~= nil then node:private().current_child = node:private().current_child + 1 end
|
||||
until (not result) or (node:private().current_child > #node.children)
|
||||
|
||||
return result
|
||||
@ -155,6 +185,20 @@ Tactree.Leaf 'Sequence'
|
||||
}
|
||||
|
||||
Tactree.Leaf 'Selector'
|
||||
{
|
||||
function(node, ...)
|
||||
local child = 1
|
||||
local result
|
||||
repeat
|
||||
result = node.children[child]:update(...)
|
||||
child = child + 1
|
||||
until (result ~= false) or (child > #node.children)
|
||||
|
||||
return result
|
||||
end
|
||||
}
|
||||
|
||||
Tactree.Leaf 'StepSelector'
|
||||
{
|
||||
start = function(node)
|
||||
node:private().current_child = 1
|
||||
@ -163,9 +207,7 @@ Tactree.Leaf 'Selector'
|
||||
local result
|
||||
repeat
|
||||
result = node.children[node:private().current_child]:update(...)
|
||||
if result == false then
|
||||
node:private().current_child = node:private().current_child + 1
|
||||
end
|
||||
if result ~= nil then node:private().current_child = node:private().current_child + 1 end
|
||||
until (result ~= false) or (node:private().current_child > #node.children)
|
||||
|
||||
return result
|
||||
@ -174,30 +216,11 @@ Tactree.Leaf 'Selector'
|
||||
|
||||
Tactree.Leaf 'Inverter'
|
||||
{
|
||||
start = function(node)
|
||||
node.children[1]:start()
|
||||
end,
|
||||
tick = function(node, ...)
|
||||
function(node, ...)
|
||||
local result = node.children[1]:update(...)
|
||||
|
||||
if type(result) == 'boolean' then return not result end
|
||||
if result ~= nil then return not result end
|
||||
end
|
||||
}
|
||||
|
||||
--[[
|
||||
Example usage
|
||||
-------------
|
||||
|
||||
Tactree.Leaf 'Find nearest object' { function (node) ... end }
|
||||
Tactree.Leaf 'Pick up object' { function (node) ... end}
|
||||
Tactree.Leaf 'Move' { function (node) return node.data.creature:move(node.data.tx, node.data.ty, dt) end }
|
||||
Tactree.Composite 'Pick up nearest object' 'Sequence' { 'Find nearest object', 'Move', 'Pick up object' }
|
||||
|
||||
local tr = Tactree.Tree 'Pick up nearest object'
|
||||
|
||||
tr:start{ ... } ( or, if you already have a table, tr:start(existing_table) )
|
||||
|
||||
t:update()
|
||||
]]--
|
||||
|
||||
return Tactree
|
Loading…
Reference in New Issue
Block a user