Total rework
This commit is contained in:
parent
342168c6c6
commit
ebe76a64ce
156
init.lua
156
init.lua
@ -3,23 +3,25 @@ local Nodes = {}
|
|||||||
|
|
||||||
local function NodeStart(node, args)
|
local function NodeStart(node, args)
|
||||||
-- don't start again if started
|
-- don't start again if started
|
||||||
if node.data then return end
|
if node._started then return end
|
||||||
|
|
||||||
node.data = node.parent and node.parent.data or args
|
node.data = node.parent and node.parent.data or args or node.data
|
||||||
node.data[node] = node.data[node] or {}
|
node.data[node] = node.data[node] or {}
|
||||||
node:_start()
|
node:_start()
|
||||||
|
|
||||||
|
node._started = true
|
||||||
end
|
end
|
||||||
|
|
||||||
local function NodeUpdate(node)
|
local function NodeUpdate(node, ...)
|
||||||
-- don't tick if not started
|
-- automatically start if not started
|
||||||
if not node.data then return end
|
if not node._started then NodeStart(node) end
|
||||||
|
|
||||||
local result = node:_tick()
|
local result = node:_tick(...)
|
||||||
|
|
||||||
if type(result) == 'boolean' then
|
if type(result) == 'boolean' then
|
||||||
node:_finish()
|
node:_finish()
|
||||||
|
|
||||||
node.data = nil
|
node._started = false
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@ -72,8 +74,10 @@ function Tactree.Composite(name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Tactree.Tree(name)
|
local function tree_by_name(name, depth)
|
||||||
if not Nodes[name] then error('no such node \'' .. name .. '\'', 2) end
|
depth = depth or 2
|
||||||
|
|
||||||
|
if not Nodes[name] then error('no such node \'' .. name .. '\'', depth) end
|
||||||
|
|
||||||
local node = {}
|
local node = {}
|
||||||
node.children = {}
|
node.children = {}
|
||||||
@ -85,7 +89,7 @@ function Tactree.Tree(name)
|
|||||||
-- find a way to prevent this?
|
-- find a way to prevent this?
|
||||||
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 = Tactree.Tree(child)
|
local cn = tree_by_name(child, depth + 1)
|
||||||
cn.parent = node
|
cn.parent = node
|
||||||
table.insert(node.children, cn)
|
table.insert(node.children, cn)
|
||||||
end
|
end
|
||||||
@ -94,27 +98,59 @@ function Tactree.Tree(name)
|
|||||||
return setmetatable(node, { __index = Nodes[name], __tostring = function() return name end })
|
return setmetatable(node, { __index = Nodes[name], __tostring = function() return name end })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Tactree.Tree(name)
|
||||||
|
if not Nodes[name] then error('no such node \'' .. name .. '\'', 2) end
|
||||||
|
|
||||||
|
return function(children)
|
||||||
|
local node = {}
|
||||||
|
node.children = {}
|
||||||
|
node.start = NodeStart
|
||||||
|
node.update = NodeUpdate
|
||||||
|
node.private = NodePrivateData
|
||||||
|
|
||||||
|
-- add pre-defined children
|
||||||
|
if Nodes[name].children then
|
||||||
|
for _, child in ipairs(Nodes[name].children) do
|
||||||
|
local cn = tree_by_name(child, 3)
|
||||||
|
cn.parent = node
|
||||||
|
table.insert(node.children, cn)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- add extra children from call
|
||||||
|
for _, child in ipairs(children) do
|
||||||
|
local cn
|
||||||
|
if type(child) == 'string' then
|
||||||
|
cn = tree_by_name(child, 3)
|
||||||
|
elseif type(child) == 'table' then
|
||||||
|
cn = child
|
||||||
|
else
|
||||||
|
error('invalid child type: \'' .. type(child) '\'', 3)
|
||||||
|
end
|
||||||
|
|
||||||
|
cn.parent = node
|
||||||
|
table.insert(node.children, cn)
|
||||||
|
end
|
||||||
|
|
||||||
|
return setmetatable(node, { __index = Nodes[name], __tostring = function() return name end })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
Tactree.Leaf 'Sequence'
|
Tactree.Leaf 'Sequence'
|
||||||
{
|
{
|
||||||
start = function(node)
|
start = function(node)
|
||||||
node:private().current_child = 1
|
node:private().current_child = 1
|
||||||
node.children[node:private().current_child]:start()
|
|
||||||
end,
|
end,
|
||||||
tick = function(node)
|
tick = function(node, ...)
|
||||||
local result = node.children[node:private().current_child]:update()
|
local result
|
||||||
|
repeat
|
||||||
if type(result) == 'boolean' then
|
result = node.children[node:private().current_child]:update(...)
|
||||||
if result then
|
if result then
|
||||||
if node:private().current_child == #node.children then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
node:private().current_child = node:private().current_child + 1
|
node:private().current_child = node:private().current_child + 1
|
||||||
node.children[node:private().current_child]:start()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
until (not result) or (node:private().current_child > #node.children)
|
||||||
|
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,23 +158,17 @@ Tactree.Leaf 'Selector'
|
|||||||
{
|
{
|
||||||
start = function(node)
|
start = function(node)
|
||||||
node:private().current_child = 1
|
node:private().current_child = 1
|
||||||
node.children[node:private().current_child]:start()
|
|
||||||
end,
|
end,
|
||||||
tick = function(node)
|
tick = function(node, ...)
|
||||||
local result = node.children[node:private().current_child]:update()
|
local result
|
||||||
|
repeat
|
||||||
if type(result) == 'boolean' then
|
result = node.children[node:private().current_child]:update(...)
|
||||||
if not result then
|
if result then
|
||||||
if node:private().current_child == #node.children then
|
|
||||||
return false
|
|
||||||
else
|
|
||||||
node:private().current_child = node:private().current_child + 1
|
node:private().current_child = node:private().current_child + 1
|
||||||
node.children[node:private().current_child]:start()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
until (result ~= false) or (node:private().current_child > #node.children)
|
||||||
|
|
||||||
|
return result
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,61 +177,13 @@ Tactree.Leaf 'Inverter'
|
|||||||
start = function(node)
|
start = function(node)
|
||||||
node.children[1]:start()
|
node.children[1]:start()
|
||||||
end,
|
end,
|
||||||
tick = function(node)
|
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 type(result) == 'boolean' then return not result end
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
Tactree.Leaf 'RepeatUntilFail'
|
|
||||||
{
|
|
||||||
start = function(node)
|
|
||||||
node.children[1]:start()
|
|
||||||
end,
|
|
||||||
tick = function(node)
|
|
||||||
local result = node.children[1]:update()
|
|
||||||
|
|
||||||
if type(result) == 'boolean' then
|
|
||||||
if not result then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
node.children[1]:start()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
Tactree.Leaf 'RepeatUntilPass'
|
|
||||||
{
|
|
||||||
start = function(node)
|
|
||||||
node.children[1]:start()
|
|
||||||
end,
|
|
||||||
tick = function(node)
|
|
||||||
local result = node.children[1]:update()
|
|
||||||
|
|
||||||
if type(result) == 'boolean' then
|
|
||||||
if result then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
node.children[1]:start()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
Tactree.Leaf 'RepeatForever'
|
|
||||||
{
|
|
||||||
start = function(node)
|
|
||||||
node.children[1]:start()
|
|
||||||
end,
|
|
||||||
tick = function(node)
|
|
||||||
local result = node.children[1]:update()
|
|
||||||
|
|
||||||
if type(result) == 'boolean' then node.children[1]:start() end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
Example usage
|
Example usage
|
||||||
-------------
|
-------------
|
||||||
|
Loading…
Reference in New Issue
Block a user