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 Tactree = {}
|
||||||
local Nodes = {}
|
local Nodes = {}
|
||||||
|
|
||||||
|
local function NodeReset(node)
|
||||||
|
node:_finish()
|
||||||
|
node._started = false
|
||||||
|
end
|
||||||
|
|
||||||
local function NodeStart(node, args)
|
local function NodeStart(node, args)
|
||||||
-- don't start again if started
|
-- don't start again if started
|
||||||
if node._started then return end
|
if node._started then return end
|
||||||
@ -14,14 +19,27 @@ end
|
|||||||
|
|
||||||
local function NodeUpdate(node, ...)
|
local function NodeUpdate(node, ...)
|
||||||
-- automatically start if not started
|
-- 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(...)
|
local result = node:_tick(...)
|
||||||
|
|
||||||
if type(result) == 'boolean' then
|
if result ~= nil then
|
||||||
node:_finish()
|
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
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -85,8 +103,8 @@ local function tree_by_name(name, depth)
|
|||||||
node.update = NodeUpdate
|
node.update = NodeUpdate
|
||||||
node.private = NodePrivateData
|
node.private = NodePrivateData
|
||||||
|
|
||||||
-- this will crash if there is a recursive structure
|
-- this will crash if there is a recursive structure; find a way to prevent this?
|
||||||
-- find a way to prevent this?
|
-- does my API even allow declaring recursive structures?
|
||||||
if Nodes[name].children then
|
if Nodes[name].children then
|
||||||
for _, child in ipairs(Nodes[name].children) do
|
for _, child in ipairs(Nodes[name].children) do
|
||||||
local cn = tree_by_name(child, depth + 1)
|
local cn = tree_by_name(child, depth + 1)
|
||||||
@ -137,6 +155,20 @@ function Tactree.Tree(name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
Tactree.Leaf 'Sequence'
|
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)
|
start = function(node)
|
||||||
node:private().current_child = 1
|
node:private().current_child = 1
|
||||||
@ -145,9 +177,7 @@ Tactree.Leaf 'Sequence'
|
|||||||
local result
|
local result
|
||||||
repeat
|
repeat
|
||||||
result = node.children[node:private().current_child]:update(...)
|
result = node.children[node:private().current_child]:update(...)
|
||||||
if result then
|
if result ~= nil then node:private().current_child = node:private().current_child + 1 end
|
||||||
node:private().current_child = node:private().current_child + 1
|
|
||||||
end
|
|
||||||
until (not result) or (node:private().current_child > #node.children)
|
until (not result) or (node:private().current_child > #node.children)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -155,6 +185,20 @@ Tactree.Leaf 'Sequence'
|
|||||||
}
|
}
|
||||||
|
|
||||||
Tactree.Leaf 'Selector'
|
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)
|
start = function(node)
|
||||||
node:private().current_child = 1
|
node:private().current_child = 1
|
||||||
@ -163,9 +207,7 @@ Tactree.Leaf 'Selector'
|
|||||||
local result
|
local result
|
||||||
repeat
|
repeat
|
||||||
result = node.children[node:private().current_child]:update(...)
|
result = node.children[node:private().current_child]:update(...)
|
||||||
if result == false then
|
if result ~= nil then node:private().current_child = node:private().current_child + 1 end
|
||||||
node:private().current_child = node:private().current_child + 1
|
|
||||||
end
|
|
||||||
until (result ~= false) or (node:private().current_child > #node.children)
|
until (result ~= false) or (node:private().current_child > #node.children)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -174,30 +216,11 @@ Tactree.Leaf 'Selector'
|
|||||||
|
|
||||||
Tactree.Leaf 'Inverter'
|
Tactree.Leaf 'Inverter'
|
||||||
{
|
{
|
||||||
start = function(node)
|
function(node, ...)
|
||||||
node.children[1]:start()
|
|
||||||
end,
|
|
||||||
tick = function(node, ...)
|
|
||||||
local result = node.children[1]:update(...)
|
local result = node.children[1]:update(...)
|
||||||
|
|
||||||
if type(result) == 'boolean' then return not result end
|
if result ~= nil then return not result end
|
||||||
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
|
return Tactree
|
Loading…
Reference in New Issue
Block a user