------------------------------- -- Start of BetterLuaApi.lua -- ------------------------------- -- BetterLuaAPI for the TI-Nspire -- Version 3.5 (March 17th 2014) -- Adriweb 2013 -- http://tiplanet.org - http://inspired-lua.org -- Contributions by LDStudios -- Put all this or some of this (be careful, though, some functions use each other) in your code and thank me ;) ---------------------- ------ Utilities ----- ---------------------- -- Thanks John Powers (TI) ! -- Needed if OS < 3.2 if not platform.withGC then function platform.withGC(f) local gc = platform.gc() gc:begin() local result = { f(gc) } gc:finish() return unpack(result) end end -- Credits to Jim Bauwens :) -- See http://inspired-lua.org/index.php/2013/05/how-to-add-your-own-functions-to-gc/ -- Needed. function AddToGC(key, func) local gcMetatable = platform.withGC(getmetatable) gcMetatable[key] = func end ---------------------- ----- New Things ----- ---------------------- device = { api, hasColor, isCalc, theType, lang } device.api = platform.apilevel device.hasColor = platform.isColorDisplay() device.lang = locale.name() function on.resize(w, h) device.isCalc = platform.window:width() < 320 device.theType = platform.isTabletModeRendering and (platform.isTabletModeRendering() and "tablet" or "software") or (platform.isDeviceModeRendering() and "handheld" or "software") -- put the rest of your resize code here end Color = { ["black"] = { 0, 0, 0 }, ["red"] = { 255, 0, 0 }, ["green"] = { 0, 255, 0 }, ["blue "] = { 0, 0, 255 }, ["white"] = { 255, 255, 255 }, ["brown"] = { 165, 42, 42 }, ["cyan"] = { 0, 255, 255 }, ["darkblue"] = { 0, 0, 139 }, ["darkred"] = { 139, 0, 0 }, ["fuchsia"] = { 255, 0, 255 }, ["gold"] = { 255, 215, 0 }, ["gray"] = { 127, 127, 127 }, ["grey"] = { 127, 127, 127 }, ["lightblue"] = { 173, 216, 230 }, ["lightgreen"] = { 144, 238, 144 }, ["magenta"] = { 255, 0, 255 }, ["maroon"] = { 128, 0, 0 }, ["navyblue"] = { 159, 175, 223 }, ["orange"] = { 255, 165, 0 }, ["palegreen"] = { 152, 251, 152 }, ["pink"] = { 255, 192, 203 }, ["purple"] = { 128, 0, 128 }, ["royalblue"] = { 65, 105, 225 }, ["salmon"] = { 250, 128, 114 }, ["seagreen"] = { 46, 139, 87 }, ["silver"] = { 192, 192, 192 }, ["turquoise"] = { 64, 224, 208 }, ["violet"] = { 238, 130, 238 }, ["yellow"] = { 255, 255, 0 } } Color.mt = { __index = function() return { 0, 0, 0 } end } setmetatable(Color, Color.mt) local function copyTable(t) local t2 = {} for k, v in pairs(t) do t2[k] = v end return t2 end -- This function recursively copies a table's contents, and ensures that metatables are preserved. -- That is, it will correctly clone a pure Lua object. -- Taken from http://snippets.luacode.org/snippets/Deep_copy_of_a_Lua_Table_2 local function deepcopy(t) if type(t) ~= 'table' then return t end local mt = getmetatable(t) local res = {} for k, v in pairs(t) do if type(v) == 'table' then v = deepcopy(v) end res[k] = v end setmetatable(res, mt) return res end local function test(arg) return arg and 1 or 0 end local function uCol(col) return col[1], col[2], col[3] end local function screenRefresh() return platform.window:invalidate() end local function pww() return platform.window:width() end local function pwh() return platform.window:height() end local function drawPoint(gc, x, y) gc:fillRect(x, y, 1, 1) end local function drawCircle(gc, x, y, r) gc:drawArc(x-r, y-r, 2*r, 2*r, 0, 360) end local function fillCircle(gc, x, y, r) gc:fillArc(x-r, y-r, 2*r, 2*r, 0, 360) end local function fillGradientRect(gc,x,y,w,h,color1,color2,d) local l = {w,x} if d==2 then l = {h,y} end for i=l[2],l[1]+l[2] do gc:setColorRGB(color1[1],color1[2],color1[3]) if d==1 then gc:fillRect(i,y,1,h) else gc:fillRect(x,i,w,1) end color1={color1[1]+(color1[1]-color2[1])/(i-l[1]-l[2]),color1[2]+(color1[2]-color2[2])/(i-l[1]-l[2]),color1[3]+(color1[3]-color2[3])/(i-l[1]-l[2])} end end local function fillGradientCircle(gc,x,y,r,color1,color2) for i=0,r do gc:setColorRGB(color1[1],color1[2],color1[3]) gc:setPen("thick") drawCircle(gc,x,y,i) color1={color1[1]+(color2[1]-color1[1])/(r-i),color1[2]+(color2[2]-color1[2])/(r-i),color1[3]+(color2[3]-color1[3])/(r-i)} end end local function drawThickCircle(gc,x,y,r,r2) gc:setPen("thick") for i=r,r2 do drawCircle(gc,x,y,i) end end local function drawCenteredString(gc, str) gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, platform.window:height() / 2, "middle") end local function drawXCenteredString(gc, str, y) gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, y, "top") end local function setColor(gc, theColor) if type(theColor) == "string" then theColor = theColor:lower() if type(Color[theColor]) == "table" then gc:setColorRGB(uCol(Color[theColor])) end elseif type(theColor) == "table" then gc:setColorRGB(uCol(theColor)) end end local function verticalBar(gc, x) gc:fillRect(x, 0, 1, platform.window:height()) end local function horizontalBar(gc, y) gc:fillRect(0, y, platform.window:width(), 1) end local function drawSquare(gc, x, y, l) gc:drawPolyLine({ (x - l / 2), (y - l / 2), (x + l / 2), (y - l / 2), (x + l / 2), (y + l / 2), (x - l / 2), (y + l / 2), (x - l / 2), (y - l / 2) }) end local function drawRoundRect(gc, x, y, wd, ht, rd) -- wd = width, ht = height, rd = radius of the rounded corner local x = x - wd / 2 -- let the center of the square be the origin (x coord) local y = y - ht / 2 -- same for y coord if rd > ht / 2 then rd = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max rd) gc:drawLine(x + rd, y, x + wd - (rd), y) gc:drawArc(x + wd - (rd * 2), y + ht - (rd * 2), rd * 2, rd * 2, 270, 90) gc:drawLine(x + wd, y + rd, x + wd, y + ht - (rd)) gc:drawArc(x + wd - (rd * 2), y, rd * 2, rd * 2, 0, 90) gc:drawLine(x + wd - (rd), y + ht, x + rd, y + ht) gc:drawArc(x, y, rd * 2, rd * 2, 90, 90) gc:drawLine(x, y + ht - (rd), x, y + rd) gc:drawArc(x, y + ht - (rd * 2), rd * 2, rd * 2, 180, 90) end local function fillRoundRect(gc, x, y, wd, ht, radius) -- wd = width and ht = height -- renders badly when transparency (alpha) is not at maximum >< will re-code later if radius > ht / 2 then radius = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max radius) gc:fillPolygon({ (x - wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y - ht / 2 + radius) }) gc:fillPolygon({ (x - wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y + ht / 2), (x - wd / 2 + radius), (y + ht / 2), (x - wd / 2 + radius), (y - ht / 2) }) local x = x - wd / 2 -- let the center of the square be the origin (x coord) local y = y - ht / 2 -- same gc:fillArc(x + wd - (radius * 2), y + ht - (radius * 2), radius * 2, radius * 2, 1, -91) gc:fillArc(x + wd - (radius * 2), y, radius * 2, radius * 2, -2, 91) gc:fillArc(x, y, radius * 2, radius * 2, 85, 95) gc:fillArc(x, y + ht - (radius * 2), radius * 2, radius * 2, 180, 95) end local function clearWindow(gc, theColor) gc:setColor(theColor) -- will handle both strings like "red" and direct colors like {255,0,0} gc:fillRect(0, 0, platform.window:width(), platform.window:height()) end ----------------------------------------- ------ Adding the functions to gc ------- ----------------------------------------- AddToGC("setColor", setColor) AddToGC("drawPoint", drawPoint) AddToGC("drawCircle", drawCircle) AddToGC("fillCircle", fillCircle) AddToGC("drawThickCircle", drawThickCircle) AddToGC("fillGradientCircle", fillGradientCircle) AddToGC("drawGradientRect", drawGradientRect) AddToGC("drawSquare", drawSquare) AddToGC("drawRoundRect", drawRoundRect) AddToGC("fillRoundRect", fillRoundRect) AddToGC("verticalBar", verticalBar) AddToGC("horizontalBar", horizontalBar) AddToGC("drawCenteredString", drawCenteredString) AddToGC("drawXCenteredString", drawXCenteredString) AddToGC("clearWindow", clearWindow) ----------------------------- -- End of BetterLuaApi.lua -- ----------------------------- ----------------------- -- Start of glib.lua -- ----------------------- ------------------------------- -- Start of BetterLuaApi.lua -- ------------------------------- -- BetterLuaAPI for the TI-Nspire -- Version 3.5 (March 17th 2014) -- Adriweb 2013 -- http://tiplanet.org - http://inspired-lua.org -- Contributions by LDStudios -- Put all this or some of this (be careful, though, some functions use each other) in your code and thank me ;) ---------------------- ------ Utilities ----- ---------------------- -- Thanks John Powers (TI) ! -- Needed if OS < 3.2 if not platform.withGC then function platform.withGC(f) local gc = platform.gc() gc:begin() local result = { f(gc) } gc:finish() return unpack(result) end end -- Credits to Jim Bauwens :) -- See http://inspired-lua.org/index.php/2013/05/how-to-add-your-own-functions-to-gc/ -- Needed. function AddToGC(key, func) local gcMetatable = platform.withGC(getmetatable) gcMetatable[key] = func end ---------------------- ----- New Things ----- ---------------------- device = { api, hasColor, isCalc, theType, lang } device.api = platform.apilevel device.hasColor = platform.isColorDisplay() device.lang = locale.name() function on.resize(w, h) device.isCalc = platform.window:width() < 320 device.theType = platform.isTabletModeRendering and (platform.isTabletModeRendering() and "tablet" or "software") or (platform.isDeviceModeRendering() and "handheld" or "software") -- put the rest of your resize code here end Color = { ["black"] = { 0, 0, 0 }, ["red"] = { 255, 0, 0 }, ["green"] = { 0, 255, 0 }, ["blue "] = { 0, 0, 255 }, ["white"] = { 255, 255, 255 }, ["brown"] = { 165, 42, 42 }, ["cyan"] = { 0, 255, 255 }, ["darkblue"] = { 0, 0, 139 }, ["darkred"] = { 139, 0, 0 }, ["fuchsia"] = { 255, 0, 255 }, ["gold"] = { 255, 215, 0 }, ["gray"] = { 127, 127, 127 }, ["grey"] = { 127, 127, 127 }, ["lightblue"] = { 173, 216, 230 }, ["lightgreen"] = { 144, 238, 144 }, ["magenta"] = { 255, 0, 255 }, ["maroon"] = { 128, 0, 0 }, ["navyblue"] = { 159, 175, 223 }, ["orange"] = { 255, 165, 0 }, ["palegreen"] = { 152, 251, 152 }, ["pink"] = { 255, 192, 203 }, ["purple"] = { 128, 0, 128 }, ["royalblue"] = { 65, 105, 225 }, ["salmon"] = { 250, 128, 114 }, ["seagreen"] = { 46, 139, 87 }, ["silver"] = { 192, 192, 192 }, ["turquoise"] = { 64, 224, 208 }, ["violet"] = { 238, 130, 238 }, ["yellow"] = { 255, 255, 0 } } Color.mt = { __index = function() return { 0, 0, 0 } end } setmetatable(Color, Color.mt) local function copyTable(t) local t2 = {} for k, v in pairs(t) do t2[k] = v end return t2 end -- This function recursively copies a table's contents, and ensures that metatables are preserved. -- That is, it will correctly clone a pure Lua object. -- Taken from http://snippets.luacode.org/snippets/Deep_copy_of_a_Lua_Table_2 local function deepcopy(t) if type(t) ~= 'table' then return t end local mt = getmetatable(t) local res = {} for k, v in pairs(t) do if type(v) == 'table' then v = deepcopy(v) end res[k] = v end setmetatable(res, mt) return res end local function test(arg) return arg and 1 or 0 end local function uCol(col) return col[1], col[2], col[3] end local function screenRefresh() return platform.window:invalidate() end local function pww() return platform.window:width() end local function pwh() return platform.window:height() end local function drawPoint(gc, x, y) gc:fillRect(x, y, 1, 1) end local function drawCircle(gc, x, y, r) gc:drawArc(x-r, y-r, 2*r, 2*r, 0, 360) end local function fillCircle(gc, x, y, r) gc:fillArc(x-r, y-r, 2*r, 2*r, 0, 360) end local function fillGradientRect(gc,x,y,w,h,color1,color2,d) local l = {w,x} if d==2 then l = {h,y} end for i=l[2],l[1]+l[2] do gc:setColorRGB(color1[1],color1[2],color1[3]) if d==1 then gc:fillRect(i,y,1,h) else gc:fillRect(x,i,w,1) end color1={color1[1]+(color1[1]-color2[1])/(i-l[1]-l[2]),color1[2]+(color1[2]-color2[2])/(i-l[1]-l[2]),color1[3]+(color1[3]-color2[3])/(i-l[1]-l[2])} end end local function fillGradientCircle(gc,x,y,r,color1,color2) for i=0,r do gc:setColorRGB(color1[1],color1[2],color1[3]) gc:setPen("thick") drawCircle(gc,x,y,i) color1={color1[1]+(color2[1]-color1[1])/(r-i),color1[2]+(color2[2]-color1[2])/(r-i),color1[3]+(color2[3]-color1[3])/(r-i)} end end local function drawThickCircle(gc,x,y,r,r2) gc:setPen("thick") for i=r,r2 do drawCircle(gc,x,y,i) end end local function drawCenteredString(gc, str) gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, platform.window:height() / 2, "middle") end local function drawXCenteredString(gc, str, y) gc:drawString(str, (platform.window:width() - gc:getStringWidth(str)) / 2, y, "top") end local function setColor(gc, theColor) if type(theColor) == "string" then theColor = theColor:lower() if type(Color[theColor]) == "table" then gc:setColorRGB(uCol(Color[theColor])) end elseif type(theColor) == "table" then gc:setColorRGB(uCol(theColor)) end end local function verticalBar(gc, x) gc:fillRect(x, 0, 1, platform.window:height()) end local function horizontalBar(gc, y) gc:fillRect(0, y, platform.window:width(), 1) end local function drawSquare(gc, x, y, l) gc:drawPolyLine({ (x - l / 2), (y - l / 2), (x + l / 2), (y - l / 2), (x + l / 2), (y + l / 2), (x - l / 2), (y + l / 2), (x - l / 2), (y - l / 2) }) end local function drawRoundRect(gc, x, y, wd, ht, rd) -- wd = width, ht = height, rd = radius of the rounded corner local x = x - wd / 2 -- let the center of the square be the origin (x coord) local y = y - ht / 2 -- same for y coord if rd > ht / 2 then rd = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max rd) gc:drawLine(x + rd, y, x + wd - (rd), y) gc:drawArc(x + wd - (rd * 2), y + ht - (rd * 2), rd * 2, rd * 2, 270, 90) gc:drawLine(x + wd, y + rd, x + wd, y + ht - (rd)) gc:drawArc(x + wd - (rd * 2), y, rd * 2, rd * 2, 0, 90) gc:drawLine(x + wd - (rd), y + ht, x + rd, y + ht) gc:drawArc(x, y, rd * 2, rd * 2, 90, 90) gc:drawLine(x, y + ht - (rd), x, y + rd) gc:drawArc(x, y + ht - (rd * 2), rd * 2, rd * 2, 180, 90) end local function fillRoundRect(gc, x, y, wd, ht, radius) -- wd = width and ht = height -- renders badly when transparency (alpha) is not at maximum >< will re-code later if radius > ht / 2 then radius = ht / 2 end -- avoid drawing cool but unexpected shapes. This will draw a circle (max radius) gc:fillPolygon({ (x - wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y - ht / 2 + radius), (x + wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y + ht / 2 - radius), (x - wd / 2), (y - ht / 2 + radius) }) gc:fillPolygon({ (x - wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y - ht / 2), (x + wd / 2 - radius + 1), (y + ht / 2), (x - wd / 2 + radius), (y + ht / 2), (x - wd / 2 + radius), (y - ht / 2) }) local x = x - wd / 2 -- let the center of the square be the origin (x coord) local y = y - ht / 2 -- same gc:fillArc(x + wd - (radius * 2), y + ht - (radius * 2), radius * 2, radius * 2, 1, -91) gc:fillArc(x + wd - (radius * 2), y, radius * 2, radius * 2, -2, 91) gc:fillArc(x, y, radius * 2, radius * 2, 85, 95) gc:fillArc(x, y + ht - (radius * 2), radius * 2, radius * 2, 180, 95) end local function clearWindow(gc, theColor) gc:setColor(theColor) -- will handle both strings like "red" and direct colors like {255,0,0} gc:fillRect(0, 0, platform.window:width(), platform.window:height()) end ----------------------------------------- ------ Adding the functions to gc ------- ----------------------------------------- AddToGC("setColor", setColor) AddToGC("drawPoint", drawPoint) AddToGC("drawCircle", drawCircle) AddToGC("fillCircle", fillCircle) AddToGC("drawThickCircle", drawThickCircle) AddToGC("fillGradientCircle", fillGradientCircle) AddToGC("drawGradientRect", drawGradientRect) AddToGC("drawSquare", drawSquare) AddToGC("drawRoundRect", drawRoundRect) AddToGC("fillRoundRect", fillRoundRect) AddToGC("verticalBar", verticalBar) AddToGC("horizontalBar", horizontalBar) AddToGC("drawCenteredString", drawCenteredString) AddToGC("drawXCenteredString", drawXCenteredString) AddToGC("clearWindow", clearWindow) ----------------------------- -- End of BetterLuaApi.lua -- ----------------------------- platform.apiLevel = '2.3' local disp=platform.window local dispX=disp:width() local dispY=disp:height() function centerText(gc, text, midX, midY) gc:drawString(text, midX-gc:getStringWidth(text)/2, midY-gc:getStringHeight(text)/2, "top") end function centerTextWithRect(gc, text, midX, midY, rectColor) centerText(gc, text, midX, midY) gc:setColorRGB(rectColor) gc:drawRect(midX-gc:getStringWidth(text)/2, midY-gc:getStringHeight(text)/2, gc:getStringWidth(text), gc:getStringHeight(text)) end function drawBoard(gc, sBX, sBY, sX, sY, bW, bH)--sB-sizeBoard, sX-startX, sY-startY, bW-boardWidth, bH-boardHeight local sizeRectX=bW/sBX local sizeRectY=bH/sBY for i=0, sBY do gc:drawLine(sX, sY+sizeRectY*i, sX+bW, sY+sizeRectY*i) end for i=0, sBX do gc:drawLine(sX+sizeRectX*i, sY, sX+sizeRectX*i, sY+bH) end end do shape=class() shape.type=0 shape.coords={} shape.tmpCoords={} shape.data=0 shape.rotAngle=0 shape.color=0 shape.color2=0 shape.tx=0 shape.ty=0 shape.rotPtX=0 shape.rotPtY=0 shape.dilX=0 shape.dilY=0 shape.dil=1 function shape:init() end function shape:moveCoords(s, x, y) local mag=math.sqrt((self.coords[s])^2+(self.coords[s+1])^2) if mag~=0 then local angle=math.asin((self.coords[s+1])/mag)+self.rotAngle self.coords[s]=mag*math.cos(angle) self.coords[s+1]=mag*math.sin(angle) else self.coords[s]=0 self.coords[s+1]=0 end self.coords[s]=self.coords[s]+x+self.tx self.coords[s+1]=self.coords[s+1]+y+self.ty end function shape:translate(x, y) self.tx=x self.ty=y end function shape:rotate(angle) self.rotAngle=angle%360 end function shape:setRotPoint(x, y) end function shape:setDilatePoint(x, y) self.dilX=x self.dilY=y end function shape:dilate(dilation) self.dil=dilation end function shape:setColorRGB(hex) self.color=hex end function shape:set2ndColorRGB(hex) self.color2=hex end function shape:point(x, y) self.type=1 self.coords={x, y} end function shape:line(x1, y1, x2, y2) self.type=2 self.coords={x1, y1, x2, y2} end function shape:polyLine(points) self.type=3 self.coords={} for i=1, #points do self.coords[i]=points[i] end end function shape:drawRect(x, y, width, height) self.type=4 self.coords={x, y, width, height} end function shape:drawArc(x, y, width, height, startAngle, arcAngle) self.type=5 self.coords={x, y, width, height, startAngle, arcAngle} end function shape:drawString(text, x, y) self.type=6 self.coords={x,y} self.data=text end function shape:image(image, x, y) self.type=7 shape.coords={x,y} self.data=image end function shape:drawRoundRect(x, y, width, height, radius) self.type=8 self.coords={x, y, width, height, radius} end function shape:fillPolygon(points) self.type=9 self.coords={} for i=1, #points do self.coords[i]=points[i] end end function shape:fillRect(x, y, width, height) self.type=10 self.coords={x, y, width, height} end function shape:fillArc(x, y, width, height, startAngle, arcAngle) self.type=11 self.coords={x, y, width, height, startAngle, arcAngle} end function shape:fillRoundRect(x, y, width, height, radius) self.type=12 self.coords={x, y, width, height, radius} end function shape:centeredString(text, x, y) self.type=13 self.coords={x, y} self.data=text end function shape:gradientRect(x, y, width, height, d) self.type=14 self.coords={x, y, width, heigh, d} end function shape:fillCircle(x, y, r) self.type=15 self.coords={x, y, r} end function shape:gradientCircle(x, y, r) self.type=16 self.coords={x, y, r} end function shape:draw(gc, x,y) gc:setColorRGB(self.color) for i=1, #self.coords do self.tmpCoords[i]=self.coords[i] end if self.type==1 then self:moveCoords(1, x, y) gc:drawPoint(self.coords[1], self.coords[2]) elseif self.type==2 then self:moveCoords(1, x, y) self:moveCoords(3, x, y) gc:drawLine(self.coords[1], self.coords[2], self.coords[3], self.coords[4]) elseif self.type==3 then for i=1, #coords, 2 do self:moveCoords(i, x, y) end gc:drawPolyLine(self.coords) elseif self.type==4 then self:moveCoords(1, x, y) gc:drawRect(self.coords[1], self.coords[2], self.coords[3], self.coords[4]) elseif self.type==5 then self.coords[1]=self.coords[1]+self.tx+x self.coords[2]=self.coords[2]+self.ty+y self.coords[5]=(self.coords[5]+self.rotAngle)%360 if self.coords[5]>=360 then self.coords[5]=self.coords[5]-360 end if self.coords[6]>=360 then self.coords[6]=self.coords[6]-360 end gc:drawArc(self.coords[1], self.coords[2], self.coords[3], self.coords[4], self.coords[5], self.coords[6]) elseif self.type==6 then self:moveCoords(1, x, y) gc:drawString(self.data, self.coords[1], self.coords[2]) elseif self.type==7 then self:moveCoords(1, x, y) gc:drawImage(self.data, self.coords[1], self.coords[2]) elseif self.type==8 then self:moveCoords(1, x, y) gc:drawRoundRect(self.coords[1], self.coords[2], self.coords[3], self.coords[4], self.coords[5]) elseif self.type==9 then for i=1, #coords, 2 do self:moveCoords(i, x, y) end gc:fillPolygon(self.coords) elseif self.type==10 then self:moveCoords(1, x, y) gc:fillRect(self.coords[1], self.coords[2], self.coords[3], self.coords[4]) elseif self.type==11 then self.coords[1]=self.coords[1]+self.tx+x self.coords[2]=self.coords[2]+self.ty+y self.coords[5]=(self.coords[5]+self.rotAngle)%360 if self.coords[5]>=360 then self.coords[5]=self.coords[5]%360 end if self.coords[6]>=360 then self.coords[6]=self.coords[6]%360 end gc:fillArc(self.coords[1], self.coords[2], self.coords[3], self.coords[4], self.coords[5], self.coords[6]) elseif self.type==12 then self:moveCoords(1, x, y) gc:fillRoundRect(self.coords[1], self.coords[2], self.coords[3], self.coords[4], self.coords[5]) elseif self.type==13 then self:moveCoords(1, x, y) centerText(gc, self.data, self.coords[1], self.coords[2]) elseif self.type==14 then self:moveCoords(1, x, y) local tmpcolors1={math.floor(self.color/0x10000), math.floor((self.color%0x10000)/0x100), self.color%0x100} local tmpcolors2={math.floor(self.color2/0x10000), math.floor((self.color2%0x10000)/0x100), self.color%0x100} gc:fillGradientRect(self.coords[1], self.coords[2], self.coords[3], self.coords[4], tmpcolors1, tmpcolors2) elseif self.type==15 then self:moveCoords(1, x, y) gc:fillCircle(self.coords[1], self.coords[2], self.coords[3]) elseif self.type==16 then self.coords[1]=self.coords[1]+self.tx+x self.coords[2]=self.coords[2]+self.ty+y local tmpcolors1={math.floor(self.color/0x10000), math.floor((self.color%0x10000)/0x100), self.color%0x100} local tmpcolors2={math.floor(self.color2/0x10000), math.floor((self.color2%0x10000)/0x100), self.color%0x100} gc:fillGradientCircle(self.coords[1], self.coords[2], self.coords[3], tmpcolors1, tmpcolors2) end for i=1, #self.coords do self.coords[i]=self.tmpCoords[i] end end end do glib=class() glib.Shapes={} glib.width=0 glib.height=0 glib.rotAngle=0 function glib:init(width, height) self.width=width self.height=height end function glib:addShape(shape, x, y, rotAngle) self.Shapes[#self.Shapes+1]=shape self.Shapes[#self.Shapes]:translate(x, y) end function glib:rotate(angle) self.rotAngle=angle%360 end function glib:changeRot(angle) self.rotAngle=(self.rotAngle+angle)%360 end function glib:draw(gc, x, y, mode) local changeX=0 local changeY=0 if mode~=nil then if mode=="middle" then changeX=self.width/2 changeY=self.height/2 elseif mode=="midtop" then changeX=self.width/2 elseif mode=="midbottom" then changeX=self.width/2 changeY=self.height end end gc:clipRect("set", x-changeX, y-changeY, self.width, self.height) for i=1, #self.Shapes do local tmp=self.Shapes[i].rotAngle self.Shapes[i]:rotate(self.Shapes[i].rotAngle+self.rotAngle) self.Shapes[i]:draw(gc, x, y) self.Shapes[i]:rotate(tmp) end gc:clipRect("reset") end end --------------------- -- End of glib.lua -- --------------------- ------------------------- -- Start of Screen.lua -- ------------------------- Screen = class() function Screen:init() end -- virtual functions to override function Screen:paint(gc) end function Screen:timer() end function Screen:charIn(ch) end function Screen:arrowKey(key) end function Screen:escapeKey() end function Screen:enterKey() end function Screen:tabKey() end function Screen:contextMenu() end function Screen:backtabKey() end function Screen:backspaceKey() end function Screen:clearKey() end function Screen:mouseMove(x, y) end function Screen:mouseDown(x, y) end function Screen:mouseUp() end function Screen:rightMouseDown(x, y) end function Screen:help() end function Screen:varChange(varList) end function Screen:openScreen() end function Screen:closeScreen() end function Screen:activate() end local Screens = {} function PushScreen(screen) screen:openScreen() table.insert(Screens, screen) disp:invalidate() end function PullScreen() if #Screens > 0 then Screens[#Screens]:closeScreen() table.remove(Screens) if #Screens>0 then Screens[#Screens]:activate() end disp:invalidate() end end function activeScreen() return Screens[#Screens] and Screens[#Screens] or Screen end -- Link events to ScreenManager function on.paint(gc) --for _, screen in pairs(Screens) do Screens[#Screens]:paint(gc) --end end function on.timer() for _, screen in pairs(Screens) do screen:timer() end end function on.charIn(ch) activeScreen():charIn(ch) --disp:invalidate() end function on.arrowKey(key) activeScreen():arrowKey(key) --disp:invalidate() end function on.escapeKey() activeScreen():escapeKey() --disp:invalidate() end function on.enterKey() activeScreen():enterKey() --disp:invalidate() end function on.tabKey() activeScreen():tabKey() --disp:invalidate() end function on.contextMenu() activeScreen():contextMenu() --disp:invalidate() end function on.backtabKey() activeScreen():backtabKey() --disp:invalidate() end function on.backspaceKey() activeScreen():backspaceKey() --disp:invalidate() end function on.clearKey() activeScreen():clearKey() disp:invalidate() end function on.mouseDown(x, y) activeScreen():mouseDown(x, y) --disp:invalidate() end function on.mouseUp() activeScreen():mouseUp() end function on.mouseMove(x, y) activeScreen():mouseMove(x, y) end function on.rightMouseDown(x, y) activeScreen():rightMouseDown(x, y) --disp:invalidate() end function on.help() activeScreen():help() --disp:invalidate() end function on.varChange(varList) activeScreen():varChange(varList) disp:invalidate() end ----------------------- -- End of Screen.lua -- ----------------------- require ('physics') --cookie clicker vec=physics.Vect do menu=Screen() menu.items={} menu.back=nil menu.x=1 function menu:arrowKey(key) if key=="up" then if self.x>1 then self.x=self.x-1 else self.x=#self.items end elseif key=="down" then if self.x<#self.items then self.x=self.x+1 else self.x=1 end end disp:invalidate() end function menu:add(name, item) self.items[#self.items+1]={n=name, i=item, id=#self.items+1} end function menu:paint(gc) if self.back~=nil then gc:drawImage(self.back, 0,0) end for _, item in pairs(self.items) do gc:setColorRGB(0x000000) centerText(gc, item.n, dispX/2, dispY/2-gc:getStringHeight(item.n)*(#self.items-item.id-1)*2/3) if item.id==self.x then gc:drawRect(dispX/2-gc:getStringWidth(item.n)/2, dispY/2-gc:getStringHeight(item.n)*(#self.items-item.id-1/2)*2/3, gc:getStringWidth(item.n), gc:getStringHeight(item.n)*2/3) end end end function menu:setBackground(img) self.back=img:copy(dispX, dispY) end function menu:enterKey() PushScreen(self.items[self.x].i) disp:invalidate() end function menu:mouseDown(x, y) PushScreen(self.items[self.x].i) disp:invalidate() end end do hlpScreen=Screen() hlpScreen.hlpInfo="Going to be made" hlpScreen.dispHelp=D2Editor.newRichText() function hlpScreen:openScreen() self.dispHelp:move(0,0) self.dispHelp:setBorder(0) self.dispHelp:setReadOnly(true) self.dispHelp:setText(self.hlpInfo) self.dispHelp:resize(318, 212) self.dispHelp:setVisible(true) end function hlpScreen:closeScreen() self.dispHelp:setVisible(false) end function hlpScreen:escapeKey() PullScreen() end end do settings=Screen() function settings:escapeKey() PullScreen() end end do game=Screen() local producersPerPage=4 local upgProducersPerPage=6 local startUpgProdX=10 local startUpgProdX2=dispX/2+5 local startUpgY=40 local endUpgY=dispY-10 local pageSizePxl=200 local startProdPxl=dispX-150 local endProdPxl=dispX-5 local startProdY=4 local endProdY=dispY-4 local prevTime=0 local millis=timer.getMilliSecCounter function getTopLeftUpg(num) local startX=startUpgProdX if num>upgProducersPerPage/2 then startX=startUpgProdX2 end local startY=startUpgY+(endUpgY-startUpgY)/(upgProducersPerPage)*((num-1)%(upgProducersPerPage/2))*2 return vec(startX, startY) end do game.cookieProducer=class() local costMultiplier=1.1 local upgradeMultiplier=1.2 local upgradeCostMultiplier=3.0 game.cookieProducer.resetCost=0 game.cookieProducer.resetOutput=0 game.cookieProducer.cost=0 game.cookieProducer.upgradeCost=0 game.cookieProducer.output=0 game.cookieProducer.img=nil game.cookieProducer.name=nil game.cookieProducer.amt=0 game.cookieProducer.id=0 function game.cookieProducer:init(img, name, cost, output) self.img=img self.name=name self.cost=cost self.output=output self.resetCost=self.cost self.resetOutput=self.output self.upgradeCost=upgradeCostMultiplier*self.cost end function game.cookieProducer:paint(gc, num) --gc:clipRect("set", startProdPxl, (endProdY-startProdY)*(num-1), endProdPxl-startProdPxl, (endProdY-startProdY)*num) gc:setColorRGB(0x000000) startY=startProdY+(endProdY-startProdY)*num/producersPerPage gc:drawImage(self.img, startProdPxl, startY) local imgWidth=self.img:width() gc:drawString(self.name, startProdPxl+imgWidth, startY, "middle") gc:drawString("amount: "..self.amt, startProdPxl+imgWidth, startY+gc:getStringHeight(self.name)*3/4, "middle") gc:drawString("cost: "..string.format("%g", math.floor(self.cost)), startProdPxl+imgWidth, startY+2*gc:getStringHeight(self.name)*3/4, "middle") gc:drawString("output: "..string.format("%g", math.floor(self.output*100)/100), startProdPxl+imgWidth, startY+3*gc:getStringHeight(self.name)*3/4, "middle") gc:drawString("total: "..string.format("%g", math.floor(self.output*self.amt*100)/100), startProdPxl+imgWidth, startY+4*gc:getStringHeight(self.name)*3/4, "middle") --gc:clipRect("reset") end function game.cookieProducer:update() return self.output*self.amt*(millis()-prevTime)/1000 end function game.cookieProducer:buy(money) if money>=self.cost then money=money-self.cost self.amt=self.amt+1 self.cost=self.cost*costMultiplier self:storeVars() end return money end function game.cookieProducer:recallVars() if var.recallAt("statProducerSPC", self.id*4-3)~=nil and var.recallAt("statProducerSPC", self.id*4-2)~=nil and var.recallAt("statProducerSPC", self.id*4-1)~=nil then--needs to be improved self.cost=var.recallAt("statProducerSPC", self.id*4-3) self.output=var.recallAt("statProducerSPC", self.id*4-2) self.amt=var.recallAt("statProducerSPC", self.id*4-1) if var.recallAt("statProducerSPC", self.id*4)~=nil then self.upgradeCost=var.recallAt("statProducerSPC", self.id*4) end end end function game.cookieProducer:storeVars() var.storeAt("statProducerSPC", self.cost, self.id*4-3)--also needs to be improved var.storeAt("statProducerSPC", self.output, self.id*4-2) var.storeAt("statProducerSPC", self.amt, self.id*4-1) var.storeAt("statProducerSPC", self.upgradeCost, self.id*4) end function game.cookieProducer:reset() self.cost=self.resetCost self.output=self.resetOutput self.upgradeCost=self.cost*upgradeCostMultiplier self.amt=0 self:storeVars() end function game.cookieProducer:upgrade() local money=0 if var.recallAt("statsCookieSPC", 1)~=nil then money=var.recallAt("statsCookieSPC", 1) if money>=self.upgradeCost then money=money-self.upgradeCost self.upgradeCost=self.upgradeCost*upgradeCostMultiplier self.output=self.output*upgradeMultiplier end var.storeAt("statsCookieSPC", money, 1) self:storeVars() end return money end function game.cookieProducer:getUpgradeCost() return self.upgradeCost end function game.cookieProducer:paintUpgrade(gc, num) local tmpCoords=getTopLeftUpg(num) gc:drawImage(self.img, tmpCoords:x(), tmpCoords:y()) gc:drawString("cost: "..string.format("%g", math.floor(self.upgradeCost)), tmpCoords:x()+self.img:width(), tmpCoords:y()) gc:drawString("new: "..string.format("%g", math.floor((self.output)*upgradeMultiplier*100)/100), tmpCoords:x()+self.img:width(), tmpCoords:y()+gc:getStringHeight("cost: "..self.upgradeCost)) end function game.cookieProducer:getOutput() return self.output*self.amt end end local upgradeAdder=3.0 local upgradeMultiplier=1.15 local upgradeCostAdder=250.0 local upgradeCostMultiplier=1.5 game.upgradeCost=100 game.upgradeCostRST=100 game.cookieCenter=vec(75, dispY/2) game.cookieRad=50 game.mouse=vec(0,0) game.moneyPerClick=1.0 game.moneyPerClickRST=1.0 game.money=0 game.cookieImg=image.new(_R.IMG.cookie) game.cursorUpg=image.new(_R.IMG.upgcursor) local back=nil function game:upgradeClick() if self.money>=self.upgradeCost then self.money=self.money-self.upgradeCost self.upgradeCost=self.upgradeCost+upgradeCostAdder self.upgradeCost=self.upgradeCost*upgradeCostMultiplier self.moneyPerClick=self.moneyPerClick+upgradeAdder self.moneyPerClick=upgradeMultiplier*self.moneyPerClick self:storeVars() end return self.money end --[[game.gameMenu={ {"mouseUpgrade", {"upgrade: "..math.floor(self.clickUpgradeCost), self:upgradeClick} } {"upgrades" } }]] local producers={} game.page=0 function game:storeVars() var.storeAt("statsCookieSPC", self.money, 1) var.storeAt("statsCookieSPC", self.moneyPerClick, 2) var.storeAt("statsCookieSPC", self.upgradeCost, 3) end function game:reset() self.money=0 self.moneyPerClick=self.moneyPerClickRST self.upgradeCost=self.upgradeCostRST self:storeVars() for _, prod in pairs(producers) do prod:reset() end end function game:timer() cursor.show() self:storeVars() for _, prod in pairs(producers) do self.money=self.money+prod:update() prod:storeVars() end prevTime=millis() disp:invalidate() self:storeVars() --[[game.gameMenu[1][1]="upgrade: "..self.upgradeCost for _, prod in pairs(producers) do game.gameMenu[2][prod.id+1][1]=prod.name..": "prod.upgradeCost end toolpalette.register(self.gameMenu)]] end function game:mouseMove(x, y) self.mouse=vec(x, y) end function game:clickCookie() self.money=self.money+self.moneyPerClick self:storeVars() end function game:mouseDown(x, y) local tmpVec=vec(self.cookieCenter-self.mouse) if tmpVec:length()startProdPxl and self.mouse:x()startProdY and self.mouse:y()0 then self.money=producers[tmpY]:buy(self.money) end end end end function game:escapeKey() PullScreen() end function game:arrowKey(key) if key=="left" then if self.page>0 then self.page=self.page-1 else self.page=math.floor((#producers-1)/producersPerPage) end elseif key=="right" then if self.pagestartUpgProdX then if self.mouse:y()>startUpgY and self.mouse:y()startUpgProdX2 then tmpY=tmpY+upgProducersPerPage/2 end if tmpY<=#producers+1 then if tmpY==1 then self.money=game:upgradeClick() else self.money=producers[tmpY-1]:upgrade() end end end end disp:invalidate() end function game.upgradeMen:arrowKey(key) if key=="left" then if self.page>0 then self.page=self.page-1 else self.page=math.floor((#producers-1)/producersPerPage) end elseif key=="right" then if self.page