Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------
- -- WHAT IS THIS? --
- --------------------------------------
- -- This is a Lua script for the Minecraft
- -- mod Computercraft (or CC: Tweaked).
- -----------------------------------
- -- WARNING
- -- This program is not meant to
- -- be downloaded.
- -- Please refer to:
- -- https://pastebin.com/qJSSf0qg
- -- for an installation guide
- -----------------------------------
- ------------------------------------
- -- COMMONS API --
- -- It handles common problems and --
- -- delegates what it can't do to --
- -- the guiHandlers --
- ------------------------------------
- -- Definition of the base class for everything
- class = {}
- setmetatable(class, {})
- class.__index = class
- class.version="0.1"
- class.MAIN_DIR="CyberOS"
- class.THEMES_DIR = class.MAIN_DIR .. "/themes"
- class.DEFAULT_THEME_DIR = class.THEMES_DIR .. "/default"
- class.DEFAULT_ICONS_DIR = class.DEFAULT_THEME_DIR .. "/icons"
- function class:new(shell)
- local self = {}
- setmetatable(self, {__index = class})
- print("Init base class")
- self.shell = shell
- self.x, self.y = term.getSize()
- print(self.DEFAULT_ICONS_DIR)
- fs.makeDir(class.THEMES_DIR)
- fs.makeDir(class.DEFAULT_THEME_DIR)
- fs.makeDir(class.DEFAULT_ICONS_DIR)
- return self
- end
- function class:initTierApi()
- error("initTierApi not implemented on this device")
- end
- function class:initDeviceApi()
- error("initDeviceApi not implemented on this device")
- end
- function class:write(text, x, y)
- return self:print(text, nil, nil, x, y)
- end
- function class:print(text, fontColor, textColor, x, y)
- error("print not implemented on this device")
- end
- local function getIndexFunction(tierClass, deviceClass)
- local func = function (tab, key)
- -- Get function of base class and of tier and device classes
- local baseFunc = class[key]
- local tierFunc = tierClass[key]
- local deviceFunc = deviceClass[key]
- -- Check that the method is not simply the stub for it
- if baseFunc == tierFunc then
- tierFunc = nil
- end
- if baseFunc == deviceFunc then
- deviceFunc = nil
- end
- assert(tierFunc==nil or deviceFunc==nil, "Only one between tierClass and deviceClass can implement "..key)
- -- Return tier or device func if present, otherwise baseFunc if present, otherwise nil
- if tierFunc then return tierFunc elseif deviceFunc then return deviceFunc else return baseFunc end
- end
- return func
- end
- --- Used to create the instance, extending class, tierClass and deviceClass
- function createInstance(tierClass, deviceClass, shell)
- -- Prototype class
- local instance = {}
- -- INHERITANCE HAPPENS HERE
- -- When class does not have a method, it searches in tierFunc and deviceClass
- setmetatable(instance, {__index = getIndexFunction(tierClass, deviceClass)})
- -- set itself as metatable
- instance.__index = instance
- -- Define constructor
- function instance:new(shell)
- local self = class:new(shell)
- setmetatable(self, {__index = instance})
- print("Init Mixed class")
- self:initTierApi()
- self:initDeviceApi()
- return self
- end
- return instance:new(shell)
- end
- function class:drawButton(text, x1, y1, x2, y2, func, color)
- assert(x2-x1-string.len(text)>=0, "Text '"..text.."' can't be longer than button width "..x2-x1)
- end
- function class:getWidth()
- return self.x
- end
- function class:getHeight()
- return self.y
- end
- ------------------
- -- SHELL RUNNING--
- ------------------
- function class:run(s, arg)
- self.shell.run(s, arg)
- end
- function class:run(s, arg1, arg2, arg3)
- self.shell.run(s, arg1, arg2, arg3)
- end
- function class:loadElementValue(setting, fileName)
- local h = fs.open(fileName, "r")
- local tab = textutils.unserialize(h.readAll())
- h.close()
- return tab[setting]
- end
- function class:getApps()
- local h
- if fs.exists(".apps") == false then
- h = fs.open(".apps", "w")
- h.writeLine("Turtle")
- h.writeLine("Mail")
- h.writeLine("Lua")
- h.writeLine("Disk")
- if term.isColor() then --- TODO ---
- h.writeLine("Paint")
- h.writeLine("Game")
- end
- h.writeLine("Off")
- h.writeLine("Add")
- h.writeLine("Add")
- end
- h = fs.open(".apps", "r")
- local tab = {}
- local line = h.readLine()
- local i = 1
- while line ~= nil do
- tab[i] = line
- i = i + 1
- line = h.readLine()
- end
- return tab
- end
- ----------------------------
- -- Draws the Main Menu --
- -- for advanced computers --
- ----------------------------
- function drawMain()
- guiHandler.drawImageTheme("blankMain") --mainBackground drawn
- sFill=""
- for i=1, 51-(string.len(version)+9) do
- sFill=sFill.." "
- end
- blit("CyberOs v"..version..sFill, "0", "5",1,1) -- disegna la barra in alto
- for i=0, 9 do
- local appName=""
- if i==0 then appName = "Turtle"
- elseif i==1 then appName = "PIM" blit("#####","7","f",4+10*(i%5), 6+math.floor(i/5)*6)
- elseif i==2 then appName = "Mail"
- elseif i==3 then appName = "Lua" blit("ua","0","5",7+10*(i%5), 6+math.floor(i/5)*6)
- elseif i==4 then appName = "Disk"
- elseif i==5 then appName = "Paint"
- elseif i==6 then appName = "Game"
- elseif i==7 then appName = "Unknown"
- elseif i==8 then appName = "Unknown"
- else appName = "Off" end
- local img = guiHandler.loadImageTheme("App"..appName)
- paintutils.guiHandler.drawImage(img,3+10*(i%5),4+math.floor(i/5)*6)
- blit(appName, "0", "f",3+10*(i%5)+math.floor((7-string.len(appName))/2), 8+math.floor(i/5)*6)
- end
- blit("MainMenu: click the Icons!", "0", "7", 12, 17)
- term.setCursorPos(2,16)
- term.blit("/ \\","888","f8f")
- term.setCursorPos(2,17)
- term.blit(" O ","888","8f8")
- term.setCursorPos(2,18)
- term.blit("\\ /","888","f8f")
- end
- ---------------------------
- -- The cycle for click --
- -- handling for advanced --
- -- computers --
- ---------------------------
- function wait4clickMain()
- while true do
- local event, button, x, y = os.pullEvent("mouse_click")
- if button==1 then
- if y>3 and y<9 then
- if x>2 and x<10 then
- s="Turtle"
- turtleClick()
- elseif x>12 and x<20 then
- s="PIM"
- elseif x>22 and x<30 then
- s="Mail"
- elseif x>32 and x<40 then
- s="Lua"
- term.clear()
- sFill=""
- for i=1, 51-(string.len(version)+9) do
- sFill=sFill.." "
- end
- blit("CyberOs v"..version..sFill, "0", "5",1,1)
- term.setCursorPos(1,2)
- run("lua", "")
- elseif x>42 and x<50 then
- s="Disk"
- end
- elseif y>9 and y<15 then
- if x>2 and x<10 then
- s="Paint"
- paintClick()
- elseif x>12 and x<20 then
- s="Game"
- run("rom/programs/fun/advanced/redirection")
- elseif x>22 and x<30 then
- s="1?"
- elseif x>32 and x<40 then
- s="2?"
- elseif x>42 and x<50 then
- s="Off"
- offClick()
- end
- end
- end
- end
- end
- -----------------------
- -- Handles the click --
- -- of TURTLE app --
- -----------------------
- function turtleClick()
- guiHandler.drawImageTheme("blankMain")
- local ids={}
- local labels={}
- for i=0, 7 do
- local turtleLabel = loadElementValue(i+1, "label", ".registeredTurtles")
- local turtleId
- if i==7 then
- turtleLabel="[Back]"
- turtleId=-1
- elseif turtleLabel == nil then
- turtleLabel="[+]"
- turtleId=-1
- else
- turtleId=tonumber(loadElementValue(i+1, "id", ".registeredTurtles"))
- end
- ids[i+1]=turtleId
- labels[i+1]=turtleLabel
- local img
- if turtleLabel=="[+]" then
- img = guiHandler.loadImageTheme("Add")
- elseif turtleLabel=="[Back]" then
- img = guiHandler.loadImageTheme("Back")
- else
- img = guiHandler.loadImageTheme("Turtle")
- end
- paintutils.guiHandler.drawImage(img,3+12*(i%4),4+math.floor(i/4)*6)
- blit(turtleLabel, "0", "f",3+12*(i%4)+math.floor((7-string.len(turtleLabel))/2), 8+math.floor(i/4)*6)
- end
- while true do
- local event, button, x, y = os.pullEvent("mouse_click")
- if button==1 then
- if x>2 and (x-2)%12>0 and x<51 and y>3 and y<14 and (y-3)%6>0 then
- x=x-((x-2)%12)+1
- y=y-((y-3)%6)+1
- i=(x-3)/12+(y-4)*4/6
- if ids[i+1]==-1 then
- if labels[i+1]=="[Back]" then
- break
- elseif labels[i+1]=="[+]" then
- guiHandler.drawImageTheme("blankMain")
- blit(" ", "0","5",3,4)
- blit(" [Add] ", "0","5",3,5)
- blit(" ", "0","5",3,6)
- blit(" ", "0","e",3,8)
- blit(" [Back] ", "0","e",3,9)
- blit(" ", "0","e",3,10)
- blit("Place the TURTLE under the PC", "0","f",18,5)
- blit("and click [Add]", "0","f",18,6)
- blit("(Make sure the turtle has a MODEM,","0","f",18,7)
- blit("or it will not work)", "0","f",18,8)
- while true do
- event, button, x, y = os.pullEvent("mouse_click")
- if button==1 and y>=4 and y<=6 and x>=3 and x<=10 then
- if (not peripheral.isPresent("bottom")) or (peripheral.isPresent("bottom") and peripheral.getType("bottom")~="turtle") then
- blit("ERROR, NO TURTLE FOUND", "e","f",18,10)
- end
- elseif button==1 and y>=8 and y<=10 and x>=3 and x<=10 then
- break
- end
- end
- break
- end
- else
- guiHandler.drawImageTheme("blankMain")
- paintutils.guiHandler.drawImage(guiHandler.loadImageTheme("Turtle"),3,4)
- blit("[Back]", "0","e", 4, 10)
- centerBlit("ID","0","7", 14, 4, 10)
- centerBlit(ids[i+1],"f","8",14,5,10)
- centerBlit("Label","0","7", 26, 4, 10)
- centerBlit(labels[i+1],"f","8",26,5,10)
- centerBlit("Program Running", "0","7", 14, 8, 22)
- centerBlit("**FAILED COMUNICATION**", "f","8", 14, 9, 22)
- while true do
- event, button, x, y = os.pullEvent("mouse_click")
- if button==1 and y==10 and x>=4 and x<10 then
- break
- end
- end
- break
- end
- end
- end
- end
- if labels[i+1]=="[Back]" then
- loadMain(ADVANCEDCOMPUTER)
- else
- turtleClick()
- end
- end
- function centerBlit(text, charT, charB, x, y, length)
- space=length-string.len(text)
- s=""
- for i=1, math.floor(space/2) do
- s=s.." "
- end
- text=s..text
- if space%2==1 then
- s=s.." "
- end
- text=text..s
- blit(text, charT, charB, x, y)
- end
- -----------------------
- -- Handles the click --
- -- of OFF app --
- -----------------------
- function offClick()
- guiHandler.drawImageTheme("OffPrompt")
- blit("Restart", "0", "5", 11, 13)
- blit("<-", "0", "5", 25, 13)
- blit("Shutdown", "0", "5", 35, 13)
- blit("What would you like to do?", "0","7", 12, 17)
- flag=false
- while not flag do
- local event, button, x, y = os.pullEvent("mouse_click")
- if y>2 and y<15 then
- if x>4 and x<23 then
- os.reboot()
- elseif x>29 and x<47 then
- os.shutdown()
- elseif x>23 and x<29 and y>11 then
- flag=true
- loadMain(ADVANCEDCOMPUTER)
- end
- end
- end
- end
- -----------------------
- -- Handles the click --
- -- of PAINT app --
- -----------------------
- function paintClick()
- guiHandler.drawImageTheme("PaintPrompt")
- blit("New IMG", "0", "5", 11, 13)
- blit("<-", "0", "5",25,13)
- blit("Edit IMG", "0", "5", 35, 13)
- blit("What would you like to do?", "0","7",12,17)
- flag=false
- while not flag do
- term.setCursorPos(12,17)
- local event, button, x, y = os.pullEvent("mouse_click")
- if y>2 and y<15 then
- if x>4 and x<23 then
- blit("New File name: ", "0","7", 12,17)
- term.setCursorPos(26,17)
- term.setCursorBlink(true)
- fileName=io.read()
- run("paint","paintFiles/"..fileName)
- loadMain(ADVANCEDCOMPUTER)
- elseif x>29 and x<47 then
- --Here you edit the ImgFiles
- local tabN = table.getn(fs.list("paintFiles/"))
- local page = 0
- local pageMax = math.floor((tabN-1)/12)
- local hasToStay = true
- while hasToStay do
- guiHandler.drawImageTheme("blankMain")
- for i=0, 14 do
- fileName=""
- if page>0 and i==12 then
- fileName=" <<<< "
- elseif i==13 then
- fileName=" Back "
- elseif page<pageMax and i==14 then
- fileName=" >>>> "
- elseif page==pageMax and tabN%12>0 and i>=tabN%12 and i~=14 then
- fileName=" - - - "
- elseif i<12 then
- fileName=fs.list("paintFiles/")[i+page*12+1]
- end
- local backColor=""
- if fileName==" >>>> " or fileName==" <<<< " or fileName==" Back " then
- backColor="b"
- elseif fileName=="" then
- backColor="f"
- else
- backColor="5"
- end
- sL = string.len(fileName)
- if sL>11 then
- fileName = string.sub(fileName, 1, 10)..".."
- elseif sL<10 then
- fileName=" "..fileName.." "
- end
- if fileName~="" then
- blit(fileName, "0", backColor, 3+(i%4)*12,4+math.floor(i/4)*3)
- end
- end
- blit("Select the file you want to edit", "0","7", 12, 17)
- local event, button, x, y = os.pullEvent("mouse_click")
- if button==1 then
- if x>2 and (x-2)%12>0 and x<51 and y>3 and y<14 and (y-1)%3==0 then
- x=x-((x-2)%12)+1
- i=((16*y+x)-67)/12
- if i==12 and page>0 then
- page=page-1
- elseif i==13 then
- flag=true
- hasToStay=false
- loadMain(ADVANCEDCOMPUTER)
- elseif i==14 and page<pageMax then
- page=page+1
- elseif i<12 and i+page*12<tabN-1 then
- flag2=true
- fname = fs.list("paintFiles/")[i+page*12+1]
- term.write(fname)
- run("paint","paintFiles/"..fname)
- end
- end
- end
- end
- elseif x>23 and x<29 and y>11 then
- flag=true
- loadMain(ADVANCEDCOMPUTER)
- end
- end
- end
- end
- -----------------------------------------
- -- Enhancement of pre-existing blit --
- -- Draws the TEXT with charT textColor --
- -- and charB backColor at X, Y coord --
- -----------------------------------------
- ------------------------
- -- gets color.COLOR --
- -- returns hex for it --
- ------------------------
- function col2hex(color)
- local hexstr = '0123456789abcdef'
- local s = ''
- color = math.log10(color)/math.log10(2)
- while color > 0 do
- local mod = math.fmod(color, 16)
- s = string.sub(hexstr, mod+1, mod+1) .. s
- color = math.floor(color / 16)
- end
- if s == '' then s = '0' end
- return s
- end
- function split (inputstr, sep)
- if sep == nil then
- sep = "%s"
- end
- local t={}
- for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
- table.insert(t, str)
- end
- return t
- end
- ---------------------------------
- -- Divides a long message in
- -- multiple lines given the line
- -- length (x)
- -- Specifying a y it will throw error
- -- if it can't divide the message in
- -- less than y lines of length x
- -----------------------------------
- function formatString(msg, x, y)
- local i = 0
- if string.len(msg) > x then
- local newMsg = {}
- for w = x, 1, -1 do
- if string.len(msg)<=x then
- i = i+1
- newMsg[i] = msg
- break
- end
- if msg:sub(w, w) == " " then
- i = i+1
- newMsg[i] = msg:sub(1, w-1)
- msg = msg:sub(w+1, -1)
- w = x
- end
- end
- msg = newMsg
- else
- msg = {msg}
- end
- if y~=nil then
- if #msg>y then
- basicWarning("Impossible to format the string", x, y)
- assert(#msg<=y, "Impossible to format the string")
- elseif #msg<=y then
- local newMsg = {}
- for k=1, math.floor((y-#msg)/2) do
- newMsg[k] = " "
- end
- local n = #newMsg
- for k, line in ipairs(msg) do
- newMsg[n+k] = line
- end
- for k=1, math.ceil((y-#msg)/2) do
- newMsg[#newMsg+k] = " "
- end
- msg = newMsg
- end
- end
- for k, word in ipairs(msg) do
- msg[k] = centerWithSpaces(msg[k], x)
- end
- return msg
- end
- function fillWithSpaces(str, x)
- local fillLength = x-string.len(str)
- return str..string.rep(" ", fillLength)
- end
- function centerWithSpaces(str, x)
- local fillLength = x-string.len(str)
- return string.rep(" ", math.floor(fillLength/2))..str..string.rep(" ", math.ceil(fillLength/2))
- end
- function drawFrame(character, topText, bottomText)
- local x, y = term.getSize()
- if character==nil then character = "#" end
- if topText then
- topText = " "..topText.." "
- else
- topText = ""
- end
- local textL = string.len(topText)
- topText = string.rep(character, math.floor((x-textL)/2)) .. topText .. string.rep(character, math.floor((x-textL)/2))
- term.setCursorPos(1, 1)
- term.write(topText)
- if bottomText then
- bottomText = " "..bottomText.." "
- else
- bottomText = ""
- end
- textL = string.len(bottomText)
- bottomText = string.rep(character, math.floor((x-textL)/2)) .. bottomText .. string.rep(character, math.floor((x-textL)/2))
- term.setCursorPos(1, y)
- term.write(bottomText)
- for j=1, y do
- term.setCursorPos(1, j)
- term.write(character)
- term.setCursorPos(x, j)
- term.write(character)
- end
- end
- function basicWarning(msg)
- term.clear()
- drawFrame("!", "WARNING", "Press ENTER to continue")
- local x, y = term.getSize()
- local disclaimer = CyberOs.formatString(msg, x-4, y-4)
- for k, v in ipairs(disclaimer) do
- if v ~= string.rep(" ", x) then
- disclaimer[k-1] = centerWithSpaces("###WARNING###", x)
- break
- end
- end
- for k, v in ipairs(disclaimer) do
- term.setCursorPos(3, 3+k)
- term.write(v)
- end
- read()
- term.clear()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement