Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --------------------------------------------------------
- --> Setup <--
- --------------------------------------------------------
- function setConfigs()
- cfg = {}
- cfg.barColor = colors.cyan
- cfg.titleProgram = "Crates program"
- cfg.freeUses = 1
- cfg.commandsToMoveKeys = {"movekeys","movekey","addkey","addkeys"}
- cfg.commandsToOpenCrate = {"open","opencrate","crate", "play"}
- cfg.commandsToMoveLegendary = {"addlegendary", "addlegendarykeys", "addleg", "addlry", "addl"}
- return cfg
- end
- --------------------------------------------------------
- --> Variables <--
- --------------------------------------------------------
- os.loadAPI("gcapi")
- local config = {}
- me = peripheral.find("appeng_me_tilecable") or peripheral.find("appeng_me_tilecolorlesscable")
- pim = peripheral.find("pim")
- chest = peripheral.find("crystal")
- spinning = false
- function hasPermissions(player)
- local hasPerms = gcapi.hasPermissions(player)
- if not hasPerms then
- printLog(player .. " tried to use an admin command!")
- end
- return hasPerms
- end
- --------------------------------------------------------
- --> Setup File <--
- --------------------------------------------------------
- function readConfigFile(cfg)
- local list = gcapi.getListFromFile("/config.cfg")
- for key,value in pairs(list) do
- cfg[key] = value
- end
- return cfg
- end
- function saveConfigFile(cfg)
- gcapi.saveListToFile("/config.cfg", cfg)
- end
- --------------------------------------------------------
- --> Key Names <--
- --------------------------------------------------------
- key_name = nil
- l_key_name = nil
- if fs.exists("/keyNames") then
- local list = gcapi.getListFromFile("/keyNames")
- key_name = list["key_name"]
- l_key_name = list["l_key_name"]
- else
- error("You need to create the keyNames file with the names of the keys ({key_name and l_key_name})")
- end
- --------------------------------------------------------
- --> Manual Setup <--
- --------------------------------------------------------
- config = readConfigFile(config)
- if config.chestDirection == nil then
- write("Where is the chest (Center: pim): ")
- config.chestDirection = read():gsub(' ','')
- print()
- saveConfigFile(config)
- end
- if config.players_database == nil then
- write("Are you allowed to make databases? ")
- local input = read()
- config.players_database = ( (input:gsub(' ',''):lower() == "yes") or (input:gsub(' ',''):lower() == "y") )
- print()
- saveConfigFile(config)
- end
- config = setConfigs()
- config = readConfigFile(config)
- --------------------------------------------------------
- --> ME STUFF <--
- --------------------------------------------------------
- function extractItem(item)
- emptyChest()
- if item ~= nil then
- me.extractItem(item,"up")
- end
- end
- function emptyChest()
- me.insertItem(1,64,"up")
- end
- --------------------------------------------------------
- --> PIM STUFF <--
- --------------------------------------------------------
- function checkPlayer(player)
- if getCurrentPlayer() == player then
- return true
- end
- return false
- end
- function getCurrentPlayer()
- return pim.getInventoryName()
- end
- function movePrize()
- if pim.getInventoryName() ~= "pim" then
- itemsToBeMoved = chest.getStackInSlot(1)["qty"]
- local itemsMoved = 0
- for i=1,36,1 do
- stackInSlot = pim.getStackInSlot(i)
- if stackInSlot == nil then
- itemsMoved = itemsMoved + pim.pullItemIntoSlot(config.chestDirection,1,64,i)
- if itemsMoved >= itemsToBeMoved then
- return true
- end
- end
- end
- else
- error('The player left the PIM before being able to deliver the prize.')
- end
- error('The items couldnt be moved for some unknown reason.')
- end
- function getKeysInInventory()
- --CONFIG
- local id = 131
- local name = key_name
- qty = 0
- for i,item in pairs(pim.getAllStacks()) do
- if item["id"] == id then
- if item["name"] == name then
- if item["ench"] ~= nil then
- if item["ench"][1] ~= nil and item["ench"][1] == "Unbreaking I" then
- qty = qty + item["qty"]
- end
- end
- end
- end
- end
- return qty
- end
- function moveKeysToSystem(amount)
- --CONFIG
- local id = 131
- local name = key_name
- if amount > getKeysInInventory() then
- return false, "Not enough keys"
- end
- local qty = 0
- for i,item in pairs(pim.getAllStacks()) do
- if item["id"] == id then
- if item["name"] == name then
- if item["ench"] ~= nil then
- if item["ench"][1] ~= nil and item["ench"][1] == "Unbreaking I" then
- local keysMoved = pim.pushItemIntoSlot(config.chestDirection, i, amount, 1)
- qty = qty + keysMoved
- amount = amount - keysMoved
- end
- end
- end
- end
- end
- return qty
- end
- function getLegendaryKeysInInventory()
- --CONFIG
- local id = 131
- local name = l_key_name
- qty = 0
- for i,item in pairs(pim.getAllStacks()) do
- if item["id"] == id then
- if item["name"] == name then
- if item["ench"] ~= nil then
- if item["ench"][1] ~= nil and item["ench"][1] == "Unbreaking I" then
- qty = qty + item["qty"]
- end
- end
- end
- end
- end
- return qty
- end
- function moveLegendaryKeysToSystem(amount)
- --CONFIG
- local id = 131
- local name = l_key_name
- if amount > getLegendaryKeysInInventory() then
- return false, "Not enough keys"
- end
- local qty = 0
- for i,item in pairs(pim.getAllStacks()) do
- if item["id"] == id then
- if item["name"] == name then
- if item["ench"] ~= nil then
- if item["ench"][1] ~= nil and item["ench"][1] == "Unbreaking I" then
- local keysMoved = pim.pushItemIntoSlot(config.chestDirection, i, amount, 1)
- qty = qty + keysMoved
- amount = amount - keysMoved
- end
- end
- end
- end
- end
- return qty
- end
- --------------------------------------------
- --> Economy <--
- --> <--
- --> This is saved every use <--
- --> for safety purposes. <--
- --------------------------------------------
- playerUses = {}
- function loadUses()
- if not config.players_database then
- return false
- end
- playerUses = gcapi.getListFromFile("/disk/playerUses")
- return true
- end
- function saveUses()
- if not config.players_database then
- return false
- end
- gcapi.saveListToFile("/disk/playerUses", playerUses)
- return true
- end
- function getPlayerUses(player)
- if not config.players_database then
- return 0
- end
- loadUses()
- if playerUses[player] then
- return tonumber(playerUses[player])
- end
- return config.freeUses
- end
- function addUses(player, newuses)
- if not config.players_database then
- return false
- end
- prevQty = getPlayerUses(player)
- playerUses[player] = prevQty + newuses
- saveUses()
- return true
- end
- function withdraw(player, amount)
- if not config.players_database then
- return false
- end
- if getPlayerUses(player) < amount then
- return false
- end
- prevQty = getPlayerUses(player)
- playerUses[player] = (prevQty - amount)
- saveUses()
- return true
- end
- --End Codes
- --------------------------------------------------------
- --> Codes <--
- --------------------------------------------------------
- --Codes
- codes = {}
- function loadCodes()
- codes = gcapi.getListFromFile("/disk/codes")
- end
- function saveCodes()
- gcapi.saveListToFile("/disk/codes", codes)
- end
- function getUsesOfCode(code)
- loadCodes()
- return codes[code]
- end
- function addCode(code)
- codes[code]=1
- saveCodes()
- end
- function disableCode(code)
- codes[code]=0
- saveCodes()
- end
- function generateCode()
- local code = string.upper(gcapi.randomString(2)) .. tostring(gcapi.getRandom(1111,9999))
- if getUsesOfCode(code) == nil then
- addCode(code)
- if pcall(printPage, code) then
- displayMessage("Ticket Job Done!" )
- else
- displayError("Printer error")
- end
- else
- displayError("Try again")
- end
- end
- function printPage(code)
- local oPrinter = peripheral.find( "printer" )
- oPrinter.newPage()
- oPrinter.setPageTitle( "Crate Ticket! ")
- oPrinter.setCursorPos( 1, 2 )
- oPrinter.write( "The Key Code is " .. code )
- oPrinter.endPage()
- end
- --End Codes
- --------------------------------------------------------
- --> Log <--
- --------------------------------------------------------
- function printLog(line)
- print(line)
- if config.players_database then
- local file = fs.open("/disk/log","a")
- file.writeLine(line)
- file.close()
- end
- end
- --------------------------------------------------------
- --> Prizes <--
- --------------------------------------------------------
- prizes = {}
- function loadPrizes()
- prizes = gcapi.getListFromFile("/disk/prizes")
- end
- function savePrizes()
- gcapi.saveListToFile("/disk/prizes", prizes)
- end
- function addPrize(id, dmg, qty, name, color)
- loadPrizes()
- if not getIDPrize(id, dmg) then
- if not color then
- color = (2^math.random(2,14))
- end
- prize = {["id"] = id, ["dmg"] = dmg, ["qty"] = qty, ["name"] = name, ["color"] = color}
- table.insert(prizes, prize)
- savePrizes()
- return true
- else
- return false, "Prize already exists"
- end
- end
- function getIDPrize(id, dmg)
- loadPrizes()
- for i, prize in pairs(prizes) do
- if id == prize["id"] then
- if dmg == prize["dmg"] then
- return i
- end
- end
- end
- return nil
- end
- function removePrizeByID(id, dmg)
- loadPrizes()
- local i = getIDPrize(id, dmg)
- if i then
- prizes[i] = nil
- savePrizes()
- return true
- end
- return false, "Prize doesnt exist"
- end
- function removePrize(i)
- loadPrizes()
- i = tonumber(i)
- if i then
- prizes[i] = nil
- savePrizes()
- return true
- end
- return false, "Prize doesnt exist"
- end
- --------------------------------------------------------
- --> Spin <--
- --------------------------------------------------------
- function getRandomItem(outOfStockBefore)
- local outOfStock = outOfStockBefore
- if outOfStock == nil then
- outOfStock = {}
- end
- local randomNumber = math.random(1, #prizes)
- while table.contains(outOfStock, randomNumber) do
- randomNumber = math.random(1, #prizes)
- end
- local item = prizes[randomNumber]
- local id = item["id"]
- local dmg = item["dmg"] or 0
- local qty = item["qty"]
- if me.containsItemType(id, dmg) and me.countOfItemType(id,dmg) >= qty then
- return item, outOfStock
- end
- table.insert(outOfStock, randomNumber)
- return getRandomItem(outOfStock)
- end
- table.contains = function (eTable, varE)
- for k,v in pairs(eTable) do
- if varE == v then
- return true
- end
- end
- return false
- end
- actualPrize = nil
- function spin(player)
- printArrows()
- local items = {}
- local outOfStock = nil
- for n = 1, 20, 1 do
- randomItem, outOfStock = getRandomItem(outOfStock)
- table.insert(items, randomItem)
- end
- actualPrize = nil
- for offsetY = 1, 63, 1 do
- for i, item in pairs(items) do
- lastPrize = actualPrize
- local displayName = item["name"] .. " (" .. item["qty"] .. ")"
- if printBox(i, displayName, offsetY, item["color"]) then
- break
- end
- if lastPrize ~= actualPrize then
- if actualPrize ~= nil then
- local local_prize = getLocalPrize(actualPrize, items)
- local_prize["color"] = nil
- local_prize["name"] = nil
- extractItem(local_prize)
- end
- end
- end
- music("note.harp",3,1)
- sleep(0.05)
- end
- music("random.successful_hit",1,1)
- local ok, err = pcall(movePrize)
- if ok then
- if not err then
- printLog(player .. " ERROR: " .. tostring(err))
- end
- else
- printLog(player .. " ERROR: " .. tostring(err))
- end
- emptyChest()
- end
- function getLocalPrize(actualPrize, items)
- return textutils.unserialize(textutils.serialize(items[actualPrize]))
- end
- --------------------------------------------------------
- --> Commands <--
- --------------------------------------------------------
- function executeCommand(player, co)
- local co = (co .. " ")
- local command = gcapi.split(co .. " ", " ")
- if not command[1] then
- return nil
- end
- if command[1] == "generatecode" and hasPermissions(player) then
- generateCode()
- return
- end
- if command[1] == "addprize" and hasPermissions(player) then
- item = pim.getAllStacks()[1]
- if item then
- local id, dmg, qty, name = item["id"], item["dmg"], item["qty"], item["name"]
- if command[2] and command[2] ~= '' then
- name = command[2]
- end
- addPrize(id, dmg, qty, name)
- displayMessage("Item added! -> " .. name .. " (" .. qty .. ")")
- else
- displayError("Item not found", player, true)
- end
- return
- end
- if config.players_database and table.contains(config.commandsToMoveKeys, command[1]) then
- local amount = 1
- if command[2] and tonumber(command[2]) then
- amount = tonumber(command[2])
- end
- keysMoved, err = moveKeysToSystem(amount)
- if keysMoved then
- addUses(player, keysMoved)
- displayMessage(keysMoved .. " keys moved!")
- emptyChest()
- else
- displayError(err, player)
- end
- return
- end
- if command[1] == "test" and hasPermissions(player) then
- spin(player)
- return
- end
- if command[1] == "prizes" then
- displayPrizes()
- return
- end
- if command[1] == "removeprize" and hasPermissions(player) then
- if tonumber(command[2]) then
- if removePrize(i) then
- displayMessage("Prize removed.")
- end
- else
- displayError("Usage: !removeprize <i>", player)
- end
- return
- end
- if command[1] == "code" then
- if command[2] then
- local code = string.upper(command[2])
- if getUsesOfCode(code) then
- local u = tonumber(getUsesOfCode(code))
- if u > 0 then
- disableCode(code)
- spin(player)
- sleep(3)
- else
- displayError("Code already used!")
- end
- else
- displayError("Code not found!")
- end
- else
- displayError("Usage: !code <code>")
- end
- return
- end
- if table.contains(config.commandsToOpenCrate, command[1]) then
- if withdraw(player, 1) then
- clearWhiteWindow()
- displayPlayerInformation()
- spin(player)
- sleep(3)
- clearWhiteWindow()
- displayPlayerInformation()
- else
- if moveKeysToSystem(1) then
- clearWhiteWindow()
- displayPlayerInformation()
- spin(player)
- sleep(3)
- clearWhiteWindow()
- displayPlayerInformation()
- else
- displayError("You do not have enough keys!")
- end
- end
- return
- end
- if config.players_database and table.contains(config.commandsToMoveLegendary, command[1]) then
- local amount = 1
- if command[2] and tonumber(command[2]) then
- amount = tonumber(command[2])
- end
- keysMoved, err = moveLegendaryKeysToSystem(amount)
- if keysMoved then
- addUses(player, keysMoved*10)
- displayMessage(keysMoved .. " legendary keys moved!")
- emptyChest()
- else
- displayError(err, player)
- end
- return
- end
- displayError("Command not found!", nil, true)
- end
- --------------------------------------------------------
- --> Monitor <--
- --------------------------------------------------------
- weidhtBox = 34
- heightBox = 6
- mon = nil
- max_x = 0
- max_y = 0
- nextReset = 0
- function getCenter(f, varP)
- if not varP then
- varP = ""
- end
- if (f - string.len(varP) % 2) == 0 then
- return math.floor((f - string.len(varP))/2)
- end
- return math.floor((f - string.len(varP))/2)+1
- end
- function setupScreen()
- if mon == nil then
- mon = peripheral.find("monitor")
- end
- mon.setBackgroundColor(colors.white)
- mon.clear()
- max_x, max_y = mon.getSize()
- --Print bar for title
- mon.setBackgroundColor(config.barColor)
- for x=1, max_x, 1 do
- mon.setCursorPos(x,1)
- mon.write(" ")
- end
- --Print title
- local x = getCenter(max_x, config.titleProgram)
- mon.setCursorPos(x,1)
- mon.setTextColor(colors.black)
- mon.write(config.titleProgram)
- --Bottom bar for title
- mon.setBackgroundColor(config.barColor)
- for x=1, max_x, 1 do
- mon.setCursorPos(x,max_y)
- mon.write(" ")
- end
- end
- function displayError(errorMessage, player, notLog)
- displayMessage(errorMessage, colors.red)
- if player then
- errorMessage = player .. " - " .. "errorMessage"
- end
- if not notLog then
- printLog(errorMessage)
- end
- end
- function displayMessage(message, color, expireTime)
- if not tonumber(expireTime) then
- expireTime = 4
- end
- mon.setBackgroundColor(colors.white)
- if not color then
- mon.setTextColor(colors.black)
- else
- mon.setTextColor(color)
- end
- local x = getCenter(max_x, message)
- local y = getCenter(max_y)
- --CLEAR OLD MESSAGE
- for x=1, max_x, 1 do
- mon.setCursorPos(x,y)
- mon.write(" ")
- end
- --PRINT NEW MESSAGE
- mon.setCursorPos(x,y)
- mon.write(message)
- if expireTime == -1 then
- nextReset = -1
- else
- nextReset = clock + expireTime
- end
- mon.setTextColor(colors.black)
- end
- function expireOldMessages()
- if clock > nextReset and nextReset ~= -1 then
- mon.setBackgroundColor(colors.white)
- for x=1, max_x, 1 do
- for y=2, max_y-1 do
- mon.setCursorPos(x,y)
- mon.write(" ")
- end
- end
- nextReset = -1
- displayPlayerInformation()
- end
- end
- function displayWelcome()
- mon.setBackgroundColor(colors.white)
- mon.setTextColor(colors.orange)
- writeCentered("Welcome to WatchStore Crates", 3)
- mon.setTextColor(colors.black)
- writeCentered("To use this machine you need vote keys.", 5)
- writeCentered("You can see the prizes on the ME monitors on your left", 7)
- writeCentered("You must remain on the PIM (plessure plate)", 9)
- writeCentered("while the machine is rolling your reward.", 10)
- writeCentered("To start playing, you need to stand on the PIM.", 12)
- writeCentered("Good luck!.", 14)
- if config.players_database then
- writeCentered("You can trade 1 legendary key for 10 vote keys.", 16)
- writeCentered("(stored in the machine) doing !addlegendary <qty>", 17)
- end
- writeCentered("By using this machine and writing !play" .. ( (config.players_database and "or !addkeys <qty>") or '' ) .. ", you", max_y-4)
- writeCentered("acknowledge that your keys will be deducted from your inventory.", max_y-3)
- end
- function displayPrizes()
- loadPrizes()
- clearWhiteWindow()
- mon.setBackgroundColor(colors.white)
- mon.setTextColor(colors.orange)
- writeCentered("Prizes", 4)
- mon.setTextColor(colors.black)
- for i, prize in pairs(prizes) do
- writeCentered(i .. ". " .. prize["name"] .. " (" .. prize["qty"] .. ")", 5 + i)
- end
- nextReset = clock + 8
- end
- function writeCentered(message, y)
- local x = getCenter(max_x, message)
- mon.setCursorPos(x,y)
- mon.write(message)
- end
- function clearWhiteWindow()
- mon.setBackgroundColor(colors.white)
- local whiteLine = ""
- for x=1, max_x, 1 do
- whiteLine = whiteLine .. " "
- end
- for y=2,max_y-1,1 do
- mon.setCursorPos(1,y)
- mon.write(whiteLine)
- end
- end
- function displayPlayerInformation()
- player = getCurrentPlayer()
- if nextReset == -1 or player == "pim" then
- clearWhiteWindow()
- end
- --Clear bottom bar
- mon.setBackgroundColor(config.barColor)
- mon.setCursorPos(1, max_y)
- for x=1, max_x, 1 do
- mon.write(" ")
- end
- if player == "pim" then
- displayWelcome()
- return nil
- end
- --Display help message
- if nextReset == -1 then
- local message = "To play type !play"
- displayMessage(message, colors.lime, -1)
- end
- mon.setTextColor(colors.black)
- mon.setBackgroundColor(config.barColor)
- --Display keys in the inventory
- mon.setCursorPos(2,max_y)
- mon.write("Keys in the inventory: " .. getKeysInInventory() .. " ")
- --Display name of player
- mon.setCursorPos(getCenter(max_x, player),max_y)
- mon.write(player)
- --Display remaining keys
- if config.players_database then
- local rText = "Keys stored: " .. getPlayerUses(player)
- mon.setCursorPos(max_x - string.len(rText) - 2,max_y)
- mon.write(rText)
- end
- end
- --> MONITOR EXTEND -> Prizes display <--
- function printArrows()
- local centerX = getCenter(max_x)
- local centerY = getCenter(max_y)
- local x = centerX + (weidhtBox/2) + 2
- mon.setBackgroundColor(colors.white)
- mon.setTextColor(colors.black)
- mon.setCursorPos(x, centerY)
- mon.write("<----")
- local x = centerX - (weidhtBox/2) - 1 - string.len("---->")
- mon.setCursorPos(x, centerY)
- mon.write("---->")
- end
- function printBox(i, name, offsetY, backgroundColor)
- local min_y_local = max_y + (i-1)*heightBox - offsetY
- if min_y_local > - heightBox then
- if not backgroundColor then
- backgroundColor = colors.orange
- end
- local max_y_local = min_y_local+heightBox
- local centerY = getCenter(max_y)
- local centerX = getCenter(max_x)
- local min_x_local = centerX-(weidhtBox/2)
- local max_x_local = centerX+(weidhtBox/2)
- if min_y_local < centerY and centerY < max_y_local then
- actualPrize = i
- end
- printBoxPaint(min_x_local, min_y_local, max_x_local, max_y_local, backgroundColor)
- --PRINT NAME
- mon.setBackgroundColor(backgroundColor)
- local yText = getCenter(max_y_local-min_y_local) + min_y_local - 1
- local xText = getCenter(max_x, name)
- mon.setTextColor(colors.black)
- mon.setCursorPos(xText, yText)
- if yText > 2 and yText < (max_y - 1) then
- mon.write(name)
- end
- end
- if min_y_local > max_y + heightBox then
- return true
- end
- return false
- end
- function isBorder(x,y, min_x_local, min_y_local, max_x_local, max_y_local)
- if x == min_x_local or y == min_y_local then
- return true
- end
- if x == max_x_local or y == max_y_local then
- return true
- end
- return false
- end
- function printBoxPaint(min_x_local, min_y_local, max_x_local, max_y_local, backgroundColor)
- for x=min_x_local, max_x_local, 1 do
- for y=min_y_local, max_y_local, 1 do
- mon.setCursorPos(x,y)
- --PAINT BOX
- if isBorder(x,y, min_x_local, min_y_local, max_x_local, max_y_local) then
- mon.setBackgroundColor(colors.black)
- else
- mon.setBackgroundColor(backgroundColor)
- end
- if y > 2 and y < (max_y - 1) then
- mon.write(" ")
- end
- end
- end
- end
- --------------------------------------------------------
- --> Music <--
- --------------------------------------------------------
- noteblock = nil
- function music(int, pitch, vol)
- if not noteblock then
- noteblock = peripheral.find("music")
- end
- noteblock.playSound(int, pitch, vol)
- end
- --------------------------------------------------------
- --> Main program <--
- --------------------------------------------------------
- clock = 0
- oldPlayer = nil
- function GUIUpdater()
- while true do
- --Update clock
- clock = os.clock()
- --Get current player
- player = getCurrentPlayer()
- --Monitor tasks
- if not usingMonitor then
- if player ~= "pim" then
- expireOldMessages()
- end
- if oldPlayer ~= player then
- displayPlayerInformation()
- end
- oldPlayer = player
- end
- sleep(0.25)
- end
- end
- usingMonitor = false
- function listener()
- sleep(1)
- while true do
- tEvent = {os.pullEvent()}
- if tEvent[1] == "chatEvent" then
- player = tEvent[2]
- co = tEvent[3]
- if checkPlayer(player) then
- usingMonitor = true
- executeCommand(player, co)
- oldPlayer = nil
- usingMonitor = false
- else
- print(player .. " no esta en el PIM")
- end
- end
- if tEvent[1] == "chat_command" then
- co = tostring(tEvent[2])
- player = tostring(tEvent[3])
- if checkPlayer(player) then
- usingMonitor = true
- executeCommand(player, co)
- oldPlayer = nil
- usingMonitor = false
- else
- print(player .. " no esta en el PIM")
- end
- end
- end
- end
- function startProgram()
- --Setup screen
- setupScreen()
- --LOAD FILES
- loadPrizes()
- loadCodes()
- loadUses()
- parallel.waitForAny(listener,GUIUpdater)
- error()
- end
- parallel.waitForAny(gcapi.startChatEventQueue, startProgram)
- error()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement