Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --PACKAGE_MODE=EXTRACTING
- local path=...or".nightfall"
- local files={["bundles"]={["Process.lua"]="local e={}local t={}local a={}local o local i local n=\"process\"\
- e[1]={name=\"main\",mode='api',content=\"local e={}local t={}local a={}\\\
- function a.create(o)local i={}i.name=tostring(o)\\\
- i.environment=setmetatable({},{__index=getfenv(2)})i.threads={}\\\
- function i:newThread(n)\\\
- local s=a.newThread(n,setmetatable({},{__index=function(h,r)return self.environment[r]end,__newindex=function(h,r,d)\\\
- self.environment[r]=d end}))table.insert(self.threads,s)return s end function i:stop()\\\
- for i=1,#self.threads do self.threads[i]:stop()end\\\
- for i=1,#e do if e[i]==self then table.remove(e,i)break end end end\\\
- table.insert(e,i)return i end\\\
- function a.newThread(o,i)i=i or getfenv(2)local n={}setfenv(o,i)\\\
- n.co=coroutine.create(o)\\\
- function n:resume(...)local s,h=coroutine.resume(self.co,...)\\\
- if not s then\\\
- if\\\
- type(self.onException)==\\\"function\\\"then self:onException(h)end self:stop()elseif coroutine.status(self.co)==\\\"dead\\\"then if\\\
- type(self.onFinish)==\\\"function\\\"then self:onFinish(h)end\\\
- self:stop()end end function n:stop()\\\
- for i=#t,1,-1 do if t[i]==self then table.remove(t,i)break end end end table.insert(t,n)return n end function a.resume(...)local o={}for i=1,#t do o[i]=t[i]end\\\
- for i=1,#o do if not o[i]then print(\\\"oh noes\\\")end o[i]:resume(...)\\\
- end end function a.list()local o={}for i=1,#e do\\\
- o[#o+1]=e[i]end return o end\\\
- setmetatable(a,{__call=function(o,i)\\\
- if\\\
- type(i)==\\\"function\\\"then return o.newThread(i)else return o.create(i)end end})return a\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["SUtils.lua"]="local e={}local t={}local a={}local o local i local n=\"SUtils\"\
- e[1]={name=\"main\",mode='api',content=\"\\\
- function gfind(t,a,o)local n={}local s={t:find(a,o)}while s[1]do table.insert(n,s)\\\
- s={t:find(a,s[2]+1)}end local h=0 return function()h=h+1\\\
- if n[h]then return unpack(n[h])end end end function split(t,a,o)local i=1 local n={}for h,r in gfind(t,a,o)do table.insert(n,t:sub(i,h-1))\\\
- i=r+1 end table.insert(n,t:sub(i))\\\
- return n end\\\
- local function e(t,a)\\\
- local o=0 for i=1,a+1 do\\\
- o=o+ (t:sub(i,i)==\\\"\\\\t\\\"and 4 or 1)if o>a+1 then break end\\\
- if t:sub(i,i)==\\\"\\\\n\\\"then return t:sub(1,i),t:sub(i+1)end end if#\\\
- t:gsub(\\\"\\\\t\\\",\\\" \\\")<=a then return t,false end local i\\\
- for n,s in gfind(t,\\\"%s+\\\")do if#\\\
- t:sub(1,n):gsub(\\\"\\\\t\\\",\\\" \\\")>a+1 then break end i=s end if i then return t:sub(1,i),t:sub(i+1)end local o=0\\\
- for i=1,#t do o=o+ (\\\
- t:sub(i,i)==\\\"\\\\t\\\"and 4 or 1)if\\\
- o>a then\\\
- return t:sub(1,math.max(i-1,1)),t:sub(math.max(i-1,1)+1)end end end\\\
- function wordwrap(t,a,o,i,n,s)local h={}\\\
- if a then local r while t do r,t=e(t,a)table.insert(h,r)end else\\\
- h=split(t,\\\"\\\\n\\\")for i=1,#h-1 do h[i]=h[i]..\\\"\\\\n\\\"end end if o then while#h>o do table.remove(h,#h)end end\\\
- h.padding={}\\\
- if i then local r,o=i:match\\\"(%w+), ?(%w+)\\\"\\\
- if r then\\\
- if s and\\\
- (r==\\\"middle\\\"or r==\\\"centre\\\"or r==\\\"center\\\")then\\\
- h.padding.vertical=math.floor(s/2-#h/2)elseif s and r==\\\"bottom\\\"then h.padding.vertical=s-#h end\\\
- if n and\\\
- (o==\\\"middle\\\"or o==\\\"centre\\\"or o==\\\"center\\\")then for i=1,#h do\\\
- h.padding[i]=math.floor(n/2-#h[i]/2)end elseif n and o==\\\"right\\\"then for i=1,#h do\\\
- h.padding[i]=n-#h[i]end else for i=1,#h do h.padding[i]=0 end end end end return h end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["Math2D.lua"]="local files={}\
- local dependencies={}\
- local requires={}\
- local mainContent\
- local apiCount\
- local name=\"Math2D\"\
- files[1]={name=\"collision\";mode='api';content=\"\\\
- local function numeq( a, b )\\\
- return math.abs( a - b ) < 0.0000001\\\
- end\\\
- \\\
- function pointInLine( lp1, lp2, point )\\\
- if point.x < math.min( lp1.x, lp2.x ) or point.x > math.max( lp1.x, lp2.x ) then\\\
- return false\\\
- end\\\
- if point.y < math.min( lp1.y, lp2.y ) or point.y > math.max( lp1.y, lp2.y ) then\\\
- return false\\\
- end\\\
- \\\
- local delta = lp2 - lp1\\\
- local m = delta.y / delta.x\\\
- local c = lp1.y - m * lp1.x\\\
- \\\
- if delta.y == 0 or delta.x == 0 then\\\
- return true\\\
- end\\\
- \\\
- if numeq( m * point.x + c, point.y ) then\\\
- return true\\\
- end\\\
- return false\\\
- end\\\
- \\\
- function pointInBox( point, position, size ) -- Vec2 point, Vec2 position, Vec2 size\\\
- if point.x >= position.x\\\
- and point.y >= position.y\\\
- and point.x <= position.x + size.x - 1\\\
- and point.y <= position.y + size.y - 1 then\\\
- return Vec2( point.x - position.x + 1, point.y - position.y + 1 )\\\
- end\\\
- return false\\\
- end\\\
- -- Vec2 relative_coords\\\
- \\\
- function boxInBox( p1, s1, p2, s2 ) -- Vec2 position1, Vec2 size1, Vec2 position2, Vec2 size2\\\
- if p1.x > p2.x + s2.x - 1 or p1.y > p2.y + s2.y - 1 then\\\
- return false\\\
- end\\\
- if p2.x > p1.x + s1.x - 1 or p2.y > p1.y + s1.y - 1 then\\\
- return false\\\
- end\\\
- local x, y = math.max( p1.x, p2.x ), math.max( p1.y, p2.y )\\\
- local x2, y2 = math.min( p1.x + s1.x, p2.x + s2.x ) - 1, math.min( p1.y + s1.y, p2.y + s2.y ) - 1\\\
- \\\
- return Vec2( x, y ), Vec2( x2 - x, y2 - y )\\\
- end\\\
- -- false if no collision\\\
- -- Vec2 position, Vec2 size if collision\\\
- \\\
- function lineIntersect( l1p1, l1p2, l2p1, l2p2 ) -- Vec2 line_1_point_1, Vec2 line_1_point_2, Vec2 line_2_point_1, Vec2 line_2_point_2\\\
- local l1d = l1p1 - l1p2\\\
- local l2d = l2p1 - l2p2\\\
- \\\
- local l1m = l1d.y / l1d.x\\\
- local l2m = l2d.y / l2d.x\\\
- \\\
- local l1c = l1p1.y - l1m * l1p1.x\\\
- local l2c = l2p1.y - l2m * l2p1.x\\\
- \\\
- if l1m == l2m then\\\
- return l1c == l2c\\\
- end\\\
- \\\
- local ix = ( l1c - l2c ) / ( l2m - l1m )\\\
- \\\
- if ix < math.min( l1p1.x, l1p2.x ) or ix > math.max( l1p1.x, l1p2.x ) then\\\
- return false\\\
- end \\\
- if ix < math.min( l2p1.x, l2p2.x ) or ix > math.max( l2p1.x, l2p2.x ) then\\\
- return false\\\
- end\\\
- \\\
- local iy = l1m * l1p1.x + l1c\\\
- \\\
- return Vec2( ix, iy )\\\
- end\\\
- -- false if no intersection\\\
- -- true if equal lines\\\
- -- Vec2 point if single intersection\\\
- \\\
- function circleInCircle( p1, r1, p2, r2 ) -- Vec2 position1, number radius1, Vec2 position2, number radius2\\\
- local delta = p2 - p1\\\
- return delta.x ^ 2 + delta.y ^ 2 <= ( r1 + r2 ) ^ 2\\\
- end\\\
- -- bool collision\\\
- \\\
- function pointInCircle( c, r, p ) -- Vec2 circlePosition, number radius, Vec2 point\\\
- local delta = p - c\\\
- return delta.x ^ 2 + delta.y ^ 2 <= r ^ 2\\\
- end\\\
- -- bool collision\"}\
- files[2]={name=\"normal\";mode='api';content=\"\\\
- return function( p1, p2, p3 ) -- line_point_1, line_point_2, normal_point\\\
- local delta = p2 - p1\\\
- local m = -1 / ( delta.y / delta.y )\\\
- local c = p3.y - m * p3.x\\\
- \\\
- return Vec2( 1, ( m * ( p3.x + 1 ) + c ) - p3.y )\\\
- end\\\
- -- Vec2 normal\"}\
- files[3]={name=\"pointOnLine\";mode='api';content=\"\\\
- return function( p1, p2, x, y )\\\
- local delta = p2 - p1\\\
- \\\
- if x then\\\
- if delta.x == 0 then\\\
- if x == p1.x then\\\
- return Vec2( x, p1.y )\\\
- end\\\
- return false\\\
- elseif delta.y == 0 then\\\
- return Vec2( x, p1.y )\\\
- end\\\
- local m = delta.y / delta.x\\\
- local c = p1.y - m * p1.x\\\
- return Vec2( x, m * x + c )\\\
- elseif y then\\\
- if delta.x == 0 then\\\
- return Vec2( p1.x, y )\\\
- elseif delta.y == 0 then\\\
- if y == p1.y then\\\
- return Vec2( p1.x, y )\\\
- end\\\
- return false\\\
- end\\\
- local m = delta.y / delta.x\\\
- local c = p1.y - m * p1.x\\\
- return Vec2( ( y - c ) / m, y )\\\
- end\\\
- end\"}\
- files[4]={name=\"Vec2\";mode='api';content=\"\\\
- local Vec2 = Class \\\"Vec2\\\"\\\
- \\\
- Vec2.public \\\"x\\\" \\\"number\\\"\\\
- Vec2.public \\\"y\\\" \\\"number\\\"\\\
- \\\
- function Vec2:Vec2( x, y )\\\
- if type( x ) == \\\"number\\\" and type( y ) == \\\"number\\\" then\\\
- self.x, self.y = x, y\\\
- else\\\
- self.x, self.y = 0, 0\\\
- end\\\
- return self.public\\\
- end\\\
- \\\
- function Vec2.public:add( other )\\\
- return Vec2( self.x + other.x, self.y + other.y )\\\
- end\\\
- function Vec2.public:sub( other )\\\
- return Vec2( self.x - other.x, self.y - other.y )\\\
- end\\\
- \\\
- function Vec2.public:mul( other )\\\
- return Vec2( self.x * other, self.y * other )\\\
- end\\\
- function Vec2.public:div( other )\\\
- return Vec2( self.x / other, self.y / other )\\\
- end\\\
- \\\
- function Vec2.public:dot( other )\\\
- return self.x * other.x + self.y * other.y\\\
- end\\\
- \\\
- function Vec2.public:length()\\\
- return math.sqrt( self.x ^ 2 + self.y ^ 2 )\\\
- end\\\
- \\\
- function Vec2.public:normalise()\\\
- return self.public / self.public:length()\\\
- end\\\
- \\\
- function Vec2.meta:add( other )\\\
- return self:add( other )\\\
- end\\\
- function Vec2.meta:sub( other )\\\
- return self:sub( other )\\\
- end\\\
- function Vec2.meta:mul( other )\\\
- return self:mul( other )\\\
- end\\\
- function Vec2.meta:div( other )\\\
- return self:div( other )\\\
- end\\\
- \\\
- function Vec2.meta:tostring( )\\\
- return \\\"Vec2(\\\" .. self.x .. \\\", \\\" .. self.y .. \\\")\\\"\\\
- end\\\
- \\\
- return Vec2\"}\
- apiCount=4\
- dependencies[1]=\"Class.lua\"\
- local env = setmetatable( {}, { __index = getfenv() } )\
- env.global = env\
- env.args = { ... }\
- local public = {}\
- local bloaded = _G[\"_bundleLoaded\"]\
- if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
- \
- if bloaded[name] and not mainContent then\
- return bloaded[name]\
- end\
- \
- for i = 1, #dependencies do\
- if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- else\
- error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
- end\
- end\
- end\
- for i = 1, #requires do\
- if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- end\
- end\
- end\
- \
- for i = 1, #files do\
- local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
- if f then\
- local e = setmetatable( {}, { __index = env } )\
- setfenv( f, e )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- break\
- end\
- if data == nil then\
- data = {}\
- for k, v in pairs( e ) do\
- data[k] = v\
- end\
- end\
- if files[i].mode == \"api\" then\
- if apiCount == 1 then\
- public = data\
- else\
- public[files[i].name] = data\
- env[files[i].name] = data\
- end\
- else\
- env[files[i].name] = data\
- end\
- else\
- printError( err )\
- break\
- end\
- end\
- \
- if mainContent then\
- local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
- if f then\
- setfenv( f, env )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- end\
- else\
- printError( err )\
- end\
- end\
- \
- bloaded[name] = public\
- return public";["Traceback.lua"]="local e={}local t={}local a={}local o local i local n=\"Traceback\"\
- e[1]={name=\"main\",mode='api',content=\"\\\
- return\\\
- function(e,t)t=type(t)==\\\"number\\\"and t local a=3+\\\
- (type(e)==\\\"number\\\"and e or 0)local o=a local i,n=nil,{}\\\
- repeat\\\
- i=select(2,pcall(error,\\\"@\\\",a)):match(\\\"^(.+): @$\\\")if i then n[#n+1]=i a=a+1 if a-o==t then return n end end until not i return n end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["Tween.lua"]="local e={}local t={}local a={}local o local i local n=\"Tween\"\
- e[1]={name=\"main\",mode='api',content=\"\\\
- local e={_VERSION='tween 2.0.0',_DESCRIPTION='tweening for lua',_URL='https://github.com/kikito/tween.lua',_LICENSE=[[\\\
- MIT LICENSE\\\
- Copyright (c) 2014 Enrique García Cota, Yuichi Tateno, Emmanuel Oga\\\
- Permission is hereby granted, free of charge, to any person obtaining a\\\
- copy of this software and associated documentation files (the\\\
- \\\"Software\\\"), to deal in the Software without restriction, including\\\
- without limitation the rights to use, copy, modify, merge, publish,\\\
- distribute, sublicense, and/or sell copies of the Software, and to\\\
- permit persons to whom the Software is furnished to do so, subject to\\\
- the following conditions:\\\
- The above copyright notice and this permission notice shall be included\\\
- in all copies or substantial portions of the Software.\\\
- THE SOFTWARE IS PROVIDED \\\"AS IS\\\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\\\
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\\\
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\\\
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\\\
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\\\
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\\\
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\\\
- ]]}\\\
- local t,a,o,i,n,s,h=math.pow,math.sin,math.cos,math.pi,math.sqrt,math.abs,math.asin local function r(ei,en,es,eh)return es*ei/eh+en end local function d(ei,en,es,eh)return\\\
- es*t(ei/eh,2)+en end local function l(ei,en,es,eh)ei=ei/eh return\\\
- -es*ei* (ei-2)+en end\\\
- local function u(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return\\\
- es/2*t(ei,2)+en end return-es/2*\\\
- ((ei-1)* (ei-3)-1)+en end\\\
- local function c(ei,en,es,eh)if ei<eh/2 then return l(ei*2,en,es/2,eh)end return d((ei*2)-eh,en+\\\
- es/2,es/2,eh)end local function m(ei,en,es,eh)return es*t(ei/eh,3)+en end\\\
- local function f(ei,en,es,eh)return es* (\\\
- t(ei/eh-1,3)+1)+en end\\\
- local function w(ei,en,es,eh)ei=ei/eh*2\\\
- if ei<1 then return es/2*ei*ei*ei+en end ei=ei-2 return es/2* (ei*ei*ei+2)+en end\\\
- local function y(ei,en,es,eh)if ei<eh/2 then return f(ei*2,en,es/2,eh)end return m((ei*2)-eh,en+\\\
- es/2,es/2,eh)end local function p(ei,en,es,eh)return es*t(ei/eh,4)+en end\\\
- local function v(ei,en,es,eh)return-es* (\\\
- t(ei/eh-1,4)-1)+en end\\\
- local function b(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return es/2*t(ei,4)+en end return\\\
- -es/2* (t(ei-2,4)-2)+en end\\\
- local function g(ei,en,es,eh)if ei<eh/2 then return v(ei*2,en,es/2,eh)end return p((ei*2)-eh,en+\\\
- es/2,es/2,eh)end local function k(ei,en,es,eh)return es*t(ei/eh,5)+en end\\\
- local function q(ei,en,es,eh)return es* (\\\
- t(ei/eh-1,5)+1)+en end\\\
- local function j(ei,en,es,eh)ei=ei/eh*2 if ei<1 then return es/2*t(ei,5)+en end return\\\
- es/2* (t(ei-2,5)+2)+en end\\\
- local function x(ei,en,es,eh)if ei<eh/2 then return q(ei*2,en,es/2,eh)end return k((ei*2)-eh,en+\\\
- es/2,es/2,eh)end local function z(ei,en,es,eh)\\\
- return-es*o(ei/eh* (i/2))+es+en end local function _(ei,en,es,eh)return\\\
- es*a(ei/eh* (i/2))+en end local function E(ei,en,es,eh)return-es/2*\\\
- (o(i*ei/eh)-1)+en end local function T(ei,en,es,eh)if\\\
- ei<eh/2 then return _(ei*2,en,es/2,eh)end return\\\
- z((ei*2)-eh,en+es/2,es/2,eh)end\\\
- local function A(ei,en,es,eh)if\\\
- ei==0 then return en end return es*t(2,10* (ei/eh-1))+en-es*\\\
- 0.001 end\\\
- local function O(ei,en,es,eh)if ei==eh then return en+es end return es*1.001*\\\
- (-t(2,-10*ei/eh)+1)+en end\\\
- local function I(ei,en,es,eh)if ei==0 then return en end if ei==eh then return en+es end ei=ei/eh*2 if ei<1 then\\\
- return\\\
- es/2*t(2,10* (ei-1))+en-es*0.0005 end return es/2*1.0005*\\\
- (-t(2,-10* (ei-1))+2)+en end\\\
- local function N(ei,en,es,eh)if ei<eh/2 then return O(ei*2,en,es/2,eh)end return A((ei*2)-eh,en+\\\
- es/2,es/2,eh)end local function S(ei,en,es,eh)return\\\
- (-es* (n(1-t(ei/eh,2))-1)+en)end\\\
- local function H(ei,en,es,eh)return(es*\\\
- n(1-t(ei/eh-1,2))+en)end\\\
- local function R(ei,en,es,eh)ei=ei/eh*2 if ei<1 then\\\
- return-es/2* (n(1-ei*ei)-1)+en end ei=ei-2 return\\\
- es/2* (n(1-ei*ei)+1)+en end\\\
- local function D(ei,en,es,eh)if ei<eh/2 then return H(ei*2,en,es/2,eh)end return S((ei*2)-eh,en+\\\
- es/2,es/2,eh)end\\\
- local function L(ei,en,es,eh)ei,en=ei or eh*0.3,en or 0 if en<s(es)then return ei,es,ei/4 end return ei,\\\
- en,ei/ (2*i)*h(es/en)end\\\
- local function U(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh if ei==1 then return en+es end\\\
- ed,er,el=L(ed,er,es,eh)ei=ei-1 return\\\
- - (er*t(2,10*ei)*\\\
- a((ei*eh-el)* (2*i)/ed))+en end\\\
- local function C(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh if ei==1 then return en+es end\\\
- ed,er,el=L(ed,er,es,eh)return\\\
- er*t(2,-10*ei)*a((ei*eh-el)* (2*i)/ed)+es+en end\\\
- local function M(ei,en,es,eh,er,ed)local el if ei==0 then return en end ei=ei/eh*2 if ei==2 then return en+es end\\\
- ed,er,el=L(ed,er,es,eh)ei=ei-1 if ei<0 then return\\\
- -0.5* (er*t(2,10*ei)*\\\
- a((ei*eh-el)* (2*i)/ed))+en end\\\
- return\\\
- er*\\\
- t(2,-10*ei)*a((ei*eh-el)* (2*i)/ed)*0.5+es+en end\\\
- local function F(ei,en,es,eh,er,ed)if ei<eh/2 then return C(ei*2,en,es/2,eh,er,ed)end return U(\\\
- (ei*2)-eh,en+es/2,es/2,eh,er,ed)end\\\
- local function W(ei,en,es,eh,er)er=er or 1.70158 ei=ei/eh return\\\
- es*ei*ei* ((er+1)*ei-er)+en end local function Y(ei,en,es,eh,er)er=er or 1.70158 ei=ei/eh-1\\\
- return es* (\\\
- ei*ei* ((er+1)*ei+er)+1)+en end\\\
- local function P(ei,en,es,eh,er)\\\
- er=(er or 1.70158)*1.525 ei=ei/eh*2 if ei<1 then return\\\
- es/2* (ei*ei* ((er+1)*ei-er))+en end ei=ei-2 return\\\
- \\\
- es/2* (ei*ei* ((er+1)*ei+er)+2)+en end\\\
- local function V(ei,en,es,eh,er)if ei<eh/2 then return Y(ei*2,en,es/2,eh,er)end return W((ei*2)-eh,\\\
- en+es/2,es/2,eh,er)end\\\
- local function B(ei,en,es,eh)ei=ei/eh if ei<1/2.75 then\\\
- return es* (7.5625*ei*ei)+en end\\\
- if ei<2/2.75 then ei=ei- (1.5/2.75)return es* (\\\
- 7.5625*ei*ei+0.75)+en elseif ei<2.5/\\\
- 2.75 then ei=ei- (2.25/2.75)return es*\\\
- (7.5625*ei*ei+0.9375)+en end ei=ei- (2.625/2.75)return es*\\\
- (7.5625*ei*ei+0.984375)+en end\\\
- local function G(ei,en,es,eh)return es-B(eh-ei,0,es,eh)+en end local function K(ei,en,es,eh)\\\
- if ei<eh/2 then return G(ei*2,0,es,eh)*0.5+en end\\\
- return B(ei*2-eh,0,es,eh)*0.5+es*.5+en end local function Q(ei,en,es,eh)if ei<eh/2 then return B(ei*2,en,es/\\\
- 2,eh)end return\\\
- G((ei*2)-eh,en+es/2,es/2,eh)end\\\
- e.easing={linear=r,inQuad=d,outQuad=l,inOutQuad=u,outInQuad=c,inCubic=m,outCubic=f,inOutCubic=w,outInCubic=y,inQuart=p,outQuart=v,inOutQuart=b,outInQuart=g,inQuint=k,outQuint=q,inOutQuint=j,outInQuint=x,inSine=z,outSine=_,inOutSine=E,outInSine=T,inExpo=A,outExpo=O,inOutExpo=I,outInExpo=N,inCirc=S,outCirc=H,inOutCirc=R,outInCirc=D,inElastic=U,outElastic=C,inOutElastic=M,outInElastic=F,inBack=W,outBack=Y,inOutBack=P,outInBack=V,inBounce=G,outBounce=B,inOutBounce=K,outInBounce=Q}\\\
- local function J(ei,en,es)es=es or en local eh=getmetatable(en)if\\\
- eh and getmetatable(ei)==nil then setmetatable(ei,eh)end for er,ed in pairs(en)do\\\
- if\\\
- type(ed)=='table'then ei[er]=J({},ed,es[er])else ei[er]=es[er]end end return ei end\\\
- local function X(ei,en,es)es=es or{}local eh,er\\\
- for ed,el in pairs(en)do eh,er=type(el),J({},es)\\\
- table.insert(er,tostring(ed))\\\
- if eh=='number'then\\\
- assert(type(ei[ed])=='number',\\\"Parameter '\\\"..table.concat(er,'/')..\\\
- \\\"' is missing from subject or isn't a number\\\")elseif eh=='table'then X(ei[ed],el,er)else\\\
- assert(eh=='number',\\\"Parameter '\\\"..table.concat(er,'/')..\\\
- \\\"' must be a number or table of numbers\\\")end end end\\\
- local function Z(ei,en,es,eh)\\\
- assert(type(ei)=='number'and ei>0,\\\"duration must be a positive number. Was \\\"..tostring(ei))local er=type(en)\\\
- assert(er=='table'or er=='userdata',\\\
- \\\"subject must be a table or userdata. Was \\\"..tostring(en))\\\
- assert(type(es)=='table',\\\"target must be a table. Was \\\"..tostring(es))\\\
- assert(type(eh)=='function',\\\"easing must be a function. Was \\\"..tostring(eh))X(en,es)end\\\
- local function ee(ei)ei=ei or\\\"linear\\\"\\\
- if type(ei)=='string'then local en=ei ei=e.easing[en]if type(ei)~=\\\
- 'function'then\\\
- error(\\\"The easing function name '\\\"..en..\\\"' is invalid\\\")end end return ei end\\\
- local function et(ei,en,es,eh,er,ed,el)local eu,ec,em,ef\\\
- for ew,ey in pairs(en)do\\\
- if type(ey)=='table'then\\\
- et(ei[ew],ey,es[ew],eh,er,ed)else eu,ec,em,ef=eh,es[ew],ey-es[ew],er if el then\\\
- ei[ew]=math.floor(ed(eu,ec,em,ef)+0.5)else ei[ew]=ed(eu,ec,em,ef)end end end end local ea={}local eo={__index=ea}\\\
- function ea:set(ei)\\\
- assert(type(ei)=='number',\\\"clock must be a positive number or 0\\\")self.clock=ei\\\
- if self.clock<=0 then self.clock=0\\\
- J(self.subject,self.initial)elseif self.clock>=self.duration then self.clock=self.duration\\\
- J(self.subject,self.target)else\\\
- et(self.subject,self.target,self.initial,self.clock,self.duration,self.easing,self.round)end return self.clock>=self.duration end function ea:reset()return self:set(0)end\\\
- function ea:update(ei)\\\
- assert(type(ei)=='number',\\\"dt must be a number\\\")return self:set(self.clock+ei)end\\\
- function e.new(ei,en,es,eh)eh=ee(eh)Z(ei,en,es,eh)return\\\
- setmetatable({duration=ei,subject=en,target=es,easing=eh,initial=J({},es,en),clock=0},eo)end return e\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["Peripheral.lua"]="local e={}local t={}local a={}local o local i local n=\"Peripheral\"\
- e[1]={name=\"main\",mode='api',content=\"local e={}\\\
- function connect(t)if e[t]then return e[t].driver end\\\
- local a=peripheral.wrap(t)e[t]={driver=a,type=peripheral.getType(t)}return a end function getType(t)if e[t]then return e[t].type end local a=peripheral.wrap(t)\\\
- e[t]={driver=a,type=peripheral.getType(t)}return a end function disconnect(t)e[t]=\\\
- nil end\\\
- function connectVirtual(t,a,o)e[t]={driver=o,type=a}end\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["SFormat.lua"]="local files={}\
- local dependencies={}\
- local requires={}\
- local mainContent\
- local apiCount\
- local name=\"SFormat\"\
- files[1]={name=\"main\";mode='api';content=\"\\\
- local c = {\\\
- [\\\"0\\\"] = colours.white;\\\
- [\\\"1\\\"] = colours.orange;\\\
- [\\\"2\\\"] = colours.magenta;\\\
- [\\\"3\\\"] = colours.lightBlue;\\\
- [\\\"4\\\"] = colours.yellow;\\\
- [\\\"5\\\"] = colours.lime;\\\
- [\\\"6\\\"] = colours.pink;\\\
- [\\\"7\\\"] = colours.grey;\\\
- [\\\"8\\\"] = colours.lightGrey;\\\
- [\\\"9\\\"] = colours.cyan;\\\
- [\\\"A\\\"] = colours.purple;\\\
- [\\\"B\\\"] = colours.blue;\\\
- [\\\"C\\\"] = colours.brown;\\\
- [\\\"D\\\"] = colours.green;\\\
- [\\\"E\\\"] = colours.red;\\\
- [\\\"F\\\"] = colours.black;\\\
- [\\\" \\\"] = 0;\\\
- }\\\
- \\\
- function format( str, syntax, bc, tc, noformat )\\\
- local colours = {}\\\
- for i = 1, #syntax do\\\
- for s, f in SUtils.gfind( str, syntax[i].pattern ) do\\\
- for p = s, f do\\\
- colours[p] = colours[p] or {}\\\
- colours[p].bc = syntax[i].bc or colours[p].bc\\\
- colours[p].tc = syntax[i].tc or colours[p].tc\\\
- end\\\
- end\\\
- end\\\
- local cstream = {}\\\
- if noformat then\\\
- for i = 1, #str do\\\
- colours[i] = colours[i] or {}\\\
- colours[i].bc = colours[i].bc or bc\\\
- colours[i].tc = colours[i].tc or tc\\\
- cstream[#cstream+1] = {\\\
- char = str:sub( i, i );\\\
- bc = colours[i].bc;\\\
- tc = colours[i].tc;\\\
- }\\\
- end\\\
- else\\\
- local escape, ignore = false, false\\\
- for i = 1, #str do\\\
- colours[i] = colours[i] or {}\\\
- colours[i].bc = colours[i].bc or bc\\\
- colours[i].tc = colours[i].tc or tc\\\
- if ignore then\\\
- ignore = false\\\
- escape = false\\\
- elseif not escape and str:sub( i, i ) == \\\"\\\\\\\\\\\" then\\\
- escape = true\\\
- elseif not escape and str:sub( i, i ) == \\\"&\\\" then\\\
- tc = c[str:sub( i + 1, i + 1 ):upper()] or 0\\\
- ignore = true\\\
- elseif not escape and str:sub( i, i ) == \\\"#\\\" then\\\
- bc = c[str:sub( i + 1, i + 1 ):upper()] or 0\\\
- ignore = true\\\
- else\\\
- cstream[#cstream+1] = {\\\
- char = str:sub( i, i );\\\
- bc = colours[i].bc;\\\
- tc = colours[i].tc;\\\
- }\\\
- escape = false\\\
- end\\\
- end\\\
- end\\\
- return cstream\\\
- end\\\
- \\\
- function wrapstream( stream, width, height, align, rw, rh )\\\
- local s = \\\"\\\"\\\
- for i = 1, #stream do\\\
- s = s .. stream[i].char\\\
- end\\\
- local t = {}\\\
- t.lines = SUtils.wordwrap( s, width, height, align, rw, rh )\\\
- local l, p = {}, 0\\\
- for line = 1, #t.lines do\\\
- l[line], p = p, p + #t.lines[line]\\\
- end\\\
- function t:getChar( line, char )\\\
- if l[line] and char <= #t.lines[line] then\\\
- return stream[char + l[line]]\\\
- end\\\
- end\\\
- return t\\\
- end\"}\
- apiCount=1\
- dependencies[1]=\"SUtils.lua\"\
- local env = setmetatable( {}, { __index = getfenv() } )\
- env.global = env\
- env.args = { ... }\
- local public = {}\
- local bloaded = _G[\"_bundleLoaded\"]\
- if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
- \
- if bloaded[name] and not mainContent then\
- return bloaded[name]\
- end\
- \
- for i = 1, #dependencies do\
- if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- else\
- error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
- end\
- end\
- end\
- for i = 1, #requires do\
- if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- end\
- end\
- end\
- \
- for i = 1, #files do\
- local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
- if f then\
- local e = setmetatable( {}, { __index = env } )\
- setfenv( f, e )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- break\
- end\
- if data == nil then\
- data = {}\
- for k, v in pairs( e ) do\
- data[k] = v\
- end\
- end\
- if files[i].mode == \"api\" then\
- if apiCount == 1 then\
- public = data\
- else\
- public[files[i].name] = data\
- env[files[i].name] = data\
- end\
- else\
- env[files[i].name] = data\
- end\
- else\
- printError( err )\
- break\
- end\
- end\
- \
- if mainContent then\
- local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
- if f then\
- setfenv( f, env )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- end\
- else\
- printError( err )\
- end\
- end\
- \
- bloaded[name] = public\
- return public";["UIKit.lua"]="local files={}\
- local dependencies={}\
- local requires={}\
- local mainContent\
- local apiCount\
- local name=\"UIKit\"\
- files[1]={name=\"Window\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local Window = Class \\\"Window\\\"\\\
- \\\
- Window.public \\\"x\\\" \\\"number\\\"\\\
- Window.public \\\"y\\\" \\\"number\\\"\\\
- Window.public \\\"width\\\"\\\
- Window.public \\\"height\\\"\\\
- \\\
- Window.public.width.write = false\\\
- Window.public.height.write = false\\\
- \\\
- Window.public \\\"onscreen_keyboard\\\" \\\"boolean\\\"\\\
- \\\
- Window.public \\\"displaymode\\\"\\\
- function Window.public.displaymode:write( value )\\\
- if value == \\\"fullscreen\\\" or value == \\\"maximised\\\" then\\\
- self.public:resize( value )\\\
- elseif value == \\\"minimised\\\" then\\\
- self.displaymode = \\\"maximised\\\"\\\
- elseif value == \\\"normal\\\" then\\\
- self.public:resize( self.width, self.height )\\\
- else\\\
- error( \\\"unknown displaymode (\\\" .. tostring( value ) .. \\\")\\\", 3 )\\\
- end\\\
- end\\\
- \\\
- function Window:Window( width, height, maxw, maxh, wm )\\\
- self.x = 1\\\
- self.y = 1\\\
- self.width = width\\\
- self.height = height\\\
- \\\
- self.wm = wm\\\
- \\\
- self.maxw = maxw\\\
- self.maxh = maxh\\\
- \\\
- self.lastx, self.lasty, self.lastt = 1, 1, nil\\\
- \\\
- self.displaymode = \\\"normal\\\" -- /fullscreen, minimised, maximised\\\
- self.onscreen_keyboard = false\\\
- \\\
- self.callbacks = {}\\\
- \\\
- self.elements = {}\\\
- self.focus = false\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function Window.public:newChild( element )\\\
- if Class.typeOf( element, UIElement ) then\\\
- table.insert( self.elements, element )\\\
- element.parent = self.public\\\
- return element\\\
- else\\\
- return error \\\"expected <UIElement> child\\\"\\\
- end\\\
- end\\\
- \\\
- function Window.public:removeChild( element )\\\
- if Class.typeOf( element, UIElement ) then\\\
- for i = 1, #self.elements do\\\
- if self.elements[i] == element then\\\
- element.parent = nil\\\
- table.remove( self.elements, i )\\\
- return\\\
- end\\\
- end\\\
- else\\\
- return error \\\"expected <UIElement> child\\\"\\\
- end\\\
- end\\\
- \\\
- function Window.public:remove()\\\
- self.wm:removeWindow( self.public )\\\
- end\\\
- \\\
- local function mt( t, x, y, scroll )\\\
- for i = #t, 1, -1 do\\\
- if x >= t[i].x and y >= t[i].y and x < t[i].x + t[i].width and y < t[i].y + t[i].height then\\\
- if t[i]:type() == \\\"UIFrame\\\" then\\\
- local _t, rx, ry = mt( t[i]:getChildren(), x - t[i].x + 1 - t[i].ox, y - t[i].y + 1 - t[i].oy, scroll )\\\
- if _t then\\\
- return _t, rx, ry\\\
- end\\\
- if scroll and t[i]:getContentHeight() > t[i].height then\\\
- return t[i], x, y\\\
- end\\\
- elseif scroll and t[i]:type() == \\\"UIText\\\" then\\\
- if t[i]:getContentHeight() > t[i].height then\\\
- return t[i], x - t[i].x + 1, y - t[i].y + 1\\\
- end\\\
- elseif not scroll then\\\
- return t[i], x - t[i].x + 1, y - t[i].y + 1\\\
- end\\\
- end\\\
- end\\\
- end\\\
- \\\
- function Window.public:click( x, y, button )\\\
- local t, rx, ry = mt( self.elements, x, y )\\\
- self.lastx, self.lasty = rx or x, ry or y\\\
- if t then\\\
- self.lastt = t\\\
- if self.focus ~= t then\\\
- if self.focus then\\\
- self.focus:onUnFocus()\\\
- end\\\
- if Class.typeOf( t, UIText ) or Class.typeOf( t, UIBuffer ) then\\\
- t:onFocus()\\\
- end\\\
- end\\\
- if Class.typeOf( t, UIText ) or Class.typeOf( t, UIBuffer ) then\\\
- self.focus = t\\\
- else\\\
- self.focus = nil\\\
- end\\\
- t:onClick( rx, ry, button )\\\
- else\\\
- self.focus = nil\\\
- self.lastt = nil\\\
- self.public:callback( \\\"onClick\\\", x, y, button )\\\
- end\\\
- end\\\
- \\\
- function Window.public:drag( x, y, button )\\\
- if self.lastt then\\\
- local p = self.lastt\\\
- while p:type() ~= \\\"Window\\\" do\\\
- x = x - p.x + 1\\\
- y = y - p.y + 1\\\
- if p:type() == \\\"UIFrame\\\" then\\\
- x = x - p.ox\\\
- y = y - p.oy\\\
- end\\\
- p = p.parent\\\
- if not p then break end\\\
- end\\\
- self.lastt:onDrag( x, y, button, self.lastx, self.lasty )\\\
- self.lastx, self.lasty = x, y\\\
- else\\\
- self.public:callback( \\\"onDrag\\\", x, y, button, x - self.lastx + 1, y - self.lasty + 1 )\\\
- self.lastx = x\\\
- self.lasty = y\\\
- end\\\
- end\\\
- \\\
- function Window.public:scroll( x, y, dir )\\\
- local t, rx, ry = mt( self.elements, x, y, true )\\\
- if t then\\\
- t:onScroll( rx, ry, dir )\\\
- else\\\
- self.public:callback( \\\"onScroll\\\", x, y, dir )\\\
- end\\\
- end\\\
- \\\
- function Window.public:write( text )\\\
- if self.focus then\\\
- self.focus:write( text )\\\
- else\\\
- self.public:callback( \\\"onTextInput\\\", text )\\\
- end\\\
- end\\\
- \\\
- function Window.public:key( key, last )\\\
- if self.focus then\\\
- self.focus:onKey( key, last )\\\
- else\\\
- self.public:callback( \\\"onKeyPress\\\", key )\\\
- end\\\
- end\\\
- \\\
- function Window.public:update( dt )\\\
- for i = #self.elements, 1, -1 do\\\
- self.elements[i]:update( dt )\\\
- end\\\
- end\\\
- \\\
- function Window.public:draw()\\\
- local l\\\
- if self.displaymode == \\\"normal\\\" then\\\
- l = Gfx2D.buffer.current():addStencil( self.x, self.y, self.width, self.height )\\\
- elseif self.displaymode == \\\"maximised\\\" then\\\
- l = Gfx2D.buffer.current():addStencil( 1, 1, self.maxw, self.maxh )\\\
- elseif self.displaymode == \\\"minimised\\\" then\\\
- return\\\
- end\\\
- for i = 1, #self.elements do\\\
- self.elements[i]:draw( self.x + self.elements[i].x - 1, self.y + self.elements[i].y - 1 )\\\
- end\\\
- if l then\\\
- Gfx2D.buffer.current():removeStencil( l )\\\
- end\\\
- end\\\
- \\\
- function Window.public:setFocus( element )\\\
- if not element or Class.typeOf( element, UIText ) or Class.typeOf( element, UIBuffer ) then\\\
- if self.focus ~= element then\\\
- if self.focus then\\\
- self.focus:onUnFocus()\\\
- end\\\
- self.focus = element\\\
- if element then\\\
- element:onFocus()\\\
- end\\\
- end\\\
- else\\\
- return error \\\"expected [<UIElement> element] or [nil]\\\"\\\
- end\\\
- end\\\
- \\\
- function Window.public:setCallback( name, callback )\\\
- if type( callback ) ~= \\\"function\\\" then\\\
- return error \\\"expected <function> callback\\\"\\\
- end\\\
- self.callbacks[name] = callback\\\
- end\\\
- \\\
- function Window.public:callback( name, ... )\\\
- if self.callbacks[name] then\\\
- return self.callbacks[name]( self.public, ... )\\\
- end\\\
- end\\\
- \\\
- function Window.public:resize( width, height )\\\
- if width == \\\"fullscreen\\\" then\\\
- self.displaymode = \\\"fullscreen\\\"\\\
- self.public:callback( \\\"onResize\\\", self.maxw, self.maxh )\\\
- elseif type( width ) == \\\"number\\\" and type( height ) == \\\"number\\\" then\\\
- self.width = width\\\
- self.height = height\\\
- self.public:callback( \\\"onResize\\\", width, height )\\\
- elseif width == \\\"maximised\\\" then\\\
- self.displaymode = \\\"maximised\\\"\\\
- self.public:callback( \\\"onResize\\\", self.maxw, self.maxh - 1 )\\\
- else\\\
- return error \\\"expected [<number> width, <number> height] or [\\\\\\\"fullscreen\\\\\\\"] or [\\\\\\\"maximised\\\\\\\"]\\\"\\\
- end\\\
- end\\\
- \\\
- return Window\"}\
- files[2]={name=\"WindowManager\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local WindowManager = Class \\\"WindowManager\\\"\\\
- \\\
- function WindowManager:WindowManager()\\\
- self.windows = {}\\\
- self.displays = {}\\\
- \\\
- self.windowfocus = false\\\
- \\\
- self.last_time = os.clock()\\\
- \\\
- local buffer = Gfx2D.buffer.current()\\\
- \\\
- self.displays.computer = {\\\
- redirects = { term.current() };\\\
- buffer = buffer;\\\
- width = buffer.pixels.width;\\\
- height = buffer.pixels.height;\\\
- windows = {};\\\
- ids = {}\\\
- }\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function WindowManager.public:newDisplay( name, id )\\\
- if name == \\\"computer\\\" then\\\
- return error \\\"cannot override computer display\\\"\\\
- end\\\
- local p = Peripheral.connect( id )\\\
- if p then\\\
- if Peripheral.getType( id ) ~= \\\"monitor\\\" then\\\
- return error \\\"could not connect to peripheral: invalid peripheral\\\"\\\
- end\\\
- self.displays[name] = {\\\
- ids = { id };\\\
- redirects = { p };\\\
- buffer = Gfx2D.buffer.create( p.getSize() );\\\
- width = p.getSize();\\\
- height = select( 2, p.getSize() );\\\
- windows = {};\\\
- }\\\
- else\\\
- return error \\\"could not connect to peripheral: peripheral not found\\\"\\\
- end\\\
- end\\\
- \\\
- function WindowManager.public:getDisplaySize( display )\\\
- if not self.displays[display] then\\\
- return error \\\"no such display\\\"\\\
- end\\\
- return self.displays[display].redirect.getSize()\\\
- end\\\
- \\\
- function WindowManager.public:mirrorDisplay( display, id )\\\
- if not self.displays[display] then\\\
- return error \\\"no such display\\\"\\\
- end\\\
- local p = Peripheral.connect( id )\\\
- if p then\\\
- if Peripheral.getType( id ) ~= \\\"monitor\\\" then\\\
- return error \\\"could not connect to peripheral: invalid peripheral\\\"\\\
- end\\\
- table.insert( self.displays[display].redirects, p )\\\
- table.insert( self.displays[display].ids, id )\\\
- self.displays[display].buffer.allchanged = true\\\
- else\\\
- return error \\\"could not connect to peripheral: peripheral not found\\\"\\\
- end\\\
- end\\\
- \\\
- function WindowManager.public:newWindow( display, width, height )\\\
- if not self.displays[display] then\\\
- return error \\\"no such display\\\"\\\
- end\\\
- local maxw, maxh = self.displays[display].width, self.displays[display].height\\\
- local window = Window( width, height, maxw, maxh, self.public )\\\
- window.x, window.y = math.ceil( maxw / 2 - width / 2 ) + 1, math.ceil( maxh / 2 - height / 2 ) + 1\\\
- table.insert( self.windows, {\\\
- window = window;\\\
- display = self.displays[display];\\\
- } )\\\
- table.insert( self.displays[display].windows, window )\\\
- self.windowfocus = window\\\
- return window\\\
- end\\\
- \\\
- function WindowManager.public:removeWindow( window )\\\
- for i = #self.windows, 1, -1 do\\\
- if self.windows[i].window == window then\\\
- local display = self.windows[i].display\\\
- table.remove( self.windows, i )\\\
- for i = #display.windows, 1, -1 do\\\
- if display.windows[i] == window then\\\
- table.remove( display.windows, i )\\\
- end\\\
- end\\\
- end\\\
- end\\\
- end\\\
- \\\
- function WindowManager.public:update()\\\
- local dt = os.clock() - self.last_time\\\
- self.last_time = os.clock()\\\
- for i = 1, #self.windows do\\\
- self.windows[i].window:update( dt )\\\
- end\\\
- end\\\
- \\\
- function WindowManager.public:draw()\\\
- local screen = Gfx2D.buffer.current()\\\
- local t = term.current()\\\
- for k, v in pairs( self.displays ) do\\\
- v.buffer:redirect()\\\
- v.buffer:clear()\\\
- local list = {}\\\
- for i = #v.windows, 1, -1 do\\\
- if v.windows[i].displaymode ~= \\\"minimised\\\" then\\\
- table.insert( list, 1, v.windows[i] )\\\
- end\\\
- if v.windows[i].displaymode == \\\"fullscreen\\\" then\\\
- break\\\
- end\\\
- end\\\
- for i = 1, #list do\\\
- list[i]:draw()\\\
- end\\\
- local _t = {}\\\
- for k in pairs( t ) do\\\
- _t[k] = function( ... )\\\
- for i = #v.redirects, 2, -1 do\\\
- v.redirects[i][k]( ... )\\\
- end\\\
- return v.redirects[1][k]( ... )\\\
- end\\\
- end\\\
- term.redirect( _t )\\\
- v.buffer:draw()\\\
- v.buffer:setCursorBlink()\\\
- end\\\
- screen:redirect()\\\
- term.redirect( t )\\\
- end\\\
- \\\
- function WindowManager.public:event( event )\\\
- local display = self.displays.computer\\\
- if event[1] == \\\"monitor_touch\\\" then\\\
- display = nil\\\
- for k, v in pairs( self.displays ) do\\\
- for i = 1, #v.ids do\\\
- if v.ids[i] == event[2] then\\\
- display = v\\\
- event = {\\\
- \\\"mouse_click\\\";\\\
- 1;\\\
- event[3];\\\
- event[4];\\\
- }\\\
- end\\\
- end\\\
- end\\\
- if not display then return end\\\
- end\\\
- if event[1] == \\\"mouse_click\\\" or event[1] == \\\"mouse_scroll\\\" then\\\
- local w, rx, ry\\\
- for i = #display.windows, 1, -1 do\\\
- local window = display.windows[i]\\\
- if event[3] >= window.x and event[4] >= window.y and event[3] < window.x + window.width and event[4] < window.y + window.height then\\\
- w = window\\\
- rx = event[3] - window.x + 1\\\
- ry = event[4] - window.y + 1\\\
- break\\\
- end\\\
- end\\\
- if w then\\\
- if event[1] == \\\"mouse_click\\\" then\\\
- w:click( rx, ry, event[2] )\\\
- else\\\
- w:scroll( rx, ry, event[2] )\\\
- end\\\
- end\\\
- if event[1] == \\\"mouse_click\\\" then\\\
- self.windowfocus = w\\\
- end\\\
- elseif event[1] == \\\"mouse_drag\\\" and self.windowfocus then\\\
- self.windowfocus:drag( event[3] - self.windowfocus.x + 1, event[4] - self.windowfocus.y + 1, event[2] )\\\
- elseif event[1] == \\\"key\\\" and self.windowfocus then\\\
- self.windowfocus:key( event[2] )\\\
- elseif event[1] == \\\"char\\\" and self.windowfocus then\\\
- self.windowfocus:write( event[2] )\\\
- elseif event[1] == \\\"update\\\" then\\\
- for i = #self.windows, 1, -1 do\\\
- self.windows[i]:update( event[2] )\\\
- end\\\
- elseif event[1] == \\\"paste\\\" then\\\
- self.windowfocus:write( event[2] )\\\
- end\\\
- end\\\
- \\\
- function WindowManager.public:run( noprocess, ... )\\\
- local function run( ... )\\\
- local ok, err = pcall( function( ... )\\\
- local event = { ... }\\\
- while true do\\\
- if event[1] == \\\"update\\\" then\\\
- self.public:draw()\\\
- self.public:update( event[2] )\\\
- else\\\
- self.public:event( event )\\\
- end\\\
- event = { coroutine.yield() }\\\
- end\\\
- end, ... )\\\
- if not ok then\\\
- printError( err )\\\
- end\\\
- end\\\
- if noprocess then\\\
- run( ... )\\\
- else\\\
- return Process.newThread( run )\\\
- end\\\
- end\\\
- \\\
- return WindowManager\"}\
- files[3]={name=\"UIElement\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIElement = Class \\\"UIElement\\\"\\\
- \\\
- UIElement.public \\\"parent\\\" (UIElement) (Window) \\\"nil\\\"\\\
- \\\
- UIElement.public \\\"x\\\" \\\"number\\\"\\\
- UIElement.public \\\"y\\\" \\\"number\\\"\\\
- UIElement.public \\\"width\\\" \\\"number\\\"\\\
- UIElement.public \\\"height\\\" \\\"number\\\"\\\
- \\\
- UIElement.public \\\"callback\\\"\\\
- UIElement.public.callback.write = false\\\
- \\\
- function UIElement:UIElement( x, y, width, height )\\\
- self.x = x\\\
- self.y = y\\\
- self.width = width\\\
- self.height = height\\\
- \\\
- self.callbacks = {}\\\
- self.callback = setmetatable( {}, { __index = self.callbacks, __newindex = function( _, k, v )\\\
- if type( v ) == \\\"function\\\" then\\\
- self.callbacks[k] = v\\\
- else\\\
- return error \\\"expected function callback\\\"\\\
- end\\\
- end } )\\\
- \\\
- self.parent = nil\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function UIElement.public:centreX( n )\\\
- if self.parent then\\\
- self.x = math.floor( self.parent.width / 2 - self.width / 2 ) + ( n or 0 ) + 1\\\
- end\\\
- end\\\
- \\\
- function UIElement.public:centreY( n )\\\
- if self.parent then\\\
- self.y = math.floor( self.parent.height / 2 - self.height / 2 ) + ( n or 0 ) + 1\\\
- end\\\
- end\\\
- \\\
- function UIElement.public:centre( x, y )\\\
- self.public:centreX( x )\\\
- self.public:centreY( y )\\\
- end\\\
- \\\
- function UIElement.public:remove()\\\
- if self.parent then\\\
- self.parent:removeChild( self.public )\\\
- end\\\
- end\\\
- \\\
- function UIElement.public:update( dt )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:draw( x, y )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onClick( x, y, button )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onDrag( x, y, button, lastx, lasty )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onScroll( x, y, dir )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onKey( key )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:write( text )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onFocus( )\\\
- \\\
- end\\\
- \\\
- function UIElement.public:onUnFocus( )\\\
- \\\
- end\\\
- \\\
- return UIElement\"}\
- files[4]={name=\"UIBuffer\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local colour = term.isColour( )\\\
- \\\
- local function termObject( buffer )\\\
- local t = { }\\\
- function t.write( str )\\\
- if type( str ) ~= \\\"string\\\" and type( str ) ~= \\\"number\\\" then return error \\\"expected string\\\" end\\\
- str = tostring( str )\\\
- for x = 1, #str do\\\
- buffer.image:setPixel( buffer.cx, buffer.cy, buffer.bc, buffer.tc, str:sub( x, x ) )\\\
- buffer.cx = buffer.cx + 1\\\
- end\\\
- end\\\
- function t.clearLine( )\\\
- buffer.image:foreach( function( x, y, bc, tc, char )\\\
- if y == buffer.cy then\\\
- return buffer.bc, buffer.tc, \\\" \\\"\\\
- end\\\
- end )\\\
- end\\\
- function t.clear( )\\\
- buffer.image:foreach( function( x, y, bc, tc, char )\\\
- return buffer.bc, buffer.tc, \\\" \\\"\\\
- end )\\\
- end\\\
- function t.setCursorPos( x, y )\\\
- if type( x ) ~= \\\"number\\\" or type( y ) ~= \\\"number\\\" then\\\
- return error \\\"expected number, number\\\"\\\
- end\\\
- buffer.cx = x\\\
- buffer.cy = y\\\
- end\\\
- function t.getCursorPos( )\\\
- return buffer.cx, buffer.cy\\\
- end\\\
- function t.setBackgroundColour( col )\\\
- if type( col ) ~= \\\"number\\\" then\\\
- return error \\\"expected number\\\"\\\
- end\\\
- buffer.bc = col\\\
- end\\\
- function t.setTextColour( col )\\\
- if type( col ) ~= \\\"number\\\" then\\\
- return error \\\"expected number\\\"\\\
- end\\\
- buffer.tc = col\\\
- end\\\
- function t.setBackgroundColor( col )\\\
- if type( col ) ~= \\\"number\\\" then\\\
- return error \\\"expected number\\\"\\\
- end\\\
- buffer.bc = col\\\
- end\\\
- function t.setTextColor( col )\\\
- if type( col ) ~= \\\"number\\\" then\\\
- return error \\\"expected number\\\"\\\
- end\\\
- buffer.tc = col\\\
- end\\\
- function t.scroll( dir )\\\
- buffer.image:foreach( function( x, y, bc, tc, char )\\\
- if buffer.image:getPixel( x, y + dir ) then\\\
- return buffer.image:getPixel( x, y + dir )\\\
- else\\\
- return buffer.bc, buffer.tc, \\\" \\\"\\\
- end\\\
- end )\\\
- end\\\
- function t.setCursorBlink( state )\\\
- buffer.cb = not not state\\\
- end\\\
- function t.isColour( )\\\
- return colour\\\
- end\\\
- function t.isColor( )\\\
- return colour\\\
- end\\\
- function t.getSize( )\\\
- return buffer.width, buffer.height\\\
- end\\\
- \\\
- return t\\\
- end\\\
- \\\
- local function luaEnvironment( canvas )\\\
- local env = { }\\\
- env.fs = fs\\\
- env.term = term\\\
- env._VERSION = _VERSION\\\
- env.pairs = pairs\\\
- env.ipairs = ipairs\\\
- env.select = select\\\
- env.unpack = unpack\\\
- env.setfenv = setfenv\\\
- env.getfenv = getfenv\\\
- env.setmetatable = setmetatable\\\
- env.getmetatable = getmetatable\\\
- env.next = next\\\
- env.rawset = rawset\\\
- env.rawget = rawget\\\
- env.rawequal = rawequal\\\
- env.type = type\\\
- env.tostring = tostring\\\
- env.tonumber = tonumber\\\
- env.pcall = pcall\\\
- env.xpcall = xpcall\\\
- env.loadstring = loadstring\\\
- env.assert = assert\\\
- env.error = error\\\
- env.sleep = sleep\\\
- env.__inext = __inext\\\
- env.math = math\\\
- env.string = string\\\
- env.table = table\\\
- env.coroutine = coroutine\\\
- env.keys = keys\\\
- env.colours = colours\\\
- env.colors = colors\\\
- env.vector = vector\\\
- env.bit = bit\\\
- env.http = http\\\
- env.write = write\\\
- env.print = print\\\
- env.printError = printError\\\
- env.read = read\\\
- env.rednet = rednet\\\
- local tAPIsLoading = { }\\\
- env.os = setmetatable( {\\\
- pullEventRaw = function( sFilter )\\\
- while true do\\\
- local event = { coroutine.yield( ) }\\\
- if not sFilter or sFilter == event[1] then\\\
- return unpack( event )\\\
- end\\\
- end\\\
- end;\\\
- pullEvent = function( sFilter )\\\
- while true do\\\
- local event = { coroutine.yield( ) }\\\
- if event[1] == \\\"terminate\\\" then\\\
- error( \\\"Terminated\\\", 0 )\\\
- end\\\
- if not sFilter or sFilter == event[1] then\\\
- return unpack( event )\\\
- end\\\
- end\\\
- end;\\\
- run = function( _tEnv, _sPath, ... )\\\
- local tArgs = { ... }\\\
- local fnFile, err = env.loadfile( _sPath )\\\
- if fnFile then\\\
- local tEnv = _tEnv\\\
- --setmetatable( tEnv, { __index = function(t,k) return _G[k] end } )\\\
- setmetatable( tEnv, { __index = env } )\\\
- setfenv( fnFile, tEnv )\\\
- local ok, err = pcall( function()\\\
- fnFile( unpack( tArgs ) )\\\
- end )\\\
- if not ok then\\\
- if err and err ~= \\\"\\\" then\\\
- printError( err )\\\
- end\\\
- return false\\\
- end\\\
- return true\\\
- end\\\
- if err and err ~= \\\"\\\" then\\\
- printError( err )\\\
- end\\\
- return false\\\
- end;\\\
- loadAPI = function( _sPath )\\\
- local sName = fs.getName( _sPath )\\\
- if tAPIsLoading[sName] == true then\\\
- printError( \\\"API \\\"..sName..\\\" is already being loaded\\\" )\\\
- return false\\\
- end\\\
- tAPIsLoading[sName] = true\\\
- \\\
- local tEnv = {}\\\
- setmetatable( tEnv, { __index = env } )\\\
- local fnAPI, err = loadfile( _sPath )\\\
- if fnAPI then\\\
- setfenv( fnAPI, tEnv )\\\
- fnAPI()\\\
- else\\\
- printError( err )\\\
- tAPIsLoading[sName] = nil\\\
- return false\\\
- end\\\
- \\\
- local tAPI = {}\\\
- for k,v in pairs( tEnv ) do\\\
- tAPI[k] = v\\\
- end\\\
- \\\
- env[sName] = tAPI \\\
- tAPIsLoading[sName] = nil\\\
- return true\\\
- end;\\\
- unloadAPI = function( _sName )\\\
- if _sName ~= \\\"_G\\\" and type(env[_sName]) == \\\"table\\\" then\\\
- env[_sName] = nil\\\
- end\\\
- end;\\\
- }, { __index = os } );\\\
- env.help = help\\\
- env.io = io\\\
- env.parallel = parallel\\\
- \\\
- env.loadfile = function( _sFile )\\\
- local file = env.fs.open( _sFile, \\\"r\\\" )\\\
- if file then\\\
- local func, err = loadstring( file.readAll(), env.fs.getName( _sFile ) )\\\
- file.close()\\\
- if not func then\\\
- return nil, err:gsub( \\\"UIBuffer.lua:215: \\\", \\\"\\\" )\\\
- end\\\
- return func, err\\\
- end\\\
- return nil, \\\"File not found\\\"\\\
- end\\\
- \\\
- env.dofile = function( _sFile )\\\
- local fnFile, e = env.loadfile( _sFile )\\\
- if fnFile then\\\
- setfenv( fnFile, env )\\\
- return fnFile()\\\
- else\\\
- error( e, 2 )\\\
- end\\\
- end\\\
- \\\
- env.shell = shell\\\
- env.multishell = multishell\\\
- env.redstone = redstone -- change in future, use device system\\\
- env.rs = rs -- change in future, use device system\\\
- env.gps = gps -- change in future, use Nova gps system\\\
- env.peripheral = peripheral -- change in future, use device system\\\
- env.disk = disk -- change in future, use filesystem\\\
- env.window = window -- oh crap...\\\
- env.textutils = textutils\\\
- env.paintutils = paintutils\\\
- env.term = term\\\
- \\\
- env._G = env\\\
- \\\
- return env\\\
- end\\\
- \\\
- local UIBuffer = Class \\\"UIBuffer\\\"\\\
- \\\
- UIBuffer:extends( UIElement )\\\
- \\\
- UIBuffer.public \\\"cx\\\" \\\"number\\\"\\\
- UIBuffer.public \\\"cy\\\" \\\"number\\\"\\\
- UIBuffer.public \\\"cb\\\" \\\"boolean\\\"\\\
- UIBuffer.public \\\"bc\\\" \\\"number\\\"\\\
- UIBuffer.public \\\"tc\\\" \\\"number\\\"\\\
- UIBuffer.public \\\"image\\\"\\\
- UIBuffer.public.image.write = false\\\
- UIBuffer.public \\\"environment\\\"\\\
- UIBuffer.public.environment.write = false\\\
- \\\
- function UIBuffer:UIBuffer( x, y, w, h )\\\
- self:UIElement( x, y, w, h )\\\
- self.image = gfx2d.Image( w, h )\\\
- self.image:foreach( function( )\\\
- return colours.black, colours.white, \\\" \\\"\\\
- end )\\\
- self.term = termObject( self.public )\\\
- self.running = false\\\
- self.co = false\\\
- self.cx = 1\\\
- self.cy = 1\\\
- self.bc = colours.black\\\
- self.tc = colours.white\\\
- self.cb = false\\\
- self.environment = luaEnvironment( )\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function UIBuffer.public:setTask( func )\\\
- setfenv( func, self.environment )\\\
- self.co = coroutine.create( func )\\\
- self.running = true\\\
- end\\\
- \\\
- function UIBuffer.public:passEvent( ... )\\\
- if not self.running then return end\\\
- local prev = term.redirect( self.term )\\\
- local ok, err = coroutine.resume( self.co, ... )\\\
- term.redirect( prev )\\\
- if not ok then\\\
- self.running = false\\\
- local prev = term.redirect( self.term )\\\
- printError( err )\\\
- term.redirect( prev )\\\
- end\\\
- if coroutine.status( self.co ) == \\\"dead\\\" then\\\
- self.running = false\\\
- end\\\
- end\\\
- \\\
- function UIBuffer.public:draw( x, y )\\\
- self.image:resize( self.width, self.height, self.bc, 1, \\\" \\\" )\\\
- self.image:foreach( function( px, py, bc, tc, char )\\\
- Gfx2D.buffer.setPixel( x + px - 1, y + py - 1, bc, tc, char )\\\
- return bc, tc, char\\\
- end )\\\
- if self.cb then\\\
- Gfx2D.buffer.setCursorBlink( x + self.cx - 1, y + self.cy - 1, self.tc )\\\
- end\\\
- end\\\
- \\\
- function UIBuffer.public:onClick( x, y, button )\\\
- self.public:passEvent( \\\"mouse_click\\\", button, x, y )\\\
- end\\\
- \\\
- function UIBuffer.public:onDrag( x, y, button )\\\
- self.public:passEvent( \\\"mouse_drag\\\", button, x, y )\\\
- end\\\
- \\\
- function UIBuffer.public:onScroll( x, y, dir )\\\
- self.public:passEvent( \\\"mouse_scroll\\\", dir, x, y )\\\
- end\\\
- \\\
- function UIBuffer.public:onKey( key, lastkey )\\\
- self.public:passEvent( \\\"key\\\", key )\\\
- end\\\
- \\\
- function UIBuffer.public:write( text, lastkey )\\\
- self.public:passEvent( \\\"char\\\", text )\\\
- end\\\
- \\\
- return UIBuffer\"}\
- files[5]={name=\"UIFrame\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIFrame = Class \\\"UIFrame\\\"\\\
- \\\
- UIFrame:extends( UIElement )\\\
- \\\
- UIFrame.public \\\"ox\\\" \\\"number\\\"\\\
- UIFrame.public \\\"oy\\\" \\\"number\\\"\\\
- \\\
- function UIFrame:UIFrame( x, y, w, h )\\\
- self:UIElement( x, y, w, h )\\\
- \\\
- self.children = {}\\\
- self.ox = 0\\\
- self.oy = 0\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function UIFrame.public:newChild( element )\\\
- if Class.typeOf( element, UIElement ) then\\\
- table.insert( self.children, element )\\\
- element.parent = self.public\\\
- return element\\\
- else\\\
- return error \\\"expected <UIElement> child\\\"\\\
- end\\\
- end\\\
- \\\
- function UIFrame.public:removeChild( element )\\\
- if Class.typeOf( element, UIElement ) then\\\
- for i = 1, #self.children do\\\
- if self.children[i] == element then\\\
- element.parent = nil\\\
- table.remove( self.children, i )\\\
- return\\\
- end\\\
- end\\\
- else\\\
- return error \\\"expected <UIElement> child\\\"\\\
- end\\\
- end\\\
- \\\
- function UIFrame.public:clearChildren()\\\
- for i = #self.children, 1, -1 do\\\
- self.public:removeChild( self.children[i] )\\\
- end\\\
- end\\\
- \\\
- function UIFrame.public:getChildren()\\\
- local t = {}\\\
- for i = 1, #self.children do\\\
- t[i] = self.children[i]\\\
- end\\\
- return t\\\
- end\\\
- \\\
- function UIFrame.public:update( dt )\\\
- for i = 1, #self.children do\\\
- self.children[i]:update( dt )\\\
- end\\\
- end\\\
- \\\
- function UIFrame.public:draw( x, y )\\\
- local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
- for i = 1, #self.children do\\\
- self.children[i]:draw( x + self.children[i].x - 1 + self.ox, y + self.children[i].y - 1 + self.oy )\\\
- end\\\
- Gfx2D.buffer.current():removeStencil( l )\\\
- end\\\
- \\\
- function UIFrame.public:onScroll( x, y, dir )\\\
- self.oy = self.oy - dir\\\
- if self.oy > 0 then self.oy = 0 end\\\
- if self.oy < self.height - self.public:getContentHeight() then self.oy = self.height - self.public:getContentHeight() end\\\
- end\\\
- \\\
- function UIFrame.public:getContentWidth()\\\
- local max = self.width\\\
- for i = 1, #self.children do\\\
- max = math.max( max, self.children[i].x + self.children[i].width - 1 )\\\
- end\\\
- return max\\\
- end\\\
- \\\
- function UIFrame.public:getContentHeight()\\\
- local max = self.height\\\
- for i = 1, #self.children do\\\
- max = math.max( max, self.children[i].y + self.children[i].height - 1 )\\\
- end\\\
- return max\\\
- end\\\
- \\\
- function UIFrame.public:getContentHScroll()\\\
- return -self.ox\\\
- end\\\
- \\\
- function UIFrame.public:getContentVScroll()\\\
- return -self.oy\\\
- end\\\
- \\\
- function UIFrame.public:setContentHScroll( n )\\\
- self.ox = -n\\\
- end\\\
- \\\
- function UIFrame.public:setContentVScroll( n )\\\
- self.oy = -n\\\
- end\\\
- \\\
- return UIFrame\"}\
- files[6]={name=\"UIImage\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIImage = Class \\\"UIImage\\\"\\\
- \\\
- UIImage:extends( UIElement )\\\
- \\\
- UIImage.public \\\"image\\\" (Gfx2D.Image)\\\
- \\\
- function UIImage:UIImage( x, y, w, h, image )\\\
- self:UIElement( x, y, w, h )\\\
- self.image = image\\\
- self.xpos, self.ypos = nil, nil\\\
- return self.public\\\
- end\\\
- \\\
- function UIImage.public:draw( x, y )\\\
- self.image:resize( self.width, self.height )\\\
- self.image:foreach( function( bc, tc, char, xx, yy )\\\
- Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, bc, tc, char )\\\
- end )\\\
- end\\\
- \\\
- function UIImage.public:onClick( rx, ry, button )\\\
- if self.callbacks.onClick then\\\
- self.callbacks.onClick( self.public, button, rx, ry )\\\
- end\\\
- end\\\
- \\\
- function UIImage.public:onDrag( rx, ry, button, lx, ly )\\\
- if self.callbacks.onDrag then\\\
- self.callbacks.onDrag( self.public, button, rx, ry, lx, ly )\\\
- end\\\
- end\\\
- \\\
- return UIImage\"}\
- files[7]={name=\"UIScrollBar\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIScrollBar = Class \\\"UIScrollBar\\\"\\\
- \\\
- UIScrollBar:extends(UIElement)\\\
- \\\
- UIScrollBar.public \\\"bc\\\" \\\"number\\\"\\\
- UIScrollBar.public \\\"tc\\\" \\\"number\\\"\\\
- \\\
- function UIScrollBar:UIScrollBar( x, y, w, h, direction, target )\\\
- self:UIElement( x, y, w, h )\\\
- \\\
- self.bc = colours.lightGrey\\\
- self.tc = colours.grey\\\
- self.direction = direction or \\\"vertical\\\"\\\
- \\\
- if target then\\\
- if Class.typeOf( target, UIElement ) then\\\
- self.target = target\\\
- else\\\
- error( \\\"expected UIElement target\\\", 3 )\\\
- end\\\
- end\\\
- return self.public\\\
- end\\\
- \\\
- function UIScrollBar:getBar( )\\\
- if not self.target then\\\
- return 0, self.direction == \\\"vertical\\\" and self.height or self.width\\\
- end\\\
- local traysize\\\
- if self.direction == \\\"vertical\\\" then\\\
- traysize = self.height\\\
- else\\\
- traysize = self.width\\\
- end\\\
- local framesize, contentsize, contentscroll\\\
- if self.direction == \\\"vertical\\\" then\\\
- framesize = self.target.height\\\
- contentsize = self.target:getContentHeight()\\\
- contentscroll = self.target:getContentVScroll()\\\
- else\\\
- framesize = self.target.width\\\
- contentsize = self.target:getContentWidth()\\\
- contentscroll = self.target:getContentHScroll()\\\
- end\\\
- \\\
- local barsize = math.max( math.floor( traysize * framesize / contentsize ), 1 )\\\
- \\\
- local barpos = traysize * contentscroll / contentsize\\\
- return math.ceil( barpos ), barsize\\\
- end\\\
- \\\
- function UIScrollBar.public:draw( x, y )\\\
- local function rect( x, y, w, h, bc )\\\
- for i = 0, w - 1 do\\\
- for n = 0, h - 1 do\\\
- Gfx2D.buffer.setPixel( x + i, y + n, bc, 1, \\\" \\\" )\\\
- end\\\
- end\\\
- end\\\
- local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
- if self.target then\\\
- local pos, size = self:getBar( )\\\
- rect( x, y, self.width, self.height, self.tc )\\\
- if self.direction == \\\"vertical\\\" then\\\
- rect( x, y + pos, self.width, size, self.bc )\\\
- else\\\
- rect( x + pos, y, size, self.height, self.bc )\\\
- end\\\
- else\\\
- rect( x, y, self.width, self.height, self.bc )\\\
- end\\\
- Gfx2D.buffer.current():removeStencil( l )\\\
- end\\\
- \\\
- function UIScrollBar.public:onClick( rx, ry, button )\\\
- if not self.target then return end\\\
- local pos, size = self:getBar( )\\\
- local traysize\\\
- if self.direction == \\\"vertical\\\" then\\\
- self.downoffset = ry - pos\\\
- if ry > pos and ry < pos + size - 1 then return end\\\
- pos = ry - 1\\\
- traysize = self.height\\\
- else\\\
- self.downoffset = rx - pos\\\
- if rx > pos and rx < pos + size - 1 then return end\\\
- pos = rx - 1\\\
- traysize = self.width\\\
- end\\\
- pos = math.max( math.min( pos, traysize - size ), 0 )\\\
- if self.direction == \\\"vertical\\\" then\\\
- self.target:setContentVScroll( math.floor( pos / traysize * self.target:getContentHeight( ) ) )\\\
- else\\\
- self.target:setContentHScroll( math.floor( pos / traysize * self.target:getContentWidth( ) ) )\\\
- end\\\
- end\\\
- \\\
- function UIScrollBar.public:onDrag( rx, ry, cx, cy, button )\\\
- if not self.target then return end\\\
- local pos, size = self:getBar( )\\\
- local traysize\\\
- if self.direction == \\\"vertical\\\" then\\\
- pos = ry - self.downoffset\\\
- traysize = self.height\\\
- else\\\
- pos = rx - self.downoffset\\\
- traysize = self.width\\\
- end\\\
- pos = math.max( math.min( pos, traysize - size ), 0 )\\\
- if self.direction == \\\"vertical\\\" then\\\
- self.target:setContentVScroll( math.floor( pos / traysize * self.target:getContentHeight( ) ) )\\\
- else\\\
- self.target:setContentHScroll( math.floor( pos / traysize * self.target:getContentWidth( ) ) )\\\
- end\\\
- end\\\
- \\\
- function UIScrollBar.public:onMouseScroll( rx, ry, dir )\\\
- if not self.target then return end\\\
- local pos, size = self:getBar( )\\\
- local traysize\\\
- if self.direction == \\\"vertical\\\" then\\\
- traysize = self.h\\\
- else\\\
- traysize = self.w\\\
- end\\\
- pos = math.max( math.min( pos + dir, traysize - size), 0 )\\\
- if self.direction == \\\"vertical\\\" then\\\
- self.target:setContentScrollV( math.floor( pos / traysize * self.target:getContentSizeV( ) ) )\\\
- else\\\
- self.target:setContentScrollH( math.floor( pos / traysize * self.target:getContentSizeH( ) ) )\\\
- end\\\
- end\\\
- \\\
- return UIScrollBar\"}\
- files[8]={name=\"UIText\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIText = Class \\\"UIText\\\"\\\
- \\\
- UIText:extends( UIElement )\\\
- \\\
- UIText.public \\\"text\\\"\\\
- UIText.public \\\"bc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"tc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"hbc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"htc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"tbc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"ttc\\\" \\\"number\\\" \\\"function\\\"\\\
- UIText.public \\\"syntax\\\"\\\
- UIText.public.syntax.write = false\\\
- \\\
- UIText.public \\\"input\\\" \\\"boolean\\\"\\\
- UIText.public \\\"wordwrap\\\" \\\"boolean\\\"\\\
- UIText.public \\\"noformat\\\" \\\"boolean\\\"\\\
- UIText.public \\\"align\\\" \\\"string\\\"\\\
- \\\
- function UIText.public.text:write( value )\\\
- self.text = type( value ) == \\\"function\\\" and value or tostring( value == nil and \\\"\\\" or value )\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- end\\\
- \\\
- function UIText:UIText( x, y, w, h, text )\\\
- self:UIElement( x, y, w, h )\\\
- \\\
- self.focussed = false\\\
- \\\
- self.bc = colours.white\\\
- self.tc = colours.grey\\\
- self.hbc = colours.blue\\\
- self.htc = colours.white\\\
- self.tbc = colours.white\\\
- self.ttc = colours.white\\\
- self.syntax = {}\\\
- \\\
- self.cx, self.cy = 0, 0\\\
- \\\
- self.input = false\\\
- self.wordwrap = true\\\
- \\\
- self.align = \\\"top left\\\"\\\
- \\\
- self.cursor = {\\\
- x = 1;\\\
- y = 1;\\\
- char = 1;\\\
- }\\\
- self.selection = false\\\
- \\\
- self.public.text = text\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function UIText.public:reload()\\\
- local text = self.text\\\
- if type( text ) == \\\"function\\\" then\\\
- text = text()\\\
- end\\\
- self.stream = SFormat.format( \\\" \\\" .. tostring( text ) .. \\\" \\\", self.syntax, self.bc, self.tc, self.input or self.noformat )\\\
- table.remove( self.stream, 1 )\\\
- table.remove( self.stream, #self.stream )\\\
- end\\\
- function UIText.public:wrap()\\\
- self.wstream = SFormat.wrapstream( self.stream, self.wordwrap and self.width, nil, self.align, self.width, self.height )\\\
- self.lines = self.wstream.lines\\\
- local function unhighlight( x, y )\\\
- if self.wstream:getChar( y, x ) then\\\
- local c = self.wstream:getChar( y, x )\\\
- c.highlight = false\\\
- end\\\
- end\\\
- if self.selection then\\\
- local ss = false\\\
- local mix, miy, max, may = self:getSelectionBounds()\\\
- local function highlight( x, y )\\\
- if self.wstream:getChar( y, x ) then\\\
- local c = self.wstream:getChar( y, x )\\\
- c.highlight = true\\\
- end\\\
- end\\\
- for i = 1, #self.lines do\\\
- if i == miy then\\\
- if miy == may then\\\
- for c = 1, mix - 1 do\\\
- unhighlight( c, i )\\\
- end\\\
- for c = mix, max do\\\
- highlight( c, i )\\\
- end\\\
- for c = max + 1, #self.lines[i] do\\\
- unhighlight( c, i )\\\
- end\\\
- else\\\
- for c = 1, mix - 1 do\\\
- unhighlight( c, i )\\\
- end\\\
- for c = mix, #self.lines[i] do\\\
- highlight( c, i )\\\
- end\\\
- ss = true\\\
- end\\\
- elseif i == may then\\\
- for c = 1, max do\\\
- highlight( c, i )\\\
- end\\\
- for c = max + 1, #self.lines[i] do\\\
- unhighlight( c, i )\\\
- end\\\
- ss = false\\\
- elseif ss then\\\
- for c = 1, #self.lines[i] do\\\
- highlight( c, i )\\\
- end\\\
- else\\\
- for c = 1, #self.lines[i] do\\\
- unhighlight( c, i )\\\
- end\\\
- end\\\
- end\\\
- else\\\
- for i = 1, #self.lines do\\\
- for c = 1, #self.lines[i] do\\\
- unhighlight( c, i )\\\
- end\\\
- end\\\
- end\\\
- end\\\
- \\\
- function UIText:charToCoords( char, noformat )\\\
- if char > #self.stream then\\\
- return #self.lines[#self.lines]:gsub( \\\"\\\\t\\\", \\\" \\\" ) + 1, #self.lines\\\
- end\\\
- local y\\\
- for i = 1, #self.lines do\\\
- y = i\\\
- if char - #self.lines[i] > 0 then\\\
- char = char - #self.lines[i]\\\
- else\\\
- break\\\
- end\\\
- end\\\
- local x = 1\\\
- for i = 1, char - 1 do\\\
- if self.lines[y]:sub( i, i ) == \\\"\\\\t\\\" then\\\
- x = x + ( noformat and 1 or 4 )\\\
- else\\\
- x = x + 1\\\
- end\\\
- end\\\
- return x, y\\\
- end\\\
- function UIText:coordsToChar( x, y )\\\
- y = math.min( y, #self.lines )\\\
- if not self.lines[y] then return 1 end\\\
- x = math.min( x, #self.lines[y]:gsub( \\\"\\\\t\\\", \\\" \\\" ):gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1 )\\\
- local pos = 1\\\
- for i = 1, y - 1 do\\\
- pos = pos + #self.lines[i]\\\
- end\\\
- for i = 1, #self.lines[y] do\\\
- local char = self.lines[y]:sub( i, i )\\\
- if char == \\\"\\\\t\\\" then\\\
- x = x - 4\\\
- else\\\
- x = x - 1\\\
- end\\\
- if x <= 0 then\\\
- return pos\\\
- end\\\
- pos = pos + 1\\\
- end\\\
- return pos\\\
- end\\\
- \\\
- function UIText:getSelectionBounds()\\\
- local sx, sy = self:charToCoords( self.selection.char, true )\\\
- local cx, cy = self:charToCoords( self.cursor.char, true )\\\
- local mix, miy, max, may\\\
- if sy < cy then\\\
- mix, miy, max, may = sx, sy, cx, cy\\\
- elseif sy == cy then\\\
- return math.min( sx, cx ), cy, math.max( sx, cx ), cy\\\
- else\\\
- max, may, mix, miy = sx, sy, cx, cy\\\
- end\\\
- return mix, miy, max, may\\\
- end\\\
- \\\
- function UIText.public:setCursorPos( x, y )\\\
- local x, y, char = y and x or self:charToCoords( x ), y or select( 2, self:charToCoords( x ) ), y and self:coordsToChar( x, y ) or x\\\
- self.cursor = { x = x, y = y, char = char }\\\
- if self.cursor.y + self.cy < 1 then\\\
- self.cy = -self.cursor.y + 1\\\
- elseif self.cursor.y + self.cy > self.height then\\\
- self.cy = -self.cursor.y + self.height\\\
- end\\\
- if self.cursor.x + self.cx < 1 then\\\
- self.cx = -self.cursor.x + 1\\\
- elseif self.cursor.x + self.cx > self.width then\\\
- self.cx = -self.cursor.x + self.width\\\
- end\\\
- end\\\
- \\\
- function UIText.public:select( x, y )\\\
- if not x then\\\
- self.selection = false\\\
- return\\\
- end\\\
- local char\\\
- if not y then\\\
- char = x\\\
- x, y = self:charToCoords( x )\\\
- end\\\
- self.selection = {}\\\
- self.selection.char = char or self:coordsToChar( x - self.cx, y )\\\
- self.selection.x, self.selection.y = x, y\\\
- self.public:wrap()\\\
- end\\\
- \\\
- function UIText.public:update( dt )\\\
- if type( self.text ) == \\\"function\\\" then\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- end\\\
- end\\\
- \\\
- function UIText.public:draw( x, y )\\\
- local l = Gfx2D.buffer.current():addStencil( x, y, self.width, self.height )\\\
- if self.bc ~= 0 then\\\
- for xx = 1, self.width do\\\
- for yy = 1, self.height do\\\
- Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, self.bc, self.tc, \\\" \\\" )\\\
- end\\\
- end\\\
- end\\\
- for i = 1, #self.lines do\\\
- local ypos = i + ( self.lines.padding.vertical or 0 ) + self.cy\\\
- if ypos >= 1 and ypos <= self.height then\\\
- local xpos = ( self.lines.padding[i] or 0 ) + self.cx\\\
- for c = 1, #self.lines[i] do\\\
- local char = self.wstream:getChar( i, c )\\\
- if char then\\\
- local bc, tc = char.bc, char.tc\\\
- if char.char == \\\"\\\\t\\\" then\\\
- bc, tc = self.tbc, self.ttc\\\
- if char.highlight then\\\
- bc, tc = self.hbc, self.htc\\\
- end\\\
- for i = 1, 3 do\\\
- Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, \\\" \\\" )\\\
- xpos = xpos + 1\\\
- end\\\
- Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, \\\":\\\" )\\\
- else\\\
- local ch = char.char\\\
- if char.char == \\\"\\\\n\\\" then\\\
- ch = \\\" \\\"\\\
- end\\\
- if char.highlight then\\\
- bc, tc = self.hbc, self.htc\\\
- end\\\
- Gfx2D.buffer.setPixel( x + xpos, y + ypos - 1, bc, tc, ch )\\\
- end\\\
- end\\\
- xpos = xpos + 1\\\
- end\\\
- end\\\
- end\\\
- if self.focussed and not self.selection and self.input then\\\
- local _x = x + self.cx + ( self.lines.padding[self.cursor.y] or 0 ) + self.cursor.x - 1\\\
- local _y = y + self.cy + ( self.lines.padding.vertical or 0 ) + self.cursor.y - 1\\\
- if self.lines[self.cursor.y] then\\\
- _x = math.min( _x, x + self.cx + ( self.lines.padding[self.cursor.y] or 0 ) + #self.lines[self.cursor.y]:gsub( \\\"\\\\t\\\", \\\" \\\" ):gsub( \\\"\\\\n$\\\", \\\"\\\" ) )\\\
- end\\\
- Gfx2D.buffer.setCursorBlink( _x, _y, self.tc )\\\
- end\\\
- Gfx2D.buffer.current():removeStencil( l )\\\
- end\\\
- \\\
- function UIText.public:onClick( rx, ry, button )\\\
- if self.callbacks.onClick then\\\
- self.callbacks.onClick( self.public, rx, ry, button )\\\
- end\\\
- ry = math.min( ry - ( self.lines.padding.vertical or 0 ), #self.lines )\\\
- if self.lines[ry] then\\\
- rx = rx - ( self.lines.padding[ry] or 0 )\\\
- elseif #self.lines > 0 then\\\
- rx, ry = #self.lines[#self.lines]:gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1, #self.lines\\\
- else\\\
- rx, ry = 1, 1\\\
- end\\\
- self.cursor.char = self:coordsToChar( rx - self.cx, ry - self.cy )\\\
- self.public:setCursorPos( self.cursor.char )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- end\\\
- \\\
- function UIText.public:onDrag( rx, ry, button, lx, ly )\\\
- if self.callbacks.onDrag then\\\
- self.callbacks.onDrag( self.public, rx, ry, button, lx, ly )\\\
- else\\\
- ry = math.min( ry - ( self.lines.padding.vertical or 0 ), #self.lines )\\\
- if self.lines[ry] then\\\
- rx = rx - ( self.lines.padding[ry] or 0 )\\\
- elseif #self.lines > 0 then\\\
- rx, ry = #self.lines[#self.lines]:gsub( \\\"\\\\n$\\\", \\\"\\\" ) + 1, #self.lines\\\
- else\\\
- rx, ry = 1, 1\\\
- end\\\
- self.public:select( self:coordsToChar( rx - self.cx, ry - self.cy ) )\\\
- end\\\
- end\\\
- \\\
- function UIText.public:onScroll( rx, ry, dir )\\\
- if dir == -1 and self.cy < 0 then\\\
- self.cy = self.cy + 1\\\
- elseif dir == 1 and -self.cy < self.public:getContentHeight() - self.height then\\\
- self.cy = self.cy - 1\\\
- end\\\
- end\\\
- \\\
- function UIText.public:onKey( key, last )\\\
- local changed\\\
- if self.input and key == keys.left then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- else\\\
- self.public:setCursorPos( math.max( self.cursor.char - 1, 1 ) )\\\
- end\\\
- elseif self.input and key == keys.right then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- else\\\
- self.public:setCursorPos( math.min( self.cursor.char + 1, #self.stream + 1 ) )\\\
- end\\\
- elseif self.input and key == keys.up then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- elseif self.cursor.y > 1 then\\\
- self.public:setCursorPos( self.cursor.x, self.cursor.y - 1 )\\\
- end\\\
- elseif self.input and key == keys.down then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- elseif self.cursor.y < #self.lines then\\\
- self.public:setCursorPos( self.cursor.x, self.cursor.y + 1 )\\\
- end\\\
- elseif self.input and key == keys.home then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.max( math.min( self.cursor.char, self.selection.char ), 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- else\\\
- self.public:setCursorPos( 1, self.cursor.y )\\\
- end\\\
- elseif self.input and key == keys[\\\"end\\\"] then\\\
- if self.selection then\\\
- self.public:setCursorPos( math.min( math.max( self.cursor.char, self.selection.char ), #self.stream + 1 ) )\\\
- self.selection = false\\\
- self.public:wrap()\\\
- else\\\
- self.public:setCursorPos( #( self.lines[self.cursor.y] or \\\"\\\" ):gsub( \\\"\\\\t\\\", \\\" \\\" ) + 1, self.cursor.y )\\\
- end\\\
- elseif self.input and key == keys.enter then\\\
- if self.callbacks.onEnter then\\\
- self.callbacks.onEnter( self.public )\\\
- else\\\
- self.public:write \\\"\\\\n\\\"\\\
- changed = true\\\
- end\\\
- elseif self.input and key == keys.backspace then\\\
- if self.selection then\\\
- self.public:write \\\"\\\"\\\
- elseif self.cursor.char > 1 then\\\
- if type( self.text ) == \\\"function\\\" then\\\
- self.text = self.text()\\\
- end\\\
- self.text = tostring( self.text ):sub( 1, self.cursor.char - 2 ) .. tostring( self.text ):sub( self.cursor.char )\\\
- self.public:setCursorPos( self.cursor.char - 1 )\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- end\\\
- changed = true\\\
- elseif self.input and key == keys.delete then\\\
- if self.selection then\\\
- self.public:write \\\"\\\"\\\
- elseif #self.text > 0 then\\\
- if type( self.text ) == \\\"function\\\" then\\\
- self.text = self.text()\\\
- end\\\
- self.text = tostring( self.text ):sub( 1, self.cursor.char - 1 ) .. tostring( self.text ):sub( self.cursor.char + 1 )\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- end\\\
- changed = true\\\
- elseif self.input and key == keys.tab then\\\
- if self.selection then\\\
- local mix, miy, may, may = self:getSelectionBounds()\\\
- for i = miy, may do\\\
- self.lines[i] = \\\"\\\\t\\\" .. self.lines[i]\\\
- end\\\
- self.text = table.concat( self.lines, \\\"\\\" )\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- else\\\
- self.public:write \\\"\\\\t\\\"\\\
- end\\\
- changed = true\\\
- end\\\
- if changed then\\\
- if self.callbacks.onChange then\\\
- self.callbacks.onChange( self.public )\\\
- end\\\
- end\\\
- end\\\
- \\\
- function UIText.public:write( text )\\\
- if not self.input then return end\\\
- if self.selection then\\\
- if type( self.text ) == \\\"function\\\" then\\\
- self.text = tostring( self.text() )\\\
- end\\\
- self.text = tostring( self.text ):sub( 1, math.min( self.selection.char, self.cursor.char ) - 1 ) .. text .. tostring( self.text ):sub( math.max( self.selection.char, self.cursor.char ) + 1 )\\\
- self.public:setCursorPos( math.min( self.selection.char, self.cursor.char ) + #text )\\\
- self.public:reload()\\\
- self.selection = false\\\
- self.public:wrap()\\\
- else\\\
- if type( self.text ) == \\\"function\\\" then\\\
- self.text = tostring( self.text() )\\\
- end\\\
- self.text = tostring( self.text ):sub( 1, self.cursor.char - 1 ) .. text .. tostring( self.text ):sub( self.cursor.char )\\\
- self.public:reload()\\\
- self.public:wrap()\\\
- self.public:setCursorPos( self.cursor.char + #text )\\\
- end\\\
- if self.callbacks.onChange then\\\
- self.callbacks.onChange( self.public )\\\
- end\\\
- end\\\
- \\\
- function UIText.public:onFocus()\\\
- self.focussed = true\\\
- end\\\
- function UIText.public:onUnFocus()\\\
- self.focussed = false\\\
- if self.selection then\\\
- self.selection = false\\\
- self.public:wrap()\\\
- end\\\
- end\\\
- \\\
- function UIText.public:getContentWidth()\\\
- local max = self.width\\\
- for i = 1, #self.lines do\\\
- max = math.max( max, #self.lines[i] )\\\
- end\\\
- return max\\\
- end\\\
- \\\
- function UIText.public:getContentHeight()\\\
- return math.max( #self.lines, self.height )\\\
- end\\\
- \\\
- function UIText.public:getContentHScroll()\\\
- return -self.cx\\\
- end\\\
- \\\
- function UIText.public:getContentVScroll()\\\
- return -self.cy\\\
- end\\\
- \\\
- function UIText.public:setContentHScroll( n )\\\
- self.cx = -n\\\
- end\\\
- \\\
- function UIText.public:setContentVScroll( n )\\\
- self.cy = -n\\\
- end\\\
- \\\
- function UIText.public:focusOn()\\\
- local p = self.parent\\\
- while p and p:type() ~= \\\"Window\\\" do\\\
- p = p.parent\\\
- end\\\
- if p then\\\
- p:setFocus( self.public )\\\
- else\\\
- return error \\\"no Window parent\\\"\\\
- end\\\
- end\\\
- \\\
- return UIText\"}\
- files[9]={name=\"UIVideo\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local UIVideo = Class \\\"UIVideo\\\"\\\
- \\\
- UIVideo:extends( UIElement )\\\
- \\\
- UIVideo.public \\\"video\\\" (Gfx2D.Video)\\\
- UIVideo.public \\\"speed\\\" \\\"number\\\"\\\
- UIVideo.public \\\"state\\\" \\\"string\\\"\\\
- \\\
- function UIVideo:UIVideo( x, y, w, h, video )\\\
- self:UIElement( x, y, w, h )\\\
- self.public.video = video\\\
- \\\
- self.speed = 1\\\
- self.state = \\\"running\\\"\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function UIVideo.public:update( dt )\\\
- self.video:resize( self.width, self.height )\\\
- if self.state == \\\"running\\\" then\\\
- self.video:step( dt * self.speed )\\\
- end\\\
- end\\\
- \\\
- function UIVideo.public:draw( x, y )\\\
- local frame = self.video:getFrame()\\\
- if frame then\\\
- frame:foreach( function( xx, yy, bc, tc, char )\\\
- Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, bc, tc, char )\\\
- end )\\\
- else\\\
- for xx = 1, self.width do\\\
- for yy = 1, self.height do\\\
- Gfx2D.buffer.setPixel( x + xx - 1, y + yy - 1, colours.grey, 1, \\\" \\\" )\\\
- end\\\
- end\\\
- local lines = SUtils.wordwrap( \\\"Video has finished!\\\", self.width, self.height )\\\
- y = y + math.ceil( self.height / 2 - #lines / 2 )\\\
- for i = 1, #lines do\\\
- lines[i] = lines[i]:sub( 1, self.width )\\\
- local x = x + math.ceil( self.width / 2 - #lines[i] / 2 )\\\
- for c = 1, #lines[i] do\\\
- Gfx2D.buffer.setPixel( x, y, colours.grey, 1, lines[i]:sub( c, c ) )\\\
- x = x + 1\\\
- end\\\
- y = y + 1\\\
- end\\\
- end\\\
- end\\\
- \\\
- return UIVideo\"}\
- apiCount=9\
- dependencies[1]=\"Class.lua\"\
- dependencies[2]=\"Gfx2D.lua\"\
- dependencies[3]=\"Peripheral.lua\"\
- dependencies[4]=\"Process.lua\"\
- dependencies[5]=\"SUtils.lua\"\
- dependencies[6]=\"SFormat.lua\"\
- local env = setmetatable( {}, { __index = getfenv() } )\
- env.global = env\
- env.args = { ... }\
- local public = {}\
- local bloaded = _G[\"_bundleLoaded\"]\
- if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
- \
- if bloaded[name] and not mainContent then\
- return bloaded[name]\
- end\
- \
- for i = 1, #dependencies do\
- if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- else\
- error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
- end\
- end\
- end\
- for i = 1, #requires do\
- if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- end\
- end\
- end\
- \
- for i = 1, #files do\
- local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
- if f then\
- local e = setmetatable( {}, { __index = env } )\
- setfenv( f, e )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- break\
- end\
- if data == nil then\
- data = {}\
- for k, v in pairs( e ) do\
- data[k] = v\
- end\
- end\
- if files[i].mode == \"api\" then\
- if apiCount == 1 then\
- public = data\
- else\
- public[files[i].name] = data\
- env[files[i].name] = data\
- end\
- else\
- env[files[i].name] = data\
- end\
- else\
- printError( err )\
- break\
- end\
- end\
- \
- if mainContent then\
- local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
- if f then\
- setfenv( f, env )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- end\
- else\
- printError( err )\
- end\
- end\
- \
- bloaded[name] = public\
- return public";["Class.lua"]="local e={}local t={}local a={}local o local i local n=\"Class\"\
- e[1]={name=\"main\",mode='api',content=\"local e={}\\\
- function e.new(t)local a={}local o={}a.public={}a.private={}a.static={}a.name=t\\\
- a.extends=false a.class=o o.name=t local i=false local n=false local s={}\\\
- function o:new(...)local r={}local d={}r.class=o r.public=d\\\
- setmetatable(r,{__index=a.private})function d:type(c)return r.class:type(c)end function d:typeOf(e)return\\\
- r.class:typeOf(e)end local l={}\\\
- l.__index=function(c,m)\\\
- if a.public[m]then\\\
- if\\\
- a.public[m].read then local f\\\
- if i then if type(i)==\\\"function\\\"then return i(r,m)else return i[m]end elseif\\\
- type(a.public[m].read)==\\\"function\\\"then f=a.public[m].read(r)elseif\\\
- a.public[m].value~=nil then f=a.public[m].value else f=r[m]end\\\
- if type(f)==\\\"function\\\"then return\\\
- function(w,...)if w==d then return f(r,...)end return f(w,...)end end return f else error(\\\"variable has no read access\\\",2)end elseif i then if type(i)==\\\"function\\\"then return i(r,m)else return i[m]end else\\\
- error(\\\
- \\\"no such variable \\\\\\\"\\\"..tostring(m)..\\\"\\\\\\\"\\\",2)end end\\\
- l.__newindex=function(c,m,f)\\\
- if a.public[m]then\\\
- if a.public[m].write then\\\
- if n then if type(n)==\\\"function\\\"then return n(r,m,f)else\\\
- n[m]=f end elseif\\\
- type(a.public[m].write)==\\\"function\\\"then a.public[m].write(r,f)else r[m]=f end else error(\\\"variable has no write access\\\",2)end else\\\
- error(\\\"no such variable \\\\\\\"\\\"..tostring(m)..\\\"\\\\\\\"\\\",2)end end l.__tostring=function()return a.name end\\\
- l.__metatable={SwiftClassObject=true,__type=a.name}for c,m in pairs(s)do l[\\\"__\\\"..tostring(c)]=m end\\\
- setmetatable(d,l)local u=a while true do if type(u.private[u.name])==\\\"function\\\"then return\\\
- u.private[u.name](r,...)end\\\
- if u.extends then u=u.extends else break end end return d end\\\
- function o:type(r)local d=\\\"\\\"if r then local l=a.extends\\\
- while l do d=l.name..\\\".\\\"..d l=l.extends end end return d..a.name end\\\
- function o:typeOf(r)\\\
- if type(r)==\\\"table\\\"then\\\
- if pcall(function()\\\
- assert(getmetatable(r).SwiftClass)end,\\\"err\\\")then local d=a while d do if d.class==r then\\\
- return true end d=d.extends end end end return false end function o:extends(r)r:extend(a)end\\\
- function o:extend(r)\\\
- setmetatable(r.static,{__index=a.static})setmetatable(r.public,{__index=a.public})\\\
- setmetatable(r.private,{__index=a.private})r.extends=a end local h={}\\\
- h.__index=function(r,d)\\\
- if d==\\\"static\\\"then return\\\
- setmetatable({},{__newindex=function(r,d,l)a.static[d]=l end,__metatable={}})elseif d==\\\"public\\\"then\\\
- return\\\
- setmetatable({},{__newindex=function(r,d,l)\\\
- a.public[d]={read=true,write=false,value=l}end,__call=function(r,d)\\\
- a.public[d]={read=true,write=true,value=nil}\\\
- return\\\
- function(l)local u={l}\\\
- a.public[d].write=function(m,f)\\\
- for i=1,#u do if e.typeOf(f,u[i])then m[d]=f return end end if e.type(u[1])==\\\"Class\\\"then\\\
- error(\\\"expected \\\"..u[1]:type()..\\\" \\\"..d,3)else\\\
- error(\\\"expected \\\"..tostring(u[1])..\\\" \\\"..d,3)end end local function c(l)table.insert(u,l)return c end return c end end,__index=function(r,d)\\\
- if\\\
- a.public[d]then\\\
- return\\\
- setmetatable({},{__newindex=function(r,t,l)\\\
- if t==\\\"read\\\"then\\\
- if type(l)==\\\"boolean\\\"or type(l)==\\\"function\\\"then\\\
- a.public[d].read=l else error(\\\"invalid modifier value\\\",2)end elseif t==\\\"write\\\"then\\\
- if type(l)==\\\"boolean\\\"or type(l)==\\\"function\\\"then\\\
- a.public[d].write=l else error(\\\"invalid modifier value\\\",2)end else error(\\\"invalid modifier name\\\",2)end end,__metatable={}})else\\\
- error(\\\"public index \\\"..tostring(d)..\\\" not found\\\",2)end end,__metatable={}})elseif d==\\\"meta\\\"then\\\
- return\\\
- setmetatable({},{__index=function(r,d)\\\
- if d==\\\"index\\\"then return i elseif d==\\\"newindex\\\"then return n else return s[d]end end,__newindex=function(r,d,l)\\\
- if d==\\\"metatable\\\"then\\\
- error(\\\"cannot change this metamethod\\\",2)elseif d==\\\"index\\\"then if\\\
- type(l)==\\\"function\\\"or type(l)==\\\"table\\\"or l==nil then i=l else\\\
- error(\\\"cannot use type \\\"..type(l)..\\\" for index metamethod\\\",2)end elseif\\\
- d==\\\"newindex\\\"then if\\\
- type(l)==\\\"function\\\"or type(l)==\\\"table\\\"or l==nil then n=l else\\\
- error(\\\"cannot use type \\\"..type(l)..\\\" for newindex metamethod\\\",2)end else s[d]=l end end,__metatable={}})else return a.static[d]end end h.__newindex=function(r,d,l)a.private[d]=l end h.__call=function(r,...)return\\\
- r:new(...)end\\\
- h.__tostring=function()return\\\"Class\\\"end h.__metatable={SwiftClass=true,__type=\\\"Class\\\"}\\\
- setmetatable(o,h)return o end function e.public(t)local a=e.new(t)getfenv()[t]=a end\\\
- function e.type(t)\\\
- if\\\
- type(t)==\\\"table\\\"then\\\
- if pcall(function()\\\
- assert(getmetatable(t).SwiftClass)end,\\\"err\\\")then return\\\"Class\\\"end if pcall(function()\\\
- assert(getmetatable(t).SwiftClassObject)end,\\\"err\\\")then\\\
- return t:type()end end return type(t)end\\\
- function e.typeOf(t,...)local a={...}\\\
- for i=1,#a do\\\
- if\\\
- type(t)==\\\"table\\\"and pcall(function()\\\
- assert(getmetatable(t).SwiftClassObject)end,\\\"err\\\")then if t:typeOf(a[i])then return a[i]end elseif\\\
- type(t)==\\\"table\\\"and pcall(function()\\\
- assert(getmetatable(t).SwiftClass)end,\\\"err\\\")then if a[i]==\\\"Class\\\"then return\\\"Class\\\"end else\\\
- if type(t)==a[i]then return a[i]end end end return false end\\\
- setmetatable(e,{__call=function(t,...)return e.new(...)end})return e\"}i=1 local s=setmetatable({},{__index=getfenv()})\
- s.global=s s.args={...}local h={}local r=_G[\"_bundleLoaded\"]if type(r)~=\"table\"then r={}\
- _G[\"_bundleLoaded\"]=r end if r[n]and not o then return r[n]end\
- for i=1,#t do\
- if r and\
- r[t[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=r[t[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..t[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[t[i]:gsub(\"%.lua$\",\"\",1)]=l()else\
- error(n..\" requires bundle '\"..t[i]..\"'\",0)end end end\
- for i=1,#a do\
- if r and r[a[i]:gsub(\"%.lua$\",\"\",1)]then\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=r[a[i]:gsub(\"%.lua$\",\"\",1)]else\
- local d=(_G[\"_bundleDependencyPath\"]or\"\")..\"/\"..a[i]local l,u=loadfile(d)if l then setfenv(l,getfenv())\
- s[a[i]:gsub(\"%.lua$\",\"\",1)]=l()end end end\
- for i=1,#e do\
- local d,l=loadstring(e[i].content,\"[\"..n..\"] \"..e[i].name)\
- if d then local u=setmetatable({},{__index=s})setfenv(d,u)\
- local c,m=pcall(d,...)if not c then printError(m)break end if m==nil then m={}\
- for f,w in pairs(u)do m[f]=w end end\
- if e[i].mode==\"api\"then if i==1 then h=m else h[e[i].name]=m\
- s[e[i].name]=m end else s[e[i].name]=m end else printError(l)break end end\
- if o then local d,l=loadstring(o,\"[\"..n..\"] main\")if d then\
- setfenv(d,s)local u,c=pcall(d,...)if not u then printError(c)end else\
- printError(l)end end r[n]=h return h";["Gfx2D.lua"]="local files={}\
- local dependencies={}\
- local requires={}\
- local mainContent\
- local apiCount\
- local name=\"Gfx2D\"\
- files[1]={name=\"pixeldata\";mode='lib';content=\"\\\
- return function( width, height )\\\
- local t = {}\\\
- \\\
- t.width = width\\\
- t.height = height\\\
- \\\
- for y = 1, height do\\\
- t[y] = {}\\\
- for x = 1, width do\\\
- t[y][x] = { bc = 1, tc = 1, char = \\\" \\\" }\\\
- end\\\
- end\\\
- \\\
- function t:setPixel( x, y, bc, tc, char )\\\
- x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
- if self[y] and self[y][x] then\\\
- local _bc, _tc, _char = self:getPixel( x, y )\\\
- if type( bc ) == \\\"function\\\" then bc = bc( _bc ) end\\\
- if bc == 0 then bc = _bc end\\\
- if type( tc ) == \\\"function\\\" then tc = tc( _tc ) end\\\
- if tc == 0 then tc, char = _tc, _char end\\\
- if char ~= \\\"\\\" then\\\
- self[y][x].bc = bc\\\
- self[y][x].tc = tc\\\
- self[y][x].char = char\\\
- end\\\
- return true\\\
- end\\\
- return false\\\
- end\\\
- function t:getPixel( x, y )\\\
- x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
- if self[y] and self[y][x] then\\\
- return self[y][x].bc, self[y][x].tc, self[y][x].char\\\
- end\\\
- end\\\
- \\\
- function t:resize( width, height, bc, tc, char )\\\
- bc = bc or 1\\\
- tc = tc or 1\\\
- char = char or \\\" \\\"\\\
- while self.height < height do\\\
- local t = {}\\\
- for i = 1, self.width do\\\
- t[i] = { bc = bc, tc = tc, char = char }\\\
- end\\\
- table.insert( self, t )\\\
- if self.last then\\\
- local t2 = {}\\\
- for i = 1, self.width do\\\
- t2[i] = { bc = bc + 1, tc = tc + 1 }\\\
- end\\\
- table.insert( self.last, t2 )\\\
- end\\\
- self.height = self.height + 1\\\
- end\\\
- while self.height > height do\\\
- table.remove( self, #self )\\\
- if self.last then\\\
- table.remove( self.last, #self.last )\\\
- end\\\
- self.height = self.height - 1\\\
- end\\\
- while self.width < width do\\\
- for i = 1, self.height do\\\
- table.insert( self[i], { bc = bc, tc = tc, char = char } )\\\
- if self.last then\\\
- table.insert( self.last[i], { bc = bc + 1, tc = tc + 1 } )\\\
- end\\\
- end\\\
- self.width = self.width + 1\\\
- end\\\
- while self.width > width do\\\
- for i = 1, self.height do\\\
- table.remove( self[i], #self[i] )\\\
- if self.last then\\\
- table.remove( self.last[i], #self.last[i] )\\\
- end\\\
- end\\\
- self.width = self.width - 1\\\
- end\\\
- end\\\
- \\\
- function t:foreach( f )\\\
- for x = 1, self.width do\\\
- for y = 1, self.height do\\\
- local bc, tc, char = self:getPixel( x, y )\\\
- local _bc, _tc, _char = f( bc, tc, char, x, y )\\\
- _bc = _bc or bc\\\
- _tc = _tc or tc\\\
- _char = _char or char\\\
- if _bc ~= bc or _tc ~= tc or _char ~= char then\\\
- self:setPixel( x, y, _bc, _tc, _char )\\\
- end\\\
- end\\\
- end\\\
- end\\\
- \\\
- return t\\\
- end\"}\
- files[2]={name=\"mode\";mode='api';content=\"\\\
- local bc = 1\\\
- local tc = 1\\\
- local char = \\\" \\\"\\\
- local pixel = function( x, y, bc, tc, char )\\\
- return buffer.setPixel( x, y, bc, tc, char )\\\
- end\\\
- \\\
- function getMode()\\\
- return bc, tc, char\\\
- end\\\
- \\\
- function setMode( b, t, c )\\\
- bc, tc, char = b or bc, t or tc, c or char\\\
- end\\\
- \\\
- function getPixelFunction()\\\
- return pixel\\\
- end\\\
- function setPixelFunction( f )\\\
- pixel = f\\\
- end\"}\
- files[3]={name=\"shader\";mode='api';content=\"--@meta[type]:\\\"lib\\\"\\\
- \\\
- local maps = {}\\\
- maps.darken = {\\\
- [colours.white] = colours.lightGrey, [colours.orange] = colours.red, [colours.magenta] = colours.purple, [colours.lightBlue] = colours.cyan;\\\
- [colours.yellow] = colours.orange, [colours.lime] = colours.green, [colours.pink] = colours.magenta, [colours.grey] = colours.black;\\\
- [colours.lightGrey] = colours.grey, [colours.cyan] = colours.blue, [colours.purple] = colours.black, [colours.blue] = colours.black;\\\
- [colours.brown] = colours.black, [colours.green] = colours.black, [colours.red] = colours.brown, [colours.black] = colours.black;\\\
- }\\\
- maps.lighten = {\\\
- [colours.white] = colours.white, [colours.orange] = colours.yellow, [colours.magenta] = colours.pink, [colours.lightBlue] = colours.white;\\\
- [colours.yellow] = colours.white, [colours.lime] = colours.white, [colours.pink] = colours.white, [colours.grey] = colours.lightGrey;\\\
- [colours.lightGrey] = colours.white, [colours.cyan] = colours.lightBlue, [colours.purple] = colours.magenta, [colours.blue] = colours.cyan;\\\
- [colours.brown] = colours.red, [colours.green] = colours.lime, [colours.red] = colours.orange, [colours.black] = colours.grey;\\\
- }\\\
- maps.greyscale = {\\\
- [colours.white] = 1, [colours.orange] = 256, [colours.magenta] = 256, [colours.lightBlue] = 256;\\\
- [colours.yellow] = 1, [colours.lime] = 256, [colours.pink] = 1, [colours.grey] = 256;\\\
- [colours.lightGrey] = 256, [colours.cyan] = 128, [colours.purple] = 128, [colours.blue] = 32768;\\\
- [colours.brown] = 32768, [colours.green] = 128, [colours.red] = 128, [colours.black] = 32768;\\\
- }\\\
- maps.sepia = {\\\
- [colours.white] = 1, [colours.orange] = 2, [colours.magenta] = 2, [colours.lightBlue] = 2;\\\
- [colours.yellow] = 1, [colours.lime] = 2, [colours.pink] = 1, [colours.grey] = 2;\\\
- [colours.lightGrey] = 2, [colours.cyan] = 16, [colours.purple] = 16, [colours.blue] = 4096;\\\
- [colours.brown] = 4096, [colours.green] = 16, [colours.red] = 16, [colours.black] = 4096;\\\
- }\\\
- --[[\\\
- maps.inverse = {\\\
- [colours.white] = colours.black, [colours.orange] = colours.purple, [colours.magenta] = colours.yellow, [colours.lightBlue] = colours.orange;\\\
- [colours.yellow] = colours.magenta, [colours.lime] = colours.red, \\\
- \\\
- TODO:\\\
- [colours.pink] = colours.white, [colours.grey] = colours.lightGrey;\\\
- [colours.lightGrey] = colours.white, [colours.cyan] = colours.lightBlue, [colours.purple] = colours.magenta, [colours.blue] = colours.cyan;\\\
- [colours.brown] = colours.red, [colours.green] = colours.orange, [colours.red] = colours.lime, [colours.black] = colours.white;\\\
- }\\\
- ]]\\\
- \\\
- function darken( col )\\\
- return maps.darken[col] or 0\\\
- end\\\
- \\\
- function lighten( col )\\\
- return maps.lighten[col] or 0\\\
- end\\\
- \\\
- function greyscale( col )\\\
- return maps.greyscale[col] or 0\\\
- end\\\
- \\\
- function sepia( col )\\\
- return maps.sepia[col] or 0\\\
- end\\\
- \\\
- --[[\\\
- function inverse( col )\\\
- return maps.inverse[col] or 0\\\
- end\\\
- ]]\"}\
- files[4]={name=\"buffer\";mode='api';content=\"--@meta[type]:\\\"lib\\\"\\\
- \\\
- local c\\\
- \\\
- local buffer = {}\\\
- \\\
- function buffer.create( w, h )\\\
- \\\
- local pixels = pixeldata( w, h )\\\
- pixels.last = {}\\\
- for y = 1, h do\\\
- pixels.last[y] = {}\\\
- for x = 1, w do\\\
- pixels.last[y][x] = { }\\\
- end\\\
- end\\\
- \\\
- local buffer = setmetatable( {}, { __type = \\\"buffer\\\" } )\\\
- buffer.textScale = 1\\\
- buffer.allchanged = false\\\
- buffer.cursor = false\\\
- \\\
- buffer.pixels = pixels\\\
- \\\
- buffer.stencils = {}\\\
- buffer.stencil = false\\\
- \\\
- function buffer:setPixel( x, y, bc, tc, char )\\\
- x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
- if self.stencil then\\\
- if x < self.stencil.x or y < self.stencil.y\\\
- or x >= self.stencil.x + self.stencil.w\\\
- or y >= self.stencil.y + self.stencil.h then\\\
- return false\\\
- end\\\
- end\\\
- if self.pixels[y] and self.pixels[y][x] then\\\
- local _bc, _tc, _char = self.pixels:getPixel( x, y )\\\
- if type( bc ) == \\\"function\\\" then bc = bc( _bc ) end\\\
- if bc == 0 then bc = _bc end\\\
- if type( tc ) == \\\"function\\\" then tc = tc( _tc ) end\\\
- if tc == 0 then tc, char = _tc, _char end\\\
- if char ~= \\\"\\\" then\\\
- self.pixels[y][x].bc = bc\\\
- self.pixels[y][x].tc = tc\\\
- self.pixels[y][x].char = char\\\
- end\\\
- return true\\\
- end\\\
- return false\\\
- end\\\
- function buffer:getPixel( x, y )\\\
- return self.pixels:getPixel( x, y )\\\
- end\\\
- function buffer:clear( bc, tc, char )\\\
- bc = bc or 1\\\
- tc = tc or 1\\\
- char = char or \\\" \\\"\\\
- for y = 1, self.pixels.height do\\\
- for x = 1, self.pixels.width do\\\
- self.pixels:setPixel( x, y, bc, tc, char )\\\
- end\\\
- end\\\
- end\\\
- function buffer:foreach( f )\\\
- return self.pixels:foreach( f )\\\
- end\\\
- \\\
- function buffer:setStencil( x, y, w, h )\\\
- if x then\\\
- self.stencil = { x = x, y = y, w = w, h = h }\\\
- else\\\
- self.stencil = false\\\
- end\\\
- end\\\
- function buffer:addStencil( x, y, w, h )\\\
- table.insert( self.stencils, { x = x, y = y, w = w, h = h } )\\\
- if self.stencil then\\\
- local xx, yy = math.max( x, self.stencil.x ), math.max( y, self.stencil.y )\\\
- local x2, y2 = math.min( x + w, self.stencil.x + self.stencil.w ) - 1, math.min( y + h, self.stencil.y + self.stencil.h ) - 1\\\
- self:setStencil( xx, yy, x2 - xx + 1, y2 - yy + 1 )\\\
- else\\\
- self:setStencil( x, y, w, h )\\\
- end\\\
- return #self.stencils\\\
- end\\\
- function buffer:removeStencil( index )\\\
- while self.stencils[index] do\\\
- table.remove( self.stencils, index )\\\
- end\\\
- self:setStencil()\\\
- for i, v in ipairs( self.stencils ) do\\\
- self:addStencil( v.x, v.y, v.w, v.h )\\\
- table.remove( self.stencils, #self.stencils )\\\
- end\\\
- end\\\
- \\\
- function buffer:setCursorBlink( x, y, tc )\\\
- if x then\\\
- x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
- self.cursor = { x = x, y = y, tc = tc or 1 }\\\
- else\\\
- self.cursor = false\\\
- end\\\
- end\\\
- \\\
- function buffer:hasChanged( x, y )\\\
- x, y = math.floor( x + 0.5 ), math.floor( y + 0.5 )\\\
- if not y then\\\
- for i = 1, self.width do\\\
- if self:hasChanged( i, x ) then\\\
- return true\\\
- end\\\
- end\\\
- end\\\
- if self.pixels[y] and self.pixels[y][x] then\\\
- return self.pixels[y][x].bc ~= self.pixels.last[y][x].bc\\\
- or self.pixels[y][x].char ~= self.pixels.last[y][x].char\\\
- or ( self.pixels[y][x].tc ~= self.pixels.last[y][x].tc and self.pixels[y][x].char ~= \\\" \\\" )\\\
- end\\\
- end\\\
- function buffer:draw( target, _x, _y )\\\
- if self.allchanged then\\\
- return self:drawAll()\\\
- end\\\
- target = target or term\\\
- _x = _x or 1\\\
- _y = _y or 1\\\
- if target.setTextScale then\\\
- target.setTextScale( self.textScale )\\\
- end\\\
- for y = 1, self.pixels.height do\\\
- local last\\\
- for x = 1, self.pixels.width do\\\
- if self:hasChanged( x, y ) then\\\
- if last then\\\
- if last.bc == self.pixels[y][x].bc and ( last.tc == self.pixels[y][x].tc or self.pixels[y][x].char == \\\" \\\" ) then\\\
- last.char = last.char .. self.pixels[y][x].char\\\
- else\\\
- target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
- target.setBackgroundColour( last.bc )\\\
- target.setTextColour( last.tc )\\\
- target.write( last.char )\\\
- last = { x = x, y = y, bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
- end\\\
- else\\\
- last = { x = x, y = y, bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
- end\\\
- self.pixels.last[y][x] = { bc = self.pixels[y][x].bc, tc = self.pixels[y][x].tc, char = self.pixels[y][x].char }\\\
- elseif last then\\\
- target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
- target.setBackgroundColour( last.bc )\\\
- target.setTextColour( last.tc )\\\
- target.write( last.char )\\\
- last = nil\\\
- end\\\
- end\\\
- if last then\\\
- target.setCursorPos( last.x + _x - 1, last.y + _y - 1 )\\\
- target.setBackgroundColour( last.bc )\\\
- target.setTextColour( last.tc )\\\
- target.write( last.char )\\\
- end\\\
- end\\\
- if self.cursor then\\\
- target.setCursorPos( _x + self.cursor.x - 1, _y + self.cursor.y - 1 )\\\
- target.setTextColour( self.cursor.tc )\\\
- target.setCursorBlink( true )\\\
- else\\\
- target.setCursorBlink( false )\\\
- end\\\
- end\\\
- function buffer:drawAll( target, _x, _y )\\\
- self.allchanged = false\\\
- target = target or term\\\
- _x = _x or 1\\\
- _y = _y or 1\\\
- if target.setTextScale then\\\
- target.setTextScale( self.textScale )\\\
- end\\\
- for y = 1, self.pixels.height do\\\
- target.setCursorPos( _x, y + _y - 1 )\\\
- for x = 1, self.pixels.width do\\\
- local bc, tc, char = self.pixels:getPixel( x, y )\\\
- target.setBackgroundColour( bc )\\\
- target.setTextColour( tc )\\\
- target.write( char )\\\
- if char == \\\"\\\" then\\\
- target.setCursorPos( _x + x, y + _y - 1 )\\\
- end\\\
- end\\\
- end\\\
- if self.cursor then\\\
- target.setCursorPos( _x + self.cursor.x - 1, _y + self.cursor.y - 1 )\\\
- target.setTextColour( self.cursor.tc )\\\
- target.setCursorBlink( true )\\\
- else\\\
- target.setCursorBlink( false )\\\
- end\\\
- end\\\
- \\\
- function buffer:resize( width, height, bc, tc, char )\\\
- return self.pixels:resize( width, height, bc, tc, char )\\\
- end\\\
- \\\
- function buffer:redirect()\\\
- c = self\\\
- end\\\
- \\\
- return buffer\\\
- end\\\
- \\\
- local methods = {\\\
- \\\"setPixel\\\";\\\
- \\\"getPixel\\\";\\\
- \\\"clear\\\";\\\
- \\\"foreach\\\";\\\
- \\\"setStencil\\\";\\\
- \\\"addStencil\\\";\\\
- \\\"removeStencil\\\";\\\
- \\\"setCursorBlink\\\";\\\
- \\\"draw\\\";\\\
- \\\"drawAll\\\";\\\
- \\\"resize\\\";\\\
- }\\\
- \\\
- function buffer.setPixel( ... )\\\
- return c:setPixel( ... )\\\
- end\\\
- function buffer.getPixel( ... )\\\
- return c:getPixel( ... )\\\
- end\\\
- \\\
- function buffer.setCursorBlink( ... )\\\
- return c:setCursorBlink( ... )\\\
- end\\\
- \\\
- function buffer.redirect( buffer )\\\
- if type( buffer ) ~= \\\"table\\\" then\\\
- return error( \\\"expected (table) buffer, got \\\" .. type( buffer ) )\\\
- end\\\
- for i = 1, #methods do\\\
- if type( buffer[methods[i]] ) ~= \\\"function\\\" then\\\
- return error( \\\"buffer missing method \\\" .. methods[i] )\\\
- end\\\
- end\\\
- local old = c\\\
- c = buffer\\\
- return old\\\
- end\\\
- function buffer.current( )\\\
- return c\\\
- end\\\
- \\\
- c = buffer.create( term.getSize() )\\\
- \\\
- return setmetatable( buffer, { __call = function( self, ... ) return self.create( ... ) end } )\"}\
- files[5]={name=\"Image\";mode='api';content=\"\\\
- local colourLookup = {\\\
- [\\\"0\\\"] = colours.white;\\\
- [\\\"1\\\"] = colours.orange;\\\
- [\\\"2\\\"] = colours.magenta;\\\
- [\\\"3\\\"] = colours.lightBlue;\\\
- [\\\"4\\\"] = colours.yellow;\\\
- [\\\"5\\\"] = colours.lime;\\\
- [\\\"6\\\"] = colours.pink;\\\
- [\\\"7\\\"] = colours.grey;\\\
- [\\\"8\\\"] = colours.lightGrey;\\\
- [\\\"9\\\"] = colours.cyan;\\\
- [\\\"A\\\"] = colours.purple;\\\
- [\\\"B\\\"] = colours.blue;\\\
- [\\\"C\\\"] = colours.brown;\\\
- [\\\"D\\\"] = colours.green;\\\
- [\\\"E\\\"] = colours.red;\\\
- [\\\"F\\\"] = colours.black;\\\
- [\\\" \\\"] = 0;\\\
- }\\\
- \\\
- local colourSave = { }\\\
- for k, v in pairs( colourLookup ) do\\\
- colourSave[v] = k\\\
- end\\\
- \\\
- local Image = Class \\\"Image\\\"\\\
- \\\
- function Image:Image( w, h )\\\
- self.pixels = pixeldata( w, h )\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function Image.public:setPixel( x, y, bc, tc, char )\\\
- return self.pixels:setPixel( x, y, bc, tc, char )\\\
- end\\\
- \\\
- function Image.public:getPixel( x, y )\\\
- return self.pixels:getPixel( x, y )\\\
- end\\\
- \\\
- function Image.public:foreach( f )\\\
- return self.pixels:foreach( f )\\\
- end\\\
- \\\
- function Image.public:savestr( str )\\\
- local w, h = #( self.pixels[1] or { } ), #self.pixels\\\
- local str = \\\"\\\"\\\
- for y = 1, h do\\\
- for x = 1, w do\\\
- local bc = colourSave[self.pixels[y][x].bc]\\\
- local tc = colourSave[self.pixels[y][x].tc]\\\
- local char = self.pixels[y][x].char\\\
- if #char == 0 then\\\
- char = \\\" \\\"\\\
- bc = colourSave[0]\\\
- end\\\
- str = str .. bc .. tc .. char\\\
- end\\\
- str = str .. \\\"\\\\n\\\"\\\
- end\\\
- return str:sub( 1, -2 )\\\
- end\\\
- \\\
- function Image.public:loadstr( str )\\\
- local lines = { }\\\
- local last = 1\\\
- for i = 1, #str do\\\
- if str:sub( i, i ) == \\\"\\\\n\\\" then\\\
- table.insert( lines, str:sub( last, i - 1 ) )\\\
- last = i + 1\\\
- end\\\
- end\\\
- table.insert( lines, str:sub( last ) )\\\
- local width = #lines[1] / 3\\\
- local height = #lines\\\
- self.public:resize( width, height )\\\
- for i = 1, #lines do\\\
- local x = 1\\\
- for pixel in lines[i]:gmatch( \\\"[0123456789ABCDEF ][0123456789ABCDEF ].\\\" ) do\\\
- local bc = pixel:sub( 1, 1 )\\\
- local tc = pixel:sub( 2, 2 )\\\
- local ch = pixel:sub( 3, 3 )\\\
- if self.pixels[i] and self.pixels[i][x] then\\\
- self.pixels[i][x] = {\\\
- bc = colourLookup[bc];\\\
- tc = colourLookup[tc];\\\
- char = ch;\\\
- }\\\
- end\\\
- x = x + 1\\\
- end\\\
- end\\\
- return self.public\\\
- end\\\
- \\\
- function Image.public:resize( w, h, bc, tc, char )\\\
- return self.pixels:resize( w, h, bc, tc, char )\\\
- end\\\
- \\\
- function Image.public:getSize()\\\
- return self.pixels.width, self.pixels.height\\\
- end\\\
- \\\
- return Image\"}\
- files[6]={name=\"Video\";mode='api';content=\"--@meta[type]:\\\"class\\\"\\\
- \\\
- local Video = Class \\\"Video\\\"\\\
- \\\
- function Video:Video( width, height, framerate )\\\
- self.frame = 0\\\
- self.frames = {}\\\
- self.width = width\\\
- self.height = height\\\
- self.framerate = framerate\\\
- self.frametime = 0\\\
- \\\
- return self.public\\\
- end\\\
- \\\
- function Video.public:step( dt, back )\\\
- self.frametime = self.frametime + dt\\\
- while self.frametime > self.framerate do\\\
- self.public:nextFrame()\\\
- self.frametime = self.frametime - self.framerate\\\
- end\\\
- while self.frametime < 0 do\\\
- self.public:lastFrame()\\\
- self.frametime = self.frametime + self.framerate\\\
- end\\\
- end\\\
- \\\
- function Video.public:nextFrame()\\\
- self.frame = self.frame + 1\\\
- end\\\
- \\\
- function Video.public:lastFrame()\\\
- self.frame = self.frame + 1\\\
- end\\\
- \\\
- function Video.public:getFrame( )\\\
- return self.frames[self.frame]\\\
- end\\\
- \\\
- function Video.public:newFrame( frame )\\\
- if Class.typeOf( frame, Image ) then\\\
- table.insert( self.frames, frame )\\\
- else\\\
- return error \\\"expected Image frame\\\"\\\
- end\\\
- end\\\
- \\\
- function Video.public:hasEnded( )\\\
- return #self.frames < self.frame\\\
- end\\\
- \\\
- function Video.public:resize( w, h )\\\
- for i = 1, #self.frames do\\\
- self.frames[i]:resize( w, h )\\\
- end\\\
- end\\\
- \\\
- function Video.public:savestr()\\\
- local t = {}\\\
- for i = 1, #self.frames do\\\
- t[i] = self.frames[i]:savestr()\\\
- end\\\
- return table.concat( t, \\\"---\\\" )\\\
- end\\\
- \\\
- function Video.public:loadstr( str )\\\
- self.frames = {}\\\
- local frames = sutils.split( str, \\\"%-%-%-\\\" )\\\
- for i = 1, #frames do\\\
- self.frames[i] = Image()\\\
- self.frames[i]:loadstr( frames[i] )\\\
- end\\\
- end\\\
- \\\
- return Video\"}\
- files[7]={name=\"drawBox\";mode='lib';content=\"\\\
- return function( x, y, w, h )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- for i = x, x + w - 1 do\\\
- pixel( i, y, bc, tc, char )\\\
- pixel( i, y + h - 1, bc, tc, char )\\\
- end\\\
- for i = y + 1, y + h - 2 do\\\
- pixel( x, i, bc, tc, char )\\\
- pixel( x + w - 1, i, bc, tc, char )\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[8]={name=\"drawFilledBox\";mode='lib';content=\"\\\
- return function( x, y, w, h )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- for x = x, x + w - 1 do\\\
- for y = y, y + h - 1 do\\\
- pixel( x, y, bc, tc, char )\\\
- end\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[9]={name=\"drawCircle\";mode='lib';content=\"\\\
- local correction = .7\\\
- \\\
- return function( x, y, r )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- local c = 2 * math.pi * r\\\
- local n = 2 * math.pi * 2 / c\\\
- local c8 = c / 8\\\
- for i = 0, c8 do\\\
- local _x, _y = math.sin( i * n ) * r, math.cos( i * n ) * r\\\
- pixel( x + _x, y + _y * correction, bc, tc, char )\\\
- pixel( x + _x, y - _y * correction, bc, tc, char )\\\
- pixel( x - _x, y + _y * correction, bc, tc, char )\\\
- pixel( x - _x, y - _y * correction, bc, tc, char )\\\
- pixel( x + _y, y + _x * correction, bc, tc, char )\\\
- pixel( x - _y, y + _x * correction, bc, tc, char )\\\
- pixel( x + _y, y - _x * correction, bc, tc, char )\\\
- pixel( x - _y, y - _x * correction, bc, tc, char )\\\
- end\\\
- end\"}\
- files[10]={name=\"drawFilledCircle\";mode='lib';content=\"\\\
- local correction = .7\\\
- \\\
- return function( x, y, r )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- local r2 = ( r + 1 ) ^ 2\\\
- for _x = x - r, x + r do\\\
- for _y = -r, r do\\\
- if ( ( x - _x ) ^ 2 + ( y / correction ) ^ 2 ) <= r2 then\\\
- pixel( _x, y + _y, bc, tc, char )\\\
- end\\\
- end\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[11]={name=\"drawEllipse\";mode='lib';content=\"\\\
- -- Credits to Xenthera\\\
- \\\
- return function( x, y, w, h )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- local rx, ry = w / 2, h / 2\\\
- local xc, yc = x + rx, y + ry\\\
- local rxSq, rySq = rx ^ 2, ry ^ 2\\\
- local x, y = 0, ry\\\
- local px, py = 0, 2 * rxSq * y\\\
- pixel( xc+x, yc+y, bc, tc, char )\\\
- pixel( xc-x, yc+y, bc, tc, char )\\\
- pixel( xc+x, yc-y, bc, tc, char )\\\
- pixel( xc-x, yc-y, bc, tc, char )\\\
- local p = rySq - (rxSq * ry) + (0.25 * rxSq)\\\
- while (px < py) do\\\
- x = x + 1\\\
- px = px + 2 * rySq\\\
- if (p < 0) then\\\
- p = p + rySq + px\\\
- else\\\
- y = y - 1\\\
- py = py - 2 * rxSq;\\\
- p = p + rySq + px - py;\\\
- end\\\
- pixel( xc+x, yc+y, bc, tc, char )\\\
- pixel( xc-x, yc+y, bc, tc, char )\\\
- pixel( xc+x, yc-y, bc, tc, char )\\\
- pixel( xc-x, yc-y, bc, tc, char )\\\
- end\\\
- p = rySq*(x+0.5)*(x+0.5) + rxSq*(y-1)*(y-1) - rxSq*rySq\\\
- while (y > 0) do\\\
- y = y - 1\\\
- py = py - 2 * rxSq\\\
- if (p > 0) then\\\
- p = p + rxSq - py\\\
- else\\\
- x = x + 1\\\
- px = px + 2 * rySq\\\
- p = p + rxSq - py + px\\\
- end\\\
- pixel( xc+x, yc+y, bc, tc, char )\\\
- pixel( xc-x, yc+y, bc, tc, char )\\\
- pixel( xc+x, yc-y, bc, tc, char )\\\
- pixel( xc-x, yc-y, bc, tc, char )\\\
- end\\\
- end\"}\
- files[12]={name=\"drawFilledEllipse\";mode='lib';content=\"\\\
- -- Credits to Xenthera\\\
- \\\
- return function( x, y, w, h )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- local ww, hh, x0, dx = w ^ 2, h ^ 2, w, 0\\\
- local hhww = hh*ww\\\
- for _x = -w, w do\\\
- pixel( x + _x, y, bc, tc, char )\\\
- end\\\
- for _y = 1, h do\\\
- local x1 = x0 - (dx - 1)\\\
- for i = x1, 0, -1 do\\\
- if (x1*x1*hh + _y*_y*ww <= hhww) then\\\
- break\\\
- end\\\
- x1 = x1 - 1\\\
- end\\\
- dx, x0 = x0 - x1, x1\\\
- for _x = -x0, x0 do\\\
- pixel( x + _x, y - _y, bc, tc, char )\\\
- pixel( x + _x, y + _y, bc, tc, char )\\\
- end\\\
- end\\\
- end\"}\
- files[13]={name=\"drawImage\";mode='lib';content=\"\\\
- return function( x, y, image )\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- image:foreach( function( bc, tc, char, _x, _y )\\\
- pixel( x + _x - 1, y + _y - 1, bc, tc, char )\\\
- end )\\\
- \\\
- return true\\\
- end\"}\
- files[14]={name=\"drawLine\";mode='lib';content=\"\\\
- return function( x1, y1, x2, y2 )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- if x1 > x2 then\\\
- x2, x1 = x1, x2\\\
- y2, y1 = y1, y2\\\
- end\\\
- \\\
- if x1 == x2 then\\\
- for i = math.min( y1, y2 ), math.max( y1, y2 ) do\\\
- pixel( x1, i, bc, tc, char )\\\
- end\\\
- return true\\\
- end\\\
- \\\
- local dx, dy = x2 - x1, y2 - y1\\\
- local m = dy / dx\\\
- local c = y1 - m * x1\\\
- \\\
- for x = x1, x2, math.min( 1 / m, 1 ) do\\\
- local y = m * x + c\\\
- pixel( x, y, bc, tc, char )\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[15]={name=\"drawPoint\";mode='lib';content=\"\\\
- return function( x, y )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- pixel( x, y, bc, tc, char )\\\
- end\"}\
- files[16]={name=\"drawPolygon\";mode='lib';content=\"\\\
- return function( points )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- for i = 1, #points do\\\
- local p1, p2 = points[i], points[i+1] or points[1]\\\
- drawLine( p1.x, p1.y, p2.x, p2.y )\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[17]={name=\"drawFilledPolygon\";mode='lib';content=\"\\\
- return function( points )\\\
- local bc, tc, char = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- local lines = {}\\\
- for i = 1, #points do\\\
- lines[i] = {\\\
- points[i];\\\
- points[i+1] or points[1];\\\
- }\\\
- end\\\
- for i = #lines, 1, -1 do\\\
- if lines[i][1].y == lines[i][2].y then\\\
- table.remove( lines, i )\\\
- end\\\
- end\\\
- \\\
- local miny, maxy = lines[1][1].y, lines[1][1].y\\\
- for i = 1, #lines do\\\
- miny = math.min( math.min( lines[i][1].y, lines[i][2].y ), miny )\\\
- maxy = math.max( math.max( lines[i][1].y, lines[i][2].y ), maxy )\\\
- end\\\
- \\\
- miny = math.ceil( miny - 0.5 )\\\
- maxy = math.floor( maxy + 0.5 )\\\
- \\\
- local intersections = {}\\\
- \\\
- for l = 1, #lines do\\\
- local v1 = Math2D.Vec2( lines[l][1].x, lines[l][1].y )\\\
- local v2 = Math2D.Vec2( lines[l][2].x, lines[l][2].y )\\\
- for i = miny, maxy do\\\
- intersections[i] = intersections[i] or {}\\\
- \\\
- local point = Math2D.pointOnLine( v1, v2, nil, i )\\\
- if point and Math2D.collision.pointInLine( v1, v2, point ) then\\\
- table.insert( intersections[i], math.floor( point.x + .5 ) )\\\
- end\\\
- end\\\
- end\\\
- \\\
- local points = {}\\\
- \\\
- for i = miny, maxy do\\\
- table.sort( intersections[i] )\\\
- local state = false\\\
- local last = 1\\\
- local p = {}\\\
- for int = 1, #intersections[i] do\\\
- if last ~= intersections[i][int] then\\\
- for _p = last, intersections[i][int] do\\\
- p[_p] = state\\\
- end\\\
- state = not state\\\
- last = intersections[i][int]\\\
- else\\\
- p[last] = state\\\
- end\\\
- end\\\
- \\\
- for x = 1, #p do\\\
- if p[x] then\\\
- pixel( x, i, bc, tc, char )\\\
- end\\\
- end\\\
- end\\\
- end\"}\
- files[18]={name=\"drawText\";mode='lib';content=\"\\\
- return function( x, y, text )\\\
- local bc, tc = mode.getMode()\\\
- local pixel = mode.getPixelFunction()\\\
- \\\
- for i = 1, #text do\\\
- pixel( x, y, bc, tc, text:sub( i, i ) )\\\
- x = x + 1\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[19]={name=\"drawWrappedText\";mode='lib';content=\"\\\
- return function( x, y, w, h, text, align )\\\
- local lines = SUtils.wordwrap( text, w, h, align, w, h )\\\
- for i = 1, #lines do\\\
- drawText( x + ( lines.padding[i] or 0 ), y + i + ( lines.padding.vertical or 0 ) - 1, lines[i] )\\\
- end\\\
- \\\
- return true\\\
- end\"}\
- files[20]={name=\"draw\";mode='api';content=\"\\\
- function point( x, y )\\\
- return drawPoint( x, y )\\\
- end\\\
- \\\
- function box( x, y, w, h )\\\
- return drawBox( x, y, w, h )\\\
- end\\\
- \\\
- function filledBox( x, y, w, h )\\\
- return drawFilledBox( x, y, w, h )\\\
- end\\\
- \\\
- function circle( x, y, r )\\\
- return drawCircle( x, y, r )\\\
- end\\\
- \\\
- function filledCircle( x, y, r )\\\
- return drawFilledCircle( x, y, r )\\\
- end\\\
- \\\
- function ellipse( x, y, w, h )\\\
- return drawEllipse( x, y, w, h )\\\
- end\\\
- \\\
- function filledEllipse( x, y, w, h )\\\
- return drawFilledEllipse( x, y, w, h )\\\
- end\\\
- \\\
- function image( x, y, image )\\\
- return drawImage( x, y, image )\\\
- end\\\
- \\\
- function line( x1, y1, x2, y2 )\\\
- return drawLine( x1, y1, x2, y2 )\\\
- end\\\
- \\\
- function polygon( ... )\\\
- if #arg == 1 and type( arg[1] ) == \\\"table\\\" then arg = arg[1] end\\\
- local points = {}\\\
- for i = 1, #arg / 2 do\\\
- points[i] = {\\\
- x = arg[2 * i - 1];\\\
- y = arg[2 * i];\\\
- }\\\
- end\\\
- return drawPolygon( points )\\\
- end\\\
- \\\
- function filledPolygon( ... )\\\
- if #arg == 1 and type( arg[1] ) == \\\"table\\\" then arg = arg[1] end\\\
- local points = {}\\\
- for i = 1, #arg / 2 do\\\
- points[i] = {\\\
- x = arg[2 * i - 1];\\\
- y = arg[2 * i];\\\
- }\\\
- end\\\
- return drawFilledPolygon( points )\\\
- end\\\
- \\\
- function text( x, y, text )\\\
- return drawText( x, y, text )\\\
- end\\\
- \\\
- function wrappedText( x, y, w, h, text, align )\\\
- return drawWrappedText( x, y, w, h, text, align )\\\
- end\"}\
- apiCount=6\
- dependencies[1]=\"Class.lua\"\
- dependencies[2]=\"Math2D.lua\"\
- dependencies[3]=\"SUtils.lua\"\
- local env = setmetatable( {}, { __index = getfenv() } )\
- env.global = env\
- env.args = { ... }\
- local public = {}\
- local bloaded = _G[\"_bundleLoaded\"]\
- if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
- \
- if bloaded[name] and not mainContent then\
- return bloaded[name]\
- end\
- \
- for i = 1, #dependencies do\
- if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- else\
- error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
- end\
- end\
- end\
- for i = 1, #requires do\
- if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- end\
- end\
- end\
- \
- for i = 1, #files do\
- local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
- if f then\
- local e = setmetatable( {}, { __index = env } )\
- setfenv( f, e )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- break\
- end\
- if data == nil then\
- data = {}\
- for k, v in pairs( e ) do\
- data[k] = v\
- end\
- end\
- if files[i].mode == \"api\" then\
- if apiCount == 1 then\
- public = data\
- else\
- public[files[i].name] = data\
- env[files[i].name] = data\
- end\
- else\
- env[files[i].name] = data\
- end\
- else\
- printError( err )\
- break\
- end\
- end\
- \
- if mainContent then\
- local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
- if f then\
- setfenv( f, env )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- end\
- else\
- printError( err )\
- end\
- end\
- \
- bloaded[name] = public\
- return public"};["Nightfall.lua"]="local files={}\
- local dependencies={}\
- local requires={}\
- local mainContent\
- local apiCount\
- local name=\"NightFall\"\
- files[1]={name=\"config\";mode='lib';content=\"\\\
- target = \\\"computer\\\"\\\
- width, height = term.getSize()\\\
- \\\
- atime = 0.4\\\
- sleep = 1\\\
- \\\
- installpath = \\\".nightfall\\\"\"}\
- files[2]={name=\"images\";mode='lib';content=\"logo = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70N70i70g70h70t70 70F70a70l70l70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 F0 70 70 70 70 70 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 70 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 70 70 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 70 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 00 00 00 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 70 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 00 00 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 00 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 70 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- 70 70 70 80 80 80 80 80 80 F0 F0 F0 F0 F0 F0 F0 80 80 80 80 80 80 80 80 80 80 80 80 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 70 \\\
- F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 \\\
- F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 \\\
- F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 F0 ]]\\\
- \\\
- plus = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 \\\
- 70 70 00 70 70 \\\
- 70 00 00 00 70 \\\
- 70 70 00 70 70 \\\
- 70 70 70 70 70 ]]\\\
- \\\
- move = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70^70 70 \\\
- 70 70 70|70 70 \\\
- 70<70-70+70-70>\\\
- 70 70 70|70 70 \\\
- 70 70 70v70 70 ]]\\\
- \\\
- delete = Gfx2D.Image( 0, 0 ):loadstr [[70 70 70 70 70 \\\
- 70 E0 70 E0 70 \\\
- 70 70 E0 70 70 \\\
- 70 E0 70 E0 70 \\\
- 70 70 70 70 70 ]]\"}\
- files[3]={name=\"waves\";mode='lib';content=\"local t = {}\\\
- \\\
- t[1] = {\\\
- 1;\\\
- 1;\\\
- 1;\\\
- 1;\\\
- 1;\\\
- }\\\
- \\\
- t[2] = {\\\
- 1;\\\
- 1;\\\
- 1;\\\
- 1;\\\
- 1;\\\
- 2;\\\
- 2;\\\
- 2;\\\
- 1;\\\
- 1;\\\
- }\\\
- \\\
- t[3] = {\\\
- 5;\\\
- 5;\\\
- 5;\\\
- 6;\\\
- 7;\\\
- 8;\\\
- 6;\\\
- 7;\\\
- 8;\\\
- }\\\
- \\\
- return t\"}\
- files[4]={name=\"listMaps\";mode='lib';content=\"\\\
- return function( w, h, onClick )\\\
- local frame = UIKit.UIFrame( 0, 0, w, h )\\\
- \\\
- local maps = fs.list( config.installpath .. \\\"/assets/maps\\\" )\\\
- \\\
- local cframe = frame:newChild( UIKit.UIFrame( 1, 1, w, h ) )\\\
- if #maps > h then\\\
- cframe.width = w - 1\\\
- local scrollbar = frame:newChild( UIKit.UIScrollBar( w, 1, 1, h, \\\"vertical\\\", cframe ) )\\\
- end\\\
- \\\
- for i = 1, #maps do\\\
- local t = cframe:newChild( UIKit.UIText( 1, i, cframe.width, 1, maps[i] ) )\\\
- t.bc = colours.grey\\\
- t.tc = colours.lightGrey\\\
- t.wordwrap = false\\\
- function t.callback:onClick()\\\
- onClick( maps[i], t )\\\
- end\\\
- t:reload()\\\
- t:wrap()\\\
- end\\\
- \\\
- if #maps == 0 then\\\
- frame:newChild( UIKit.UIText( 0, 0, 8, 1, \\\"#7&8No maps!\\\" ) ):centre()\\\
- end\\\
- \\\
- return frame\\\
- end\"}\
- files[5]={name=\"saveLoader\";mode='lib';content=\"\"}\
- files[6]={name=\"saveSaver\";mode='lib';content=\"\"}\
- files[7]={name=\"loadGameUI\";mode='lib';content=\"\\\
- return function()\\\
- local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
- newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
- frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
- \\\
- frame:newChild( UIKit.UIText( 0, 1, 9, 1, \\\"#7&0Load Game\\\" ) ):centreX()\\\
- local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
- function back.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- \\\
- local f = frame:newChild( UIKit.UIFrame( 1, 3, frame.width, frame.height - 2 ) )\\\
- \\\
- local saves = fs.list( config.installpath .. \\\"/saves\\\" )\\\
- \\\
- local cframe = f:newChild( UIKit.UIFrame( 1, 1, f.width, f.height ) )\\\
- if #saves > f.height then\\\
- cframe.width = w - 1\\\
- local scrollbar = f:newChild( UIKit.UIScrollBar( f.width, 1, 1, f.height, \\\"vertical\\\", cframe ) )\\\
- end\\\
- \\\
- for i = 1, #saves do\\\
- local t = cframe:newChild( UIKit.UIText( 1, i, cframe.width, 1, saves[i] ) )\\\
- t.bc = colours.grey\\\
- t.tc = colours.lightGrey\\\
- t.wordwrap = false\\\
- function t.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- gameUI( saves[i] )\\\
- end\\\
- end\\\
- t:reload()\\\
- t:wrap()\\\
- end\\\
- \\\
- if #saves == 0 then\\\
- f:newChild( UIKit.UIText( 0, 0, 9, 1, \\\"#7&8No saves!\\\" ) ):centre()\\\
- end\\\
- end\"}\
- files[8]={name=\"newGameUI\";mode='lib';content=\"\\\
- return function()\\\
- local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 10 ) )\\\
- newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
- frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
- \\\
- frame:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"#7&0New Game\\\" ) ):centreX()\\\
- local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
- function back.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- \\\
- local name = frame:newChild( UIKit.UIText( 1, 3, 4, 1, \\\"#7&8Name\\\" ) )\\\
- local ni = frame:newChild( UIKit.UIText( 6, 3, frame.width - 6, 1, \\\"\\\" ) )\\\
- ni.bc = colours.lightGrey\\\
- ni.hbc = 32768\\\
- ni.input = true\\\
- ni.wordwrap = false\\\
- \\\
- function ni.callback:onChange()\\\
- if fs.exists( config.installpath .. \\\"/saves/\\\" .. self.text ) then\\\
- self.bc = colours.yellow\\\
- else\\\
- self.bc = colours.lightGrey\\\
- end\\\
- self:reload()\\\
- self:wrap()\\\
- end\\\
- \\\
- local mapname\\\
- local button\\\
- local f = frame:newChild( listMaps( frame.width, frame.height - 6, function( map, b )\\\
- mapname = map\\\
- if button then\\\
- button.bc = colours.grey\\\
- button:reload()\\\
- button:wrap()\\\
- end\\\
- button = b\\\
- button.bc = colours.black\\\
- button:reload()\\\
- button:wrap()\\\
- end ) )\\\
- f.x = 1\\\
- f.y = 5\\\
- \\\
- local c = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&3create\\\" ) )\\\
- c:centreX()\\\
- function c.callback:onClick()\\\
- local name = ni.text\\\
- if name == \\\"\\\" then\\\
- local t = window:newChild( UIKit.UIText( 0, config.height - 1, 24, 1, \\\"# &EPlease type a save name.\\\" ) )\\\
- t.bc = 0\\\
- t:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- t:remove()\\\
- end )\\\
- elseif fs.exists( config.installpath .. \\\"/saves/\\\" .. name ) then\\\
- local t = window:newChild( UIKit.UIText( 0, config.height - 1, 39, 1, \\\"# &EThere is already a save with that name.\\\" ) )\\\
- t.bc = 0\\\
- t:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- t:remove()\\\
- end )\\\
- elseif not mapname then\\\
- local t = window:newChild( UIKit.UIText( 0, config.height - 1, 27, 1, \\\"# &EPlease select a map to use.\\\" ) )\\\
- t.bc = 0\\\
- t:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- t:remove()\\\
- end )\\\
- else\\\
- local h = fs.open( config.installpath .. \\\"/saves/\\\" .. name, \\\"w\\\" )\\\
- h.write( \\\"map=\\\" .. (\\\"%q\\\"):format( mapname ) .. \\\";\\\\nturrets={};\\\\nstage=0;\\\\nmoney=0;\\\\ntraps={};\\\\nhealth=0;\\\\ninitialised=false;\\\" )\\\
- h.close()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- gameUI( name )\\\
- end\\\
- end\\\
- end\\\
- \\\
- function ni.callback:onEnter()\\\
- c.callback:onClick()\\\
- end\\\
- \\\
- ni:focusOn()\\\
- end\"}\
- files[9]={name=\"createMapUI\";mode='lib';content=\"\\\
- return function()\\\
- local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
- newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
- frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
- \\\
- frame:newChild( UIKit.UIText( 0, 1, 10, 1, \\\"#7&0Create Map\\\" ) ):centreX()\\\
- local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
- function back.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- \\\
- local n = frame:newChild( UIKit.UIText( 1, 3, 4, 1, \\\"#7&8Name\\\" ) )\\\
- local ni = frame:newChild( UIKit.UIText( 6, 3, frame.width - 6, 1, \\\"\\\" ) )\\\
- ni.bc = colours.lightGrey\\\
- ni.hbc = 32768\\\
- ni.input = true\\\
- ni.wordwrap = false\\\
- \\\
- function ni.callback:onChange()\\\
- if fs.exists( config.installpath .. \\\"/assets/maps/\\\" .. self.text ) then\\\
- self.bc = colours.yellow\\\
- else\\\
- self.bc = colours.lightGrey\\\
- end\\\
- self:reload()\\\
- self:wrap()\\\
- end\\\
- \\\
- local w = frame:newChild( UIKit.UIText( 1, 5, 5, 1, \\\"#7&8Width\\\" ) )\\\
- local h = frame:newChild( UIKit.UIText( 1, 6, 6, 1, \\\"#7&8Height\\\" ) )\\\
- \\\
- local wd = frame:newChild( UIKit.UIText( 8, 5, 4, 1, \\\"#835\\\" ) )\\\
- wd.bc = colours.lightGrey\\\
- wd.hbc = 32768\\\
- \\\
- local hd = frame:newChild( UIKit.UIText( 8, 6, 4, 1, \\\"#818\\\" ) )\\\
- hd.bc = colours.lightGrey\\\
- hd.hbc = 32768\\\
- \\\
- local wdown = frame:newChild( UIKit.UIText( 13, 5, 1, 1, \\\"#7&0-\\\" ) )\\\
- function wdown.callback:onClick()\\\
- wd.text = \\\"#8\\\" .. math.max( ( tonumber( wd.text:sub( 3 ) ) or 0 ) - 1, 1 )\\\
- end\\\
- local wup = frame:newChild( UIKit.UIText( 15, 5, 1, 1, \\\"#7&0+\\\" ) )\\\
- function wup.callback:onClick()\\\
- wd.text = \\\"#8\\\" .. math.min( ( tonumber( wd.text:sub( 3 ) ) or 0 ) + 1, 9999 )\\\
- end\\\
- \\\
- local hdown = frame:newChild( UIKit.UIText( 13, 6, 1, 1, \\\"#7&0-\\\" ) )\\\
- function hdown.callback:onClick()\\\
- hd.text = \\\"#8\\\" .. math.max( ( tonumber( hd.text:sub( 3 ) ) or 0 ) - 1, 1 )\\\
- end\\\
- local hup = frame:newChild( UIKit.UIText( 15, 6, 1, 1, \\\"#7&0+\\\" ) )\\\
- function hup.callback:onClick()\\\
- hd.text = \\\"#8\\\" .. math.min( ( tonumber( hd.text:sub( 3 ) ) or 0 ) + 1, 9999 )\\\
- end\\\
- \\\
- local c = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&3create\\\" ) )\\\
- c:centreX()\\\
- function c.callback:onClick()\\\
- local width, height = tonumber( wd.text:sub( 3 ) ) or 0, tonumber( hd.text:sub( 3 ) ) or 0\\\
- local name = ni.text\\\
- if name == \\\"\\\" then\\\
- local t = window:newChild( UIKit.UIText( 0, config.height - 1, 19, 1, \\\"# &EPlease type a name.\\\" ) )\\\
- t.bc = 0\\\
- t:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- t:remove()\\\
- end )\\\
- elseif fs.exists( config.installpath .. \\\"/assets/maps/\\\" .. name ) then\\\
- local t = window:newChild( UIKit.UIText( 0, config.height - 1, 38, 1, \\\"# &EThere is already a map with that name.\\\" ) )\\\
- t.bc = 0\\\
- t:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- t:remove()\\\
- end )\\\
- else\\\
- local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. name, \\\"w\\\" )\\\
- h.write( \\\"width=\\\" .. width .. \\\";\\\\nheight=\\\" .. height .. \\\";\\\\npath={};\\\\nstart={x=1,y=1};\\\\nfinish={x=\\\" .. width .. \\\",y=\\\" .. height .. \\\"};\\\\nassets={};\\\" )\\\
- h.close()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- mapUI( name )\\\
- fs.delete( config.installpath .. \\\"/assets/maps/\\\" .. name )\\\
- end\\\
- end\\\
- end\\\
- \\\
- function ni.callback:onEnter()\\\
- c.callback:onClick()\\\
- end\\\
- \\\
- ni:focusOn()\\\
- end\"}\
- files[10]={name=\"editMapUI\";mode='lib';content=\"\\\
- return function()\\\
- local frame = window:newChild( UIKit.UIFrame( config.width + 1, 7, 19, 8 ) )\\\
- newTween( config.atime, frame, { x = config.width - frame.width + 1 }, \\\"outSine\\\" ).round = true\\\
- frame:newChild( UIKit.UIText( 1, 1, frame.width, frame.height ) ).bc = colours.grey\\\
- \\\
- frame:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"#7&0Edit Map\\\" ) ):centreX()\\\
- local back = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&8<\\\" ) )\\\
- function back.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- \\\
- local f = frame:newChild( listMaps( frame.width, frame.height - 2, function( map )\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- newTween( config.atime, background, { y = 1 - config.height }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- mapUI( map )\\\
- end\\\
- end ) )\\\
- f.x = 1\\\
- f.y = 3\\\
- end\"}\
- files[11]={name=\"gameUI\";mode='lib';content=\"\\\
- local states = {}\\\
- \\\
- local units = {}\\\
- local files = fs.list( config.installpath .. \\\"/assets/units\\\" )\\\
- for i = 1, #files do\\\
- local h = fs.open( config.installpath .. \\\"/assets/units/\\\" .. files[i], \\\"r\\\" )\\\
- local content = h.readAll()\\\
- h.close()\\\
- units[i] = textutils.unserialize( \\\"{\\\" .. content .. \\\"}\\\" )\\\
- units[i].image = Gfx2D.Image( 0, 0 ):loadstr( units[i].image )\\\
- end\\\
- local turrets = {}\\\
- local files = fs.list( config.installpath .. \\\"/assets/turrets\\\" )\\\
- for i = 1, #files do\\\
- local h = fs.open( config.installpath .. \\\"/assets/turrets/\\\" .. files[i], \\\"r\\\" )\\\
- local content = h.readAll()\\\
- h.close()\\\
- turrets[i] = textutils.unserialize( \\\"{\\\" .. content .. \\\"}\\\" )\\\
- turrets[i].image = Gfx2D.Image( 0, 0 ):loadstr( turrets[i].image )\\\
- turrets[i].image:resize( 3, 2 )\\\
- end\\\
- \\\
- local function endState( state )\\\
- local s = states[state]\\\
- if s then\\\
- local r = newTween( config.atime, s.frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- newTween( config.atime, background, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
- r.round = true\\\
- s.UIProcess:stop()\\\
- s.timerProcess:stop()\\\
- s.turretHandler:stop()\\\
- function r:onFinish()\\\
- s.frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- end\\\
- local function saveState( state )\\\
- local h = fs.open( config.installpath .. \\\"/saves/\\\" .. states[state].savename, \\\"w\\\" )\\\
- if not h then\\\
- return\\\
- end\\\
- local savedata = states[state].savedata\\\
- local turrets = {}\\\
- for i = 1, #savedata.turrets do\\\
- turrets[i] = {\\\
- turret = savedata.turrets[i].turret.name;\\\
- x = savedata.turrets[i].x;\\\
- y = savedata.turrets[i].y;\\\
- lastfire = 0;\\\
- }\\\
- end\\\
- local data = {\\\
- map = savedata.map;\\\
- turrets = turrets;\\\
- stage=savedata.stage;\\\
- money=savedata.money;\\\
- traps=savedata.traps;\\\
- health=savedata.health;\\\
- initialised=savedata.initialised;\\\
- }\\\
- h.write( textutils.serialize( data ):sub( 2, -2 ) )\\\
- h.close()\\\
- end\\\
- \\\
- local function loaddata( name, state )\\\
- local h = fs.open( config.installpath .. \\\"/saves/\\\" .. name, \\\"r\\\" )\\\
- if not h then\\\
- content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load save.\\\" ) ):centre()\\\
- return\\\
- end\\\
- local savedata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
- h.close()\\\
- if type( savedata ) ~= \\\"table\\\" then\\\
- content:newChild( UIKit.UIText( 0, 0, 13, 1, \\\"&ECorrupt save.\\\" ) ):centre()\\\
- return\\\
- end\\\
- \\\
- local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. savedata.map, \\\"r\\\" )\\\
- if not h then\\\
- content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load map.\\\" ) ):centre()\\\
- return\\\
- end\\\
- local mapdata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
- h.close()\\\
- if type( mapdata ) ~= \\\"table\\\" then\\\
- content:newChild( UIKit.UIText( 0, 0, 12, 1, \\\"&ECorrupt map.\\\" ) ):centre()\\\
- return\\\
- end\\\
- \\\
- if not savedata.initialised then\\\
- savedata.health = 100\\\
- savedata.stage = 1\\\
- savedata.money = 100\\\
- savedata.initialised = true\\\
- end\\\
- \\\
- for i = 1, #savedata.turrets do\\\
- for t = 1, #turrets do\\\
- if turrets[t].name == savedata.turrets[i].turret then\\\
- savedata.turrets[i].turret = turrets[t]\\\
- end\\\
- end\\\
- end\\\
- \\\
- states[state].savedata, states[state].mapdata = savedata, mapdata\\\
- return true\\\
- end\\\
- \\\
- local function displayVars( state )\\\
- local s = states[state]\\\
- \\\
- s.scrollx, s.scrolly = 0, 0\\\
- s.changed = true\\\
- s.buffer = Gfx2D.Image( s.content.width, s.content.height )\\\
- s.display = s.content:newChild( UIKit.UIImage( 1, 1, s.content.width, s.content.height, s.buffer ) )\\\
- \\\
- function s.display.callback:onDrag( button, x, y, lx, ly )\\\
- s.scrollx = s.scrollx - x + lx\\\
- s.scrolly = s.scrolly - y + ly\\\
- s.changed = true\\\
- end\\\
- end\\\
- \\\
- local function mapDisplay( state )\\\
- local s = states[state]\\\
- \\\
- local map = Gfx2D.Image( s.mapdata.width, s.mapdata.height )\\\
- map:foreach( function()\\\
- return colours.green\\\
- end )\\\
- for i = 1, s.mapdata.width * s.mapdata.height / 10 do\\\
- local x = math.random( 1, s.mapdata.width )\\\
- local y = math.random( 2, s.mapdata.height )\\\
- map:setPixel( x, y, colours.green, colours.lime, \\\"v\\\" )\\\
- end\\\
- for i = 1, #s.mapdata.path do\\\
- local x, y = s.mapdata.path[i].x, s.mapdata.path[i].y\\\
- map:setPixel( x, y, colours.grey, 1, \\\" \\\" )\\\
- end\\\
- map:setPixel( s.mapdata.start.x, s.mapdata.start.y, colours.blue, 1, \\\" \\\" )\\\
- map:setPixel( s.mapdata.finish.x, s.mapdata.finish.y, colours.magenta, 1, \\\" \\\" )\\\
- \\\
- s.map = map\\\
- end\\\
- \\\
- local function cloneT( t )\\\
- local t2 = {}\\\
- for i = 1, #t do\\\
- t2[i] = t[i]\\\
- end\\\
- return t2\\\
- end\\\
- \\\
- local function recursivePoint( x, y, map, finx, finy, paths, path, checked )\\\
- checked[y] = checked[y] or {}\\\
- if checked[y][x] then return end\\\
- checked[y][x] = true\\\
- table.insert( path, { x = x, y = y } )\\\
- if x == finx and y == finy then\\\
- table.insert( paths, cloneT( path ) )\\\
- table.remove( path, #path )\\\
- return\\\
- end\\\
- if map[y] and map[y][x] then\\\
- recursivePoint( x - 1, y, map, finx, finy, paths, path, checked )\\\
- recursivePoint( x + 1, y, map, finx, finy, paths, path, checked )\\\
- recursivePoint( x, y - 1, map, finx, finy, paths, path, checked )\\\
- recursivePoint( x, y + 1, map, finx, finy, paths, path, checked )\\\
- end\\\
- table.remove( path, #path )\\\
- end\\\
- \\\
- local function findPath( state )\\\
- local t = states[state].mapdata.path\\\
- local map = {}\\\
- for i = 1, #t do\\\
- map[t[i].y] = map[t[i].y] or {}\\\
- map[t[i].y][t[i].x] = true\\\
- end\\\
- local paths = {}\\\
- recursivePoint( states[state].mapdata.start.x, states[state].mapdata.start.y, map, states[state].mapdata.finish.x, states[state].mapdata.finish.y, paths, {}, {} )\\\
- if not paths[1] then\\\
- return\\\
- end\\\
- local min = #paths[1]\\\
- local minc = 1\\\
- for i = 2, #paths do\\\
- if #paths[i] < min then\\\
- min = #paths[i]\\\
- minc = i\\\
- end\\\
- end\\\
- local path = paths[minc]\\\
- states[state].path = path\\\
- end\\\
- \\\
- local function unitDisplay( state )\\\
- states[state].units = {}\\\
- \\\
- end\\\
- \\\
- local function dispatcher( state )\\\
- local function dispatch( unit )\\\
- local t = {\\\
- unit = setmetatable( {}, { __index = units[unit] } );\\\
- pos = 1;\\\
- }\\\
- states[state].timerProcess:newThread( function()\\\
- for i = 2, #states[state].path do\\\
- sleep( 1 / units[unit].speed )\\\
- t.pos = t.pos + 1\\\
- states[state].changed = true\\\
- end\\\
- if not t.unit.dead then\\\
- states[state].savedata.health = states[state].savedata.health - t.unit.health\\\
- saveState( state )\\\
- end\\\
- for i = 1, #states[state].units do\\\
- if states[state].units[i] == t then\\\
- table.remove( states[state].units, i )\\\
- break\\\
- end\\\
- end\\\
- end )\\\
- table.insert( states[state].units, t )\\\
- end\\\
- states[state].dispatch = function( unit, ... )\\\
- local units = { ... }\\\
- dispatch( unit )\\\
- if #units > 0 then\\\
- states[state].timerProcess:newThread( function()\\\
- for i = 1, #units do\\\
- sleep( .5 )\\\
- dispatch( units[i] )\\\
- end\\\
- end )\\\
- end\\\
- end\\\
- end\\\
- \\\
- local function waveDispatcher( state )\\\
- local s = states[state]\\\
- s.timerProcess:newThread( function()\\\
- for i = s.savedata.stage, #waves do\\\
- if s.savedata.stage ~= i then\\\
- s.savedata.stage = i\\\
- saveState( state )\\\
- end\\\
- s.countdown = 15\\\
- for _ = 1, 15 do\\\
- s.countdown = s.countdown - 1\\\
- sleep( 1 )\\\
- end\\\
- s.countdown = nil\\\
- s.dispatch( unpack( waves[i] ) )\\\
- sleep( #waves[i] * .5 )\\\
- while #s.units > 0 do\\\
- coroutine.yield()\\\
- end\\\
- end\\\
- fs.delete( config.installpath .. \\\"/saves/\\\" .. s.savename )\\\
- s.completed = true\\\
- s.changed = true\\\
- end ).onException = function( _ , err )\\\
- error( err, 0 )\\\
- end\\\
- end\\\
- \\\
- local function coreUI( state )\\\
- local s = states[state]\\\
- local frame = s.frame\\\
- \\\
- frame:newChild( UIKit.UIText( 1, frame.height, frame.width - 6, 1, \\\"\\\" ) ).bc = colours.lightGrey\\\
- frame:newChild( UIKit.UIText( 1, frame.height, 7, 1, \\\"#8&FHealth:\\\" ) )\\\
- frame:newChild( UIKit.UIText( 8, frame.height, 3, 1, function()\\\
- return \\\"#8&F\\\" .. s.savedata.health\\\
- end ) ).bc = colours.lightGrey\\\
- \\\
- frame:newChild( UIKit.UIText( 13, frame.height, 6, 1, \\\"#8&FMoney:\\\" ) )\\\
- frame:newChild( UIKit.UIText( 19, frame.height, 5, 1, function()\\\
- return \\\"#8&F\\\" .. s.savedata.money\\\
- end ) ).bc = colours.lightGrey\\\
- \\\
- frame:newChild( UIKit.UIText( 26, frame.height, 6, 1, \\\"#8&FStage:\\\" ) )\\\
- frame:newChild( UIKit.UIText( 32, frame.height, 2, 1, function()\\\
- return \\\"#8&F\\\" .. s.savedata.stage\\\
- end ) ).bc = colours.lightGrey\\\
- \\\
- frame:newChild( UIKit.UIText( 35, frame.height, frame.width - 40, 1, function()\\\
- if s.countdown then\\\
- return \\\"#8&Fwave in \\\" .. s.countdown\\\
- end\\\
- return \\\"\\\"\\\
- end ) ).bc = colours.lightGrey\\\
- end\\\
- \\\
- local function placementMap( state )\\\
- local banned = {}\\\
- local s = states[state]\\\
- local turrets = s.savedata.turrets\\\
- local path = s.mapdata.path\\\
- \\\
- local function ban( x, y, w, h )\\\
- for _y = 1, h do\\\
- banned[y + _y - 1] = banned[y + _y - 1] or {}\\\
- for _x = 1, w do\\\
- banned[y + _y - 1][x + _x - 1] = true\\\
- end\\\
- end\\\
- end\\\
- \\\
- for i = 1, #path do\\\
- ban( path[i].x - 1, path[i].y, 3, 2 )\\\
- end\\\
- for i = 1, #turrets do\\\
- ban( turrets[i].x - 2, turrets[i].y - 1, 5, 3 )\\\
- end\\\
- \\\
- local t = {}\\\
- for x = 1, s.mapdata.width do\\\
- for y = 1, s.mapdata.height do\\\
- if not banned[y] or not banned[y][x] then\\\
- t[#t+1] = { x = x, y = y }\\\
- end\\\
- end\\\
- end\\\
- \\\
- s.placementMap = t\\\
- end\\\
- \\\
- local function showTurretInfo( state, turret )\\\
- local frame = states[state].frame:newChild( UIKit.UIFrame( states[state].frame.width + 1, 1, 16, states[state].frame.height - 1 ) )\\\
- \\\
- frame:newChild( UIKit.UIText( 1, 1, 1, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
- frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, frame.height, \\\"\\\" ) )\\\
- \\\
- newTween( config.atime, frame, { x = states[state].frame.width - 15 }, \\\"inOutSine\\\" ).round = true\\\
- \\\
- local c = frame:newChild( UIKit.UIText( 1, 1, 1, 1, \\\"#7&0>\\\" ) )\\\
- function c.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = states[state].frame.width + 1 }, \\\"inOutSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- frame:remove()\\\
- end\\\
- end\\\
- \\\
- frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, 1, \\\"#7&0 \\\" .. turret.name ) ).bc = colours.grey\\\
- frame:newChild( UIKit.UIText( 3, 5, frame.width - 3, 1, \\\"&8range\\\" ) )\\\
- frame:newChild( UIKit.UIText( 3, 6, frame.width - 3, 1, turret.range ) )\\\
- frame:newChild( UIKit.UIText( 3, 8, frame.width - 3, 1, \\\"&8rate of fire\\\" ) )\\\
- frame:newChild( UIKit.UIText( 3, 9, frame.width - 3, 1, turret.rateOfFire ) )\\\
- frame:newChild( UIKit.UIText( 3, 11, frame.width - 3, 1, \\\"&8damage\\\" ) )\\\
- frame:newChild( UIKit.UIText( 3, 12, frame.width - 3, 1, turret.damage ) )\\\
- frame:newChild( UIKit.UIText( 3, 14, frame.width - 3, 1, \\\"&8cost\\\" ) )\\\
- frame:newChild( UIKit.UIText( 3, 15, frame.width - 3, 1, turret.cost ) )\\\
- \\\
- frame:newChild( UIKit.UIText( 3, 3, 5, 1, \\\"&8image\\\" ) )\\\
- local w, h = turret.image:getSize()\\\
- local image = frame:newChild( UIKit.UIImage( frame.width - w, 3, w, h, turret.image ) )\\\
- \\\
- local place = frame:newChild( UIKit.UIText( 7, frame.height - 1, 5, 1, \\\"&9place\\\" ) )\\\
- function place.callback:onClick()\\\
- local s = states[state]\\\
- if s.savedata.money < turret.cost then\\\
- local message = s.frame:newChild( UIKit.UIText( 0, s.frame.height - 1, 17, 1, \\\"# &ENot enough money!\\\" ) )\\\
- message.bc = 0\\\
- message:centreX()\\\
- Process.newThread( function()\\\
- sleep( 1.5 )\\\
- message:remove()\\\
- end )\\\
- return\\\
- end\\\
- s.savedata.money = s.savedata.money - turret.cost\\\
- saveState( state )\\\
- local places = s.placementMap\\\
- local buttons = {}\\\
- for i = 1, #places do\\\
- local b = s.content:newChild( UIKit.UIText( places[i].x - s.scrollx, places[i].y - s.scrolly, 1, 1, \\\"#9& \\\" ) )\\\
- function b.callback:onClick()\\\
- for i = 1, #buttons do\\\
- buttons[i]:remove()\\\
- end\\\
- table.insert( s.savedata.turrets, {\\\
- turret = turret;\\\
- lastfire = os.clock() - 1/turret.rateOfFire;\\\
- x = places[i].x;\\\
- y = places[i].y;\\\
- } )\\\
- placementMap( state )\\\
- saveState( state )\\\
- s.changed = true\\\
- end\\\
- table.insert( buttons, b )\\\
- end\\\
- end\\\
- end\\\
- \\\
- local function turretUI( state )\\\
- local frame = states[state].frame:newChild( UIKit.UIFrame( states[state].frame.width - 15, 1, 16, states[state].frame.height - 1 ) )\\\
- \\\
- frame:newChild( UIKit.UIText( 1, 1, 1, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
- frame:newChild( UIKit.UIText( 2, 1, frame.width - 1, frame.height, \\\"\\\" ) )\\\
- local content = frame:newChild( UIKit.UIFrame( 3, 2, frame.width - 4, frame.height - 2 ) )\\\
- local scrollbar = frame:newChild( UIKit.UIScrollBar( frame.width - 1, 2, 1, frame.height - 2, \\\"vertical\\\", content ) )\\\
- \\\
- content:newChild( UIKit.UIText( 0, 1, 8, 1, \\\"Turrets:\\\" ) ):centreX()\\\
- local y = 3\\\
- for i = 1, #turrets do\\\
- local im = turrets[i].image\\\
- local w, h = im:getSize()\\\
- local name = content:newChild( UIKit.UIText( 0, y, #turrets[i].name, 1, turrets[i].name ) )\\\
- name:centreX()\\\
- local image = content:newChild( UIKit.UIImage( 0, y + 1, w, h, im ) )\\\
- image:centreX()\\\
- y = y + h + 2\\\
- function image.callback:onClick()\\\
- showTurretInfo( state, turrets[i] )\\\
- end\\\
- function name.callback:onClick()\\\
- showTurretInfo( state, turrets[i] )\\\
- end\\\
- end\\\
- end\\\
- \\\
- local function turretHandler( state )\\\
- local s = states[state]\\\
- s.bullets = {}\\\
- s.turretHandler = Process \\\"TurretHandler\\\"\\\
- \\\
- s.turretHandler:newThread( function()\\\
- while true do\\\
- local time = os.clock()\\\
- for i = 1, #s.savedata.turrets do\\\
- local t = s.savedata.turrets[i]\\\
- if time - t.lastfire >= 1/t.turret.rateOfFire then\\\
- local r2 = t.turret.range ^ 2\\\
- for i = 1, #s.units do\\\
- if ( s.path[s.units[i].pos].x - t.x ) ^ 2 + ( s.path[s.units[i].pos].y - t.y ) ^ 2 <= r2 then\\\
- \\\
- local b = { x = t.x, y = t.y - 1, bc = t.turret.bullet.bc, tc = t.turret.bullet.tc, char = t.turret.bullet.char }\\\
- local bt = newTween( .3, b, { x = s.path[s.units[i].pos].x, y = s.path[s.units[i].pos].y }, \\\"inSine\\\" )\\\
- bt.round = true\\\
- function bt:onFinish()\\\
- s.timerProcess:newThread( function()\\\
- sleep( .1 )\\\
- for i = 1, #s.bullets do\\\
- if s.bullets[i] == b then\\\
- table.remove( s.bullets, i )\\\
- break\\\
- end\\\
- end\\\
- end )\\\
- end\\\
- table.insert( s.bullets, b )\\\
- if type( b.bc ) == \\\"function\\\" then setfenv( b.bc, { math = math } ) end\\\
- if type( b.tc ) == \\\"function\\\" then setfenv( b.tc, { math = math } ) end\\\
- if type( b.char ) == \\\"function\\\" then setfenv( b.char, { math = math } ) end\\\
- \\\
- s.units[i].unit.health = s.units[i].unit.health - t.turret.damage\\\
- if s.units[i].unit.health <= 0 then\\\
- s.units[i].dead = true\\\
- s.savedata.money = s.savedata.money + s.units[i].unit.reward\\\
- table.remove( s.units, i )\\\
- s.changed = true\\\
- end\\\
- t.lastfire = time\\\
- break\\\
- end\\\
- end\\\
- end\\\
- end\\\
- coroutine.yield()\\\
- end\\\
- end ).onException = function( _, err )\\\
- error( err, 0 )\\\
- end\\\
- end\\\
- \\\
- return function( savename )\\\
- \\\
- local state = {}\\\
- states[state] = {}\\\
- states[state].savename = savename\\\
- \\\
- local frame = window:newChild( UIKit.UIFrame( 1 - config.width, 1, config.width, config.height ) )\\\
- local content = frame:newChild( UIKit.UIFrame( 1, 1, frame.width, frame.height ) )\\\
- local back = frame:newChild( UIKit.UIText( frame.width - 5, frame.height, 6, 1, \\\"#7&8< exit\\\" ) )\\\
- function back.callback:onClick()\\\
- endState( state )\\\
- end\\\
- \\\
- local i = newTween( config.atime, frame, { x = 1 }, \\\"outSine\\\" )\\\
- i.round = true\\\
- \\\
- states[state].frame = frame\\\
- states[state].content = content\\\
- states[state].UIProcess = Process \\\"UIProcess\\\"\\\
- states[state].timerProcess = Process \\\"TimerProcess\\\"\\\
- \\\
- if not loaddata( savename, state ) then\\\
- return\\\
- end\\\
- displayVars( state )\\\
- mapDisplay( state )\\\
- findPath( state )\\\
- unitDisplay( state )\\\
- dispatcher( state )\\\
- placementMap( state )\\\
- coreUI( state )\\\
- turretUI( state )\\\
- turretHandler( state )\\\
- waveDispatcher( state )\\\
- \\\
- states[state].UIProcess:newThread( function()\\\
- local s = states[state]\\\
- local function pixel( x, y, bc, tc, char )\\\
- s.buffer:setPixel( x - s.scrollx, y - s.scrolly, bc, tc, char )\\\
- end\\\
- while true do\\\
- if s.changed then\\\
- s.buffer:foreach( function()\\\
- return 1, 1, \\\" \\\"\\\
- end )\\\
- if s.completed then\\\
- s.display:remove()\\\
- s.frame:newChild( UIKit.UIText( math.floor( ( s.frame.width - 16 ) / 2 - 5 ), math.floor( s.frame.height / 2 ), 10, 1, \\\"Completed!\\\" ) )\\\
- s.UIProcess:stop()\\\
- s.timerProcess:stop()\\\
- s.turretHandler:stop()\\\
- else\\\
- s.map:foreach( function( bc, tc, char, x, y )\\\
- pixel( x, y, bc, tc, char )\\\
- end )\\\
- for i = 1, #s.savedata.turrets do\\\
- local im = s.savedata.turrets[i].turret.image\\\
- im:foreach( function( bc, tc, char, xx, yy )\\\
- local posx = xx + s.savedata.turrets[i].x - im:getSize() / 2 - 1\\\
- local posy = yy + s.savedata.turrets[i].y - select( 2, im:getSize() )\\\
- pixel( posx, posy, bc, tc, char )\\\
- end )\\\
- end\\\
- for i = 1, #s.units do\\\
- local im = s.units[i].unit.image\\\
- im:foreach( function( bc, tc, char, xx, yy )\\\
- local posx = xx + s.path[s.units[i].pos].x - im:getSize() / 2 - 1\\\
- local posy = yy + s.path[s.units[i].pos].y - select( 2, im:getSize() )\\\
- pixel( posx, posy, bc, tc, char )\\\
- end )\\\
- end\\\
- for i = 1, #s.bullets do\\\
- pixel( s.bullets[i].x, s.bullets[i].y, s.bullets[i].bc, s.bullets[i].tc, s.bullets[i].char )\\\
- end\\\
- end\\\
- s.changed = false\\\
- end\\\
- coroutine.yield()\\\
- end\\\
- end ).onException = function( _, err )\\\
- error( err, 0 )\\\
- end\\\
- end\"}\
- files[12]={name=\"mapUI\";mode='lib';content=\"\\\
- return function( map )\\\
- \\\
- local frame = window:newChild( UIKit.UIFrame( 1 - config.width, 1, config.width, config.height ) )\\\
- local i = newTween( config.atime, frame, { x = 1 }, \\\"outSine\\\" )\\\
- i.round = true\\\
- \\\
- local content = frame:newChild( UIKit.UIFrame( 1, 1, frame.width, frame.height ) )\\\
- \\\
- local UIProcess = Process \\\"UIProcess\\\"\\\
- \\\
- local back = frame:newChild( UIKit.UIText( 1, frame.height, 6, 1, \\\"#7&8< back\\\" ) )\\\
- function back.callback:onClick()\\\
- local r = newTween( config.atime, frame, { x = config.width + 1 }, \\\"inOutSine\\\" )\\\
- newTween( config.atime, background, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
- r.round = true\\\
- UIProcess:stop()\\\
- function r:onFinish()\\\
- frame:remove()\\\
- menuUI()\\\
- end\\\
- end\\\
- \\\
- local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. map, \\\"r\\\" )\\\
- if not h then\\\
- content:newChild( UIKit.UIText( 0, 0, 19, 1, \\\"&ECouldn't load map.\\\" ) ):centre()\\\
- return\\\
- end\\\
- \\\
- local mapdata = textutils.unserialize( \\\"{\\\" .. h.readAll() .. \\\"}\\\" )\\\
- h.close()\\\
- \\\
- if type( mapdata ) ~= \\\"table\\\" then\\\
- content:newChild( UIKit.UIText( 0, 0, 12, 1, \\\"&ECorrupt map.\\\" ) ):centre()\\\
- return\\\
- end\\\
- \\\
- local background = Gfx2D.Image( mapdata.width, mapdata.height )\\\
- background:foreach( function()\\\
- return colours.green\\\
- end )\\\
- for i = 1, mapdata.width * mapdata.height / 10 do\\\
- local x = math.random( 1, mapdata.width )\\\
- local y = math.random( 2, mapdata.height )\\\
- background:setPixel( x, y, colours.green, colours.lime, \\\"v\\\" )\\\
- end\\\
- \\\
- local scrollx, scrolly = 0, 0\\\
- \\\
- local buffer = Gfx2D.Image( content.width, content.height )\\\
- local display = content:newChild( UIKit.UIImage( 1, 1, content.width, content.height, buffer ) )\\\
- local changed = true\\\
- \\\
- local function drawAll()\\\
- local function pixel( x, y, bc, tc, char )\\\
- buffer:setPixel( x - scrollx, y - scrolly, bc, tc, char )\\\
- end\\\
- \\\
- while true do\\\
- if changed then\\\
- buffer:foreach( function()\\\
- return 1, 1, \\\" \\\"\\\
- end )\\\
- background:foreach( function( bc, tc, char, x, y )\\\
- pixel( x, y, bc, tc, char )\\\
- end )\\\
- for i = 1, #mapdata.path do\\\
- pixel( mapdata.path[i].x, mapdata.path[i].y, colours.grey, 1, \\\" \\\" )\\\
- end\\\
- pixel( mapdata.start.x, mapdata.start.y, colours.blue, 1, \\\" \\\" )\\\
- pixel( mapdata.finish.x, mapdata.finish.y, colours.magenta, 1, \\\" \\\" )\\\
- changed = false\\\
- end\\\
- coroutine.yield()\\\
- end\\\
- end\\\
- \\\
- frame:newChild( UIKit.UIText( frame.width - 5, 1, 6, frame.height, \\\"\\\" ) ).bc = colours.lightGrey\\\
- local plus = frame:newChild( UIKit.UIImage( frame.width - 4, 1, 5, 5, images.plus ) )\\\
- local move = frame:newChild( UIKit.UIImage( frame.width - 4, 7, 5, 5, images.move ) )\\\
- local delete = frame:newChild( UIKit.UIImage( frame.width - 4, 13, 5, 5, images.delete ) )\\\
- local save = frame:newChild( UIKit.UIText( frame.width - 4, frame.height, 4, 1, \\\"#8&7save\\\" ) )\\\
- \\\
- local tool = \\\"move\\\"\\\
- \\\
- function plus.callback:onClick()\\\
- tool = \\\"add\\\"\\\
- end\\\
- function move.callback:onClick()\\\
- tool = \\\"move\\\"\\\
- end\\\
- function delete.callback:onClick()\\\
- tool = \\\"delete\\\"\\\
- end\\\
- \\\
- function display.callback:onClick( button, x, y )\\\
- if tool == \\\"delete\\\" then\\\
- for i = 1, #mapdata.path do\\\
- if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
- table.remove( mapdata.path, i )\\\
- changed = true\\\
- return\\\
- end\\\
- end\\\
- elseif tool == \\\"add\\\" then\\\
- for i = 1, #mapdata.path do\\\
- if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
- return\\\
- end\\\
- end\\\
- changed = true\\\
- table.insert( mapdata.path, { x = x + scrollx, y = y + scrolly } )\\\
- end\\\
- end\\\
- \\\
- function display.callback:onDrag( button, x, y, lx, ly )\\\
- if tool == \\\"move\\\" then\\\
- changed = true\\\
- scrollx = scrollx - x + lx\\\
- scrolly = scrolly - y + ly\\\
- elseif tool == \\\"delete\\\" then\\\
- for i = 1, #mapdata.path do\\\
- if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
- table.remove( mapdata.path, i )\\\
- changed = true\\\
- return\\\
- end\\\
- end\\\
- elseif tool == \\\"add\\\" then\\\
- for i = 1, #mapdata.path do\\\
- if mapdata.path[i].x == x + scrollx and mapdata.path[i].y == y + scrolly then\\\
- return\\\
- end\\\
- end\\\
- changed = true\\\
- table.insert( mapdata.path, { x = x + scrollx, y = y + scrolly } )\\\
- end\\\
- end\\\
- \\\
- function save.callback:onClick()\\\
- local h = fs.open( config.installpath .. \\\"/assets/maps/\\\" .. map, \\\"w\\\" )\\\
- if h then\\\
- h.write( textutils.serialize( mapdata ):sub( 2, -2 ) )\\\
- h.close()\\\
- else\\\
- local t = frame:newChild( UIKit.UIText( 1, 1, 14, 1, \\\"# &ECouldn't save.\\\" ) )\\\
- UIProcess:newThread( function()\\\
- sleep( config.sleep )\\\
- t:remove()\\\
- end )\\\
- end\\\
- end\\\
- \\\
- function i:onFinish()\\\
- UIProcess:newThread( drawAll ).onException = function( _, err )\\\
- error( err, 0 )\\\
- end\\\
- end\\\
- end\"}\
- files[13]={name=\"menuUI\";mode='lib';content=\"\\\
- return function()\\\
- local menuFrame = window:newChild( UIKit.UIFrame( 1, 1, config.width, config.height ) )\\\
- \\\
- local ng = menuFrame:newChild( UIKit.UIText( config.width + 1, 7, 8, 1, \\\"#7&8New Game\\\" ) )\\\
- local lg = menuFrame:newChild( UIKit.UIText( config.width + 1, 8, 9, 1, \\\"#7&8Load Game\\\" ) )\\\
- local cm = menuFrame:newChild( UIKit.UIText( config.width + 1, 10, 10, 1, \\\"#7&8Create Map\\\" ) )\\\
- local em = menuFrame:newChild( UIKit.UIText( config.width + 1, 11, 8, 1, \\\"#7&8Edit Map\\\" ) )\\\
- local qg = menuFrame:newChild( UIKit.UIText( config.width + 1, 14, 9, 1, \\\"#7&8Quit Game\\\" ) )\\\
- newTween( config.atime, ng, { x = 33 }, \\\"outSine\\\" ).round = true\\\
- newTween( config.atime, lg, { x = 33 }, \\\"outSine\\\" ).round = true\\\
- newTween( config.atime, cm, { x = 33 }, \\\"outSine\\\" ).round = true\\\
- newTween( config.atime, em, { x = 33 }, \\\"outSine\\\" ).round = true\\\
- newTween( config.atime, qg, { x = 33 }, \\\"outSine\\\" ).round = true\\\
- \\\
- function ng.callback:onClick()\\\
- local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- menuFrame:remove()\\\
- newGameUI()\\\
- end\\\
- end\\\
- function lg.callback:onClick()\\\
- local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- menuFrame:remove()\\\
- loadGameUI()\\\
- end\\\
- end\\\
- function cm.callback:onClick()\\\
- local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- menuFrame:remove()\\\
- createMapUI()\\\
- end\\\
- end\\\
- function em.callback:onClick()\\\
- local r = newTween( config.atime, menuFrame, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- r.round = true\\\
- function r:onFinish()\\\
- menuFrame:remove()\\\
- editMapUI()\\\
- end\\\
- end\\\
- function qg.callback:onClick()\\\
- global.running = false\\\
- end\\\
- end\"}\
- apiCount=0\
- dependencies[1]=\"Gfx2D.lua\"\
- dependencies[2]=\"Math2D.lua\"\
- dependencies[3]=\"Process.lua\"\
- dependencies[4]=\"Traceback.lua\"\
- dependencies[5]=\"Tween.lua\"\
- dependencies[6]=\"UIKit.lua\"\
- mainContent=\"\\\
- Gfx2D.buffer.current().allchanged = true\\\
- \\\
- global.windowManager = UIKit.WindowManager()\\\
- global.window = windowManager:newWindow( config.target, config.width, config.height )\\\
- global.tweens = {}\\\
- global.running = true\\\
- \\\
- local p = windowManager:run()\\\
- p.onException = function( _, err )\\\
- error( err, 0 )\\\
- end\\\
- \\\
- local ok, err = xpcall( function()\\\
- \\\
- function global.newTween( ... )\\\
- local tween = Tween.new( ... )\\\
- table.insert( tweens, tween )\\\
- return tween\\\
- end\\\
- \\\
- global.background = window:newChild( UIKit.UIImage( 1, 1, config.width, config.height, images.logo ) )\\\
- \\\
- local creators = window:newChild( UIKit.UIText( 33, 9, 15, 3, \\\"#7&8by\\\\n&0Benedict Allen\\\\nRequiem\\\" ) )\\\
- creators.bc = colours.grey\\\
- creators.align = \\\"top, centre\\\"\\\
- creators:wrap()\\\
- creators:reload()\\\
- \\\
- Process.newThread( function()\\\
- sleep( config.sleep )\\\
- local ct = newTween( config.atime, creators, { x = config.width + 1 }, \\\"inSine\\\" )\\\
- ct.round = true\\\
- function ct:onFinish()\\\
- creators:remove()\\\
- menuUI()\\\
- end\\\
- end ).onException = function( _, err )\\\
- error( err, 0 )\\\
- end\\\
- \\\
- -----------------------------------------------------------------------------------------------------------\\\
- \\\
- local _running = true\\\
- \\\
- local time = os.clock()\\\
- local timer = os.startTimer( 0 )\\\
- while running or _running do\\\
- if not running then\\\
- local backwin = windowManager:newWindow( config.target, config.width, config.height )\\\
- backwin:newChild( UIKit.UIText( 1, 1, config.width, config.height ) ).bc = 32768\\\
- backwin.y = config.height\\\
- local r = newTween( config.atime, window, { y = 1 - config.height }, \\\"inOutSine\\\" )\\\
- newTween( config.atime, backwin, { y = 1 }, \\\"inOutSine\\\" ).round = true\\\
- r.round = true\\\
- function r:onFinish()\\\
- backwin:remove()\\\
- _running = false\\\
- end\\\
- _running = config.atime\\\
- end\\\
- local ev = { coroutine.yield() }\\\
- if ev[1] == \\\"timer\\\" and ev[2] == timer then\\\
- local dt = os.clock() - time\\\
- time = os.clock()\\\
- timer = os.startTimer( 0.05 )\\\
- \\\
- if type( _running ) == \\\"number\\\" then\\\
- _running = _running - dt\\\
- end\\\
- \\\
- for i = #tweens, 1, -1 do\\\
- tweens[i]:update( dt )\\\
- if tweens[i].clock == tweens[i].duration then\\\
- if type( tweens[i].onFinish ) == \\\"function\\\" then\\\
- tweens[i]:onFinish()\\\
- end\\\
- table.remove( tweens, i )\\\
- end\\\
- end\\\
- Process.resume( \\\"update\\\", dt )\\\
- elseif ev[1] == \\\"terminate\\\" then\\\
- running = false\\\
- else\\\
- Process.resume( unpack( ev ) )\\\
- end\\\
- end\\\
- \\\
- end, function( err, lvl )\\\
- local t = Traceback( 2 )\\\
- local str = tostring( err )\\\
- local x = false\\\
- for i = 1, #t do\\\
- if t[i] == \\\"xpcall\\\" then\\\
- x = true\\\
- end\\\
- if x and t[i] == \\\"[NightFall] main:14\\\" then\\\
- for e = 1, i - 2 do\\\
- str = str .. \\\"\\\\n in \\\" .. t[e]\\\
- end\\\
- break\\\
- end\\\
- end\\\
- term.setBackgroundColour( colours.black )\\\
- printError( str )\\\
- end )\\\
- \\\
- window:remove()\\\
- p:stop()\\\
- \\\
- if not ok then\\\
- return\\\
- end\\\
- \\\
- term.setBackgroundColour( 32768 )\\\
- term.clear()\\\
- term.setCursorPos( 1, 1 )\\\
- \\\
- print \\\"Thank you for playing NightFall\\\"\"\
- local env = setmetatable( {}, { __index = getfenv() } )\
- env.global = env\
- env.args = { ... }\
- local public = {}\
- local bloaded = _G[\"_bundleLoaded\"]\
- if type( bloaded ) ~= \"table\" then bloaded = {} _G[\"_bundleLoaded\"] = bloaded end\
- \
- if bloaded[name] and not mainContent then\
- return bloaded[name]\
- end\
- \
- for i = 1, #dependencies do\
- if bloaded and bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[dependencies[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. dependencies[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[dependencies[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- else\
- error( name .. \" requires bundle '\" .. dependencies[i] .. \"'\", 0 )\
- end\
- end\
- end\
- for i = 1, #requires do\
- if bloaded and bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)] then\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = bloaded[requires[i]:gsub(\"%.lua$\", \"\", 1)]\
- else\
- local path = ( _G[\"_bundleDependencyPath\"] or \"\" ) .. \"/\" .. requires[i]\
- local f, err = loadfile( path )\
- if f then\
- setfenv( f, getfenv() )\
- env[requires[i]:gsub(\"%.lua$\", \"\", 1)] = f()\
- end\
- end\
- end\
- \
- for i = 1, #files do\
- local f, err = loadstring( files[i].content, \"[\" .. name .. \"] \" .. files[i].name )\
- if f then\
- local e = setmetatable( {}, { __index = env } )\
- setfenv( f, e )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- break\
- end\
- if data == nil then\
- data = {}\
- for k, v in pairs( e ) do\
- data[k] = v\
- end\
- end\
- if files[i].mode == \"api\" then\
- if apiCount == 1 then\
- public = data\
- else\
- public[files[i].name] = data\
- env[files[i].name] = data\
- end\
- else\
- env[files[i].name] = data\
- end\
- else\
- printError( err )\
- break\
- end\
- end\
- \
- if mainContent then\
- local f, err = loadstring( mainContent, \"[\" .. name .. \"] main\" )\
- if f then\
- setfenv( f, env )\
- local ok, data = pcall( f, ... )\
- if not ok then\
- printError( data )\
- end\
- else\
- printError( err )\
- end\
- end\
- \
- bloaded[name] = public\
- return public";["assets"]={["turrets"]={["5"]="name=\"Laser\";\
- range=20;\
- rateOfFire=.5;\
- damage=10;\
- cost=250;\
- image=\" E0 \\nF0 80 F0 \";\
- bullet = {\
- bc = 16384;\
- tc = 1;\
- char = \" \";\
- };";["4"]="name=\"Cannon\";\
- range=4;\
- rateOfFire=.1;\
- damage=10;\
- cost=100;\
- image=\"F0 F0 80 \\n 80 80 \";\
- bullet = {\
- bc = 0;\
- tc = 16;\
- char = \"@\";\
- };";["1"]="name=\"Heavy Gun\";\
- range=6;\
- rateOfFire=.25;\
- damage=2;\
- cost=40;\
- image=\" F-F0 80 \\n80 80 80 \";\
- bullet = {\
- bc = 0;\
- tc = 16;\
- char = \"o\";\
- };";["0"]="name=\"Basic Gun\";\
- range=5;\
- rateOfFire=.5;\
- damage=1;\
- cost=20;\
- image=\" F-F0 \\n 80 \";\
- bullet = {\
- bc = 0;\
- tc = 16;\
- char = \".\";\
- };";["3"]="name=\"Flamethrower\";\
- range=10;\
- rateOfFire=10;\
- damage=.2;\
- cost=50;\
- image=\" F-F0 E0 \\n80 80 E0 \";\
- bullet = {\
- bc = function()\
- local cols = { 2 ^ 14, 16, 2 }\
- return cols[math.random( 1, 3 )]\
- end;\
- tc = 1;\
- char = \" \";\
- };";["2"]="name=\"Machine Gun\";\
- range=8;\
- rateOfFire=3;\
- damage=.5;\
- cost=50;\
- image=\" F-F0 8F=\\n80 80 8F=\";\
- bullet = {\
- bc = 0;\
- tc = 16;\
- char = \".\";\
- };"};["maps"]={["map1"]="\
- start = {\
- y = 1,\
- x = 1,\
- },\
- width = 35,\
- assets = {},\
- height = 18,\
- finish = {\
- y = 18,\
- x = 35,\
- },\
- path = {\
- {\
- y = 1,\
- x = 1,\
- },\
- {\
- y = 1,\
- x = 2,\
- },\
- {\
- y = 1,\
- x = 3,\
- },\
- {\
- y = 1,\
- x = 4,\
- },\
- {\
- y = 1,\
- x = 5,\
- },\
- {\
- y = 1,\
- x = 6,\
- },\
- {\
- y = 1,\
- x = 7,\
- },\
- {\
- y = 1,\
- x = 8,\
- },\
- {\
- y = 1,\
- x = 9,\
- },\
- {\
- y = 1,\
- x = 10,\
- },\
- {\
- y = 1,\
- x = 11,\
- },\
- {\
- y = 1,\
- x = 12,\
- },\
- {\
- y = 1,\
- x = 13,\
- },\
- {\
- y = 1,\
- x = 14,\
- },\
- {\
- y = 1,\
- x = 15,\
- },\
- {\
- y = 2,\
- x = 15,\
- },\
- {\
- y = 3,\
- x = 15,\
- },\
- {\
- y = 4,\
- x = 15,\
- },\
- {\
- y = 5,\
- x = 15,\
- },\
- {\
- y = 6,\
- x = 15,\
- },\
- {\
- y = 7,\
- x = 15,\
- },\
- {\
- y = 7,\
- x = 14,\
- },\
- {\
- y = 7,\
- x = 13,\
- },\
- {\
- y = 7,\
- x = 12,\
- },\
- {\
- y = 7,\
- x = 11,\
- },\
- {\
- y = 7,\
- x = 10,\
- },\
- {\
- y = 7,\
- x = 9,\
- },\
- {\
- y = 7,\
- x = 8,\
- },\
- {\
- y = 7,\
- x = 7,\
- },\
- {\
- y = 7,\
- x = 6,\
- },\
- {\
- y = 7,\
- x = 5,\
- },\
- {\
- y = 8,\
- x = 5,\
- },\
- {\
- y = 9,\
- x = 5,\
- },\
- {\
- y = 10,\
- x = 5,\
- },\
- {\
- y = 11,\
- x = 5,\
- },\
- {\
- y = 11,\
- x = 22,\
- },\
- {\
- y = 4,\
- x = 25,\
- },\
- {\
- y = 4,\
- x = 26,\
- },\
- {\
- y = 4,\
- x = 27,\
- },\
- {\
- y = 4,\
- x = 28,\
- },\
- {\
- y = 4,\
- x = 29,\
- },\
- {\
- y = 18,\
- x = 31,\
- },\
- {\
- y = 18,\
- x = 32,\
- },\
- {\
- y = 18,\
- x = 33,\
- },\
- {\
- y = 18,\
- x = 34,\
- },\
- {\
- y = 18,\
- x = 35,\
- },\
- {\
- y = 4,\
- x = 24,\
- },\
- {\
- y = 10,\
- x = 22,\
- },\
- {\
- y = 9,\
- x = 22,\
- },\
- {\
- y = 8,\
- x = 22,\
- },\
- {\
- y = 7,\
- x = 22,\
- },\
- {\
- y = 6,\
- x = 22,\
- },\
- {\
- y = 5,\
- x = 22,\
- },\
- {\
- y = 4,\
- x = 22,\
- },\
- {\
- y = 4,\
- x = 23,\
- },\
- {\
- y = 13,\
- x = 22,\
- },\
- {\
- y = 13,\
- x = 21,\
- },\
- {\
- y = 13,\
- x = 20,\
- },\
- {\
- y = 13,\
- x = 19,\
- },\
- {\
- y = 13,\
- x = 18,\
- },\
- {\
- y = 13,\
- x = 17,\
- },\
- {\
- y = 13,\
- x = 16,\
- },\
- {\
- y = 13,\
- x = 15,\
- },\
- {\
- y = 13,\
- x = 14,\
- },\
- {\
- y = 13,\
- x = 13,\
- },\
- {\
- y = 13,\
- x = 12,\
- },\
- {\
- y = 13,\
- x = 11,\
- },\
- {\
- y = 13,\
- x = 10,\
- },\
- {\
- y = 13,\
- x = 9,\
- },\
- {\
- y = 13,\
- x = 8,\
- },\
- {\
- y = 13,\
- x = 7,\
- },\
- {\
- y = 13,\
- x = 6,\
- },\
- {\
- y = 13,\
- x = 5,\
- },\
- {\
- y = 12,\
- x = 5,\
- },\
- {\
- y = 12,\
- x = 22,\
- },\
- {\
- y = 9,\
- x = 30,\
- },\
- {\
- y = 10,\
- x = 30,\
- },\
- {\
- y = 11,\
- x = 30,\
- },\
- {\
- y = 12,\
- x = 30,\
- },\
- {\
- y = 18,\
- x = 30,\
- },\
- {\
- y = 17,\
- x = 30,\
- },\
- {\
- y = 16,\
- x = 30,\
- },\
- {\
- y = 15,\
- x = 30,\
- },\
- {\
- y = 13,\
- x = 30,\
- },\
- {\
- y = 14,\
- x = 30,\
- },\
- {\
- y = 8,\
- x = 30,\
- },\
- {\
- y = 7,\
- x = 30,\
- },\
- {\
- y = 6,\
- x = 30,\
- },\
- {\
- y = 5,\
- x = 30,\
- },\
- {\
- y = 4,\
- x = 30,\
- },\
- },";["map2"]="\
- start = {\
- y = 1,\
- x = 1,\
- },\
- width = 35,\
- assets = {},\
- height = 18,\
- finish = {\
- y = 18,\
- x = 35,\
- },\
- path = {\
- {\
- y = 1,\
- x = 1,\
- },\
- {\
- y = 1,\
- x = 2,\
- },\
- {\
- y = 1,\
- x = 3,\
- },\
- {\
- y = 1,\
- x = 4,\
- },\
- {\
- y = 1,\
- x = 5,\
- },\
- {\
- y = 1,\
- x = 6,\
- },\
- {\
- y = 1,\
- x = 7,\
- },\
- {\
- y = 1,\
- x = 8,\
- },\
- {\
- y = 1,\
- x = 9,\
- },\
- {\
- y = 1,\
- x = 10,\
- },\
- {\
- y = 2,\
- x = 10,\
- },\
- {\
- y = 3,\
- x = 10,\
- },\
- {\
- y = 4,\
- x = 10,\
- },\
- {\
- y = 5,\
- x = 10,\
- },\
- {\
- y = 6,\
- x = 10,\
- },\
- {\
- y = 6,\
- x = 9,\
- },\
- {\
- y = 7,\
- x = 9,\
- },\
- {\
- y = 8,\
- x = 9,\
- },\
- {\
- y = 8,\
- x = 8,\
- },\
- {\
- y = 8,\
- x = 7,\
- },\
- {\
- y = 9,\
- x = 7,\
- },\
- {\
- y = 10,\
- x = 7,\
- },\
- {\
- y = 11,\
- x = 7,\
- },\
- {\
- y = 12,\
- x = 7,\
- },\
- {\
- y = 12,\
- x = 6,\
- },\
- {\
- y = 12,\
- x = 5,\
- },\
- {\
- y = 12,\
- x = 4,\
- },\
- {\
- y = 13,\
- x = 4,\
- },\
- {\
- y = 14,\
- x = 4,\
- },\
- {\
- y = 15,\
- x = 4,\
- },\
- {\
- y = 15,\
- x = 5,\
- },\
- {\
- y = 15,\
- x = 6,\
- },\
- {\
- y = 15,\
- x = 7,\
- },\
- {\
- y = 15,\
- x = 8,\
- },\
- {\
- y = 15,\
- x = 9,\
- },\
- {\
- y = 15,\
- x = 10,\
- },\
- {\
- y = 15,\
- x = 11,\
- },\
- {\
- y = 15,\
- x = 12,\
- },\
- {\
- y = 15,\
- x = 13,\
- },\
- {\
- y = 15,\
- x = 14,\
- },\
- {\
- y = 15,\
- x = 15,\
- },\
- {\
- y = 15,\
- x = 16,\
- },\
- {\
- y = 15,\
- x = 17,\
- },\
- {\
- y = 15,\
- x = 18,\
- },\
- {\
- y = 14,\
- x = 18,\
- },\
- {\
- y = 13,\
- x = 18,\
- },\
- {\
- y = 12,\
- x = 18,\
- },\
- {\
- y = 11,\
- x = 18,\
- },\
- {\
- y = 10,\
- x = 18,\
- },\
- {\
- y = 10,\
- x = 19,\
- },\
- {\
- y = 10,\
- x = 20,\
- },\
- {\
- y = 10,\
- x = 21,\
- },\
- {\
- y = 10,\
- x = 22,\
- },\
- {\
- y = 9,\
- x = 22,\
- },\
- {\
- y = 8,\
- x = 22,\
- },\
- {\
- y = 7,\
- x = 22,\
- },\
- {\
- y = 6,\
- x = 22,\
- },\
- {\
- y = 5,\
- x = 22,\
- },\
- {\
- y = 5,\
- x = 23,\
- },\
- {\
- y = 5,\
- x = 24,\
- },\
- {\
- y = 5,\
- x = 25,\
- },\
- {\
- y = 5,\
- x = 26,\
- },\
- {\
- y = 5,\
- x = 27,\
- },\
- {\
- y = 5,\
- x = 28,\
- },\
- {\
- y = 5,\
- x = 29,\
- },\
- {\
- y = 6,\
- x = 29,\
- },\
- {\
- y = 7,\
- x = 29,\
- },\
- {\
- y = 8,\
- x = 29,\
- },\
- {\
- y = 9,\
- x = 29,\
- },\
- {\
- y = 10,\
- x = 29,\
- },\
- {\
- y = 11,\
- x = 29,\
- },\
- {\
- y = 12,\
- x = 29,\
- },\
- {\
- y = 13,\
- x = 29,\
- },\
- {\
- y = 14,\
- x = 29,\
- },\
- {\
- y = 15,\
- x = 29,\
- },\
- {\
- y = 16,\
- x = 29,\
- },\
- {\
- y = 17,\
- x = 29,\
- },\
- {\
- y = 18,\
- x = 29,\
- },\
- {\
- y = 18,\
- x = 30,\
- },\
- {\
- y = 18,\
- x = 31,\
- },\
- {\
- y = 18,\
- x = 32,\
- },\
- {\
- y = 18,\
- x = 33,\
- },\
- {\
- y = 18,\
- x = 34,\
- },\
- {\
- y = 18,\
- x = 35,\
- },\
- },"};["units"]={["1"]="name=\"Rifleman\";\
- health=1;\
- speed=5;\
- image=\"50 \\nF0 \";\
- reward=15;";["0"]="name=\"Scout\";\
- health=1;\
- speed=8;\
- image=\"80 \\nF0 \";\
- reward=10;";["3"]="name=\"Sniper\";\
- health=3;\
- speed=3;\
- image=\"B0 \\nF0 \";\
- reward=25;";["2"]="name=\"Machine Gunner\";\
- health=2;\
- speed=5;\
- image=\"70 \\nF0 \";\
- reward=20;";["5"]="name=\"Artillery\";\
- health=20;\
- speed=2;\
- image=\"8F \\n 8F 8F 8F \\nF7oF7oF7oF7oF7o\";\
- reward=50;";["4"]="name=\"Mortar\";\
- health=4;\
- speed=3;\
- image=\"80 \\n80 \";\
- reward=30;";["7"]="name=\"Motorbike\";\
- health=4;\
- speed=10;\
- image=\" D0 \\n FoF0 Fo\";\
- reward=30;";["6"]="name=\"Tank\";\
- health=25;\
- speed=2;\
- image=\" F-5F-5F 5F \\n5F 5F 5F 5F 5F \\nF7oF7oF7oF7oF7o\";\
- reward=80;"}};["launcher"]="\
- _G[\"_bundleDependencyPath\"] = \".nightfall/bundles\"\
- shell.run \".nightfall/NightFall.lua\"";["saves"]={}}
- function ttf( table, dir )
- if not fs.isDir( dir ) then
- fs.makeDir( dir )
- end
- for k, v in pairs( table ) do
- if type( v ) == "table" then
- ttf( v, dir.."/"..k )
- elseif type( v ) == "string" then
- local f = fs.open( dir.."/"..k, "w" )
- f.write( v )
- f.close( )
- end
- end
- end
- ttf( files, path )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement