1
0
Fork 0
mirror of https://github.com/Oreolek/ink-instead.git synced 2024-04-28 15:19:25 +03:00
ink-instead/pink/runtime.lua
2016-12-31 00:27:11 +01:00

121 lines
2.4 KiB
Lua

local is = function (what, node)
return node ~= nil
and (type(node) == "table" and node[1] == what)
or (type(node) == "string" and node == what)
end
local getPara = function (node)
if is('para', node) then return node[2] end
end
return function (tree)
--print(to_string(tree))
local s = {}
local pointer = nil
local tab = {}
local knots = {}
-- TODO state should contain tab/pointer to be able to save / load
s.state = {
visitCount = {}
}
local process = function ()
for _, v in ipairs(tree) do
if is('knot', v) then
knots[v[2]] = v
end
end
end
local goToKnot = function(knotName)
if knots[knotName] then
s.state.visitCount[knotName] = (s.state.visitCount[knotName] or 0) + 1
tab = knots[knotName]
pointer = 3
return tab[pointer]
else
print('unknown knot', knotName)
end
end
local update = function ()
local next = tab[pointer]
if is('knot', next) then -- FIXME: we shouldn't continue to next knot automatically probably - how about stitches?
next = goToKnot(next)
end
if is('divert', next) then next = goToKnot(next[2]) end
s.canContinue = is('para', next)
s.currentChoices = {}
if is('choice', next) then
for i=2, #next do
--print(to_string(next[i]))
table.insert(s.currentChoices, {
text = (next[i][2] or '') .. (next[i][3] or ''),
choiceText = next[i][2] .. (next[i][4] or ''),
})
end
end
end
local step = function ()
pointer = pointer + 1
update()
return tab[pointer]
end
local stepTo = function (table, pos)
tab = table
pointer = pos
update()
return tab[pointer]
end
s.canContinue = nil
s.continue = function()
local res = getPara(tab[pointer])
local next = step()
if is('glue', next) then
step()
res = res .. s.continue()
end
return res;
end
s.currentChoices = nil
s.chooseChoiceIndex = function(index)
s.currentChoices = {}
local choice = tab[pointer]
local option = choice[1 + index]
stepTo(option, 5)
end
s.choosePathString = function(knotName)
goToKnot(knotName)
update()
end
s.state.visitCountAtPathString = function(knotName)
return s.state.visitCount[knotName] or 0
end
s.variablesState = {}
-- s.state.ToJson();s.state.LoadJson(savedJson);
stepTo(tree, 1)
process()
return s
end