Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- os.loadAPI("ocs/apis/sensor")
- rednet.open("right")
- local prox = sensor.wrap("top")
- local wired = peripheral.wrap("bottom")
- local monitor, chatbox, playerDetector
- for k,v in pairs(wired.getNamesRemote()) do
- local name = wired.getTypeRemote(v)
- if name == "monitor" then
- monitor = peripheral.wrap(v)
- elseif name == "chat" then
- chatbox = peripheral.wrap(v)
- elseif name == "playerDetector" then
- playerDetector = peripheral.wrap(v)
- end
- end
- if prox == nil then error("unable to find proximity sensor") end
- if monitor == nil then error("unable to find monitor") end
- if not monitor.isColor() then error("not an advanced monitor") end
- if chatbox == nil then error("unable to find chatbox") end
- if playerDetector == nil then error("unable to find player detector") end
- monitor.setTextScale(1)
- local w,h = monitor.getSize()
- local maxHighScores = 20
- local score = 0
- local offset = {}
- offset.X = 17
- offset.Z = 14
- local facings = {{-1,0},{0,1},{1,0},{0,-1}}
- local ghosts =
- {
- ["Blinky"] = {},
- ["Pinky"]= {},
- ["Inky"] = {},
- ["Clyde"] = {}
- }
- local logo =
- {
- "###..............##.##........",
- "#..#.#.##.#.#....#.#.#..#..###",
- "###..#.#..##..##.#...#.#.#.#.#",
- "#....#.##.#.#....#...#.#.#.#.#"
- }
- local logocolor = colors.yellow
- ghosts["Blinky"].state = "scatter"
- ghosts["Blinky"].X = 14
- ghosts["Blinky"].Y = 12
- ghosts["Blinky"].color = colors.red
- ghosts["Blinky"].fuel = 0
- ghosts["Pinky"].state = "scatter"
- ghosts["Pinky"].X = 14
- ghosts["Pinky"].Y = 12
- ghosts["Pinky"].fuel = 0
- ghosts["Pinky"].color = colors.pink
- ghosts["Inky"].state = "scatter"
- ghosts["Inky"].X = 14
- ghosts["Inky"].Y = 12
- ghosts["Inky"].fuel = 0
- ghosts["Inky"].color = colors.lightBlue
- ghosts["Clyde"].state = "scatter"
- ghosts["Clyde"].X = 14
- ghosts["Clyde"].Y = 12
- ghosts["Clyde"].color = colors.orange
- ghosts["Clyde"].fuel = 0
- local playername
- local options =
- {
- ["instakill"] = {},
- ["quitonexit"] = {},
- ["resetscores"] = {}
- }
- options["instakill"].name = "Instant Death"
- options["instakill"].type = "boolean"
- options["instakill"].value = false
- options["instakill"].color = colors.red
- options["quitonexit"].name = "Quit when leaving area"
- options["quitonexit"].type = "boolean"
- options["quitonexit"].value = true
- options["quitonexit"].color = colors.lime
- options["resetscores"].name = "Reset scores"
- options["resetscores"].type = "confirm"
- options["resetscores"].value = false
- options["resetscores"].color = colors.red
- local data = {}
- data.X = 1
- data.Y = 1
- data.dX = -1
- data.dY = 0
- data.gold = 0
- data.diamonds = 0
- data.blinkyX = 0
- data.blinkyY = 0
- data.health = 20
- data.started = false
- data.quit = false
- local maze =
- {
- "############################",
- "#............##............#",
- "#.####.#####.##.#####.####.#",
- "#.####.#####.##.#####.####.#",
- "#.####.#####.##.#####.####.#",
- "#..........................#",
- "#.####.##.########.##.####.#",
- "#.####.##.########.##.####.#",
- "#......##....##....##......#",
- "######.#####.##.#####.######",
- ".....#.#####+##+#####.#.....",
- ".....#.##..........##.#.....",
- ".....#.##.###--###.##.#.....",
- "######.##.#......#.##.######",
- "..........#......#..........",
- "######.##.#......#.##.######",
- ".....#.##.########.##.#.....",
- ".....#.##..........##.#.....",
- ".....#.##.########.##.#.....",
- "######.##.########.##.######",
- "#............##............#",
- "#.####.#####.##.#####.####.#",
- "#.####.#####+##+#####.####.#",
- "#...##................##...#",
- "###.##.##.########.##.##.###",
- "###.##.##.########.##.##.###",
- "#......##....##....##......#",
- "#.##########.##.##########.#",
- "#.##########.##.##########.#",
- "#..........................#",
- "############################"
- }
- local printTable = function(t)
- print(textutils.serialize(t))
- end
- local tableSize = function(t)
- local size = 0
- for k,v in pairs(t) do
- size = size + 1
- end
- return size
- end
- local printLogo = function()
- local posx = 5
- local posy = 1
- for y, line in pairs(logo) do
- for x =1,line:len() do
- if line:sub(x,x) == "#" then
- paintutils.drawPixel(x+posx,y+posy,logocolor)
- end
- end
- end
- end
- local printMap = function()
- term.redirect(monitor)
- monitor.setBackgroundColor(colors.black)
- monitor.clear()
- local posx = 4
- local posy = 1
- for y,line in pairs(maze) do
- for x = 1,#line do
- local cell = line:sub(x,x)
- if cell == "#" then
- paintutils.drawPixel(x+posx,y+posy,colors.blue)
- elseif cell == "-"then
- paintutils.drawPixel(x+posx,y+posy,colors.white)
- end
- end
- end
- for k,v in pairs(ghosts) do
- if v.state == "frightened" then
- paintutils.drawPixel(v.X+posx,v.Y+posy,colors.gray)
- elseif v.state == "dead" then
- if k == "Blinky" then
- paintutils.drawPixel(14+posx,14+posy,v.color)
- elseif k == "Inky" then
- paintutils.drawPixel(13+posx,15+posy,v.color)
- elseif k == "Pinky" then
- paintutils.drawPixel(15+posx,15+posy,v.color)
- else
- paintutils.drawPixel(17+posx,15+posy,v.color)
- end
- else
- paintutils.drawPixel(v.X+posx,v.Y+posy,v.color)
- end
- end
- paintutils.drawPixel(data.X+posx,data.Y+posy,colors.yellow)
- term.setCursorPos(5,35)
- term.write("Score: "..tostring(score))
- term.restore()
- end
- local loadScores = function()
- if not fs.exists("pickmanscores") then
- return {}
- end
- local scorefile = fs.open("pickmanscores","r")
- if scorefile == nil then error("unable to load scores") end
- local highScores = {}
- local line = scorefile.readLine()
- while line ~= nil do
- local score = {}
- local i = line:find(" ")
- score.name = line:sub(1,i-1)
- score.score = tonumber(line:sub(i+1,line:len()))
- table.insert(highScores,score)
- line = scorefile.readLine()
- end
- scorefile.close()
- return highScores
- end
- local saveScores = function(scores)
- table.sort(scores,function(a,b) return a.score > b.score end)
- local scorefile = fs.open("pickmanscores","w")
- if scorefile == nil then error("unable to open score file for saving") end
- local n = math.min(tableSize(scores),maxHighScores)
- for i = 1,n do
- local line = scores[i].name.." "..tostring(scores[i].score)
- scorefile.writeLine(line)
- end
- scorefile.close()
- end
- local deleteScores = function ()
- if fs.exists("pickmanscores") then fs.delete("pickmanscores") end
- end
- local start, menu, mainMenu, optionsMenu, highscoreMenu, highScores
- local ghostnames = {}
- local printButton = function(button,color)
- term.setBackgroundColor(color)
- for j = 1,button.sizeY do
- term.setCursorPos(button.X,button.Y+j-1)
- term.write(string.rep(" ",button.sizeX))
- end
- term.setCursorPos(button.X+math.floor((button.sizeX-button.text:len())/2),button.Y+math.floor(button.sizeY/2))
- term.write(button.text)
- end
- local printButtons = function(buttons)
- for k,v in pairs(buttons) do
- printButton(v,v.color)
- end
- end
- local flashButton = function(button)
- printButton(button, button.colorFlash)
- --term.setCursorPos(1000,1000)
- sleep(0.2)
- printButton(button, button.color)
- sleep(0.1)
- end
- local waitForButton = function(buttons)
- local button
- while button == nil do
- local e, side, X, Y = os.pullEvent("monitor_touch")
- for k,v in pairs(buttons) do
- if X >= v.X and X <= v.X+v.sizeX and Y >= v.Y and Y <= v.Y+v.sizeY then
- button = k
- break
- end
- end
- end
- return button
- end
- local optionsToggle = function(key)
- options[key].value = not options[key].value
- if options[key].value then
- options[key].color = colors.lime
- optionsMenu[key].color = colors.lime
- optionsMenu[key].colorFlash = colors.lime
- optionsMenu[key].text = "On"
- else
- options[key].color = colors.red
- optionsMenu[key].color = colors.red
- optionsMenu[key].colorFlash = colors.red
- optionsMenu[key].text = "Off"
- end
- end
- local confirmCheck = function(key)
- local item = optionsMenu[key]
- item.text = " Sure?"
- item.color = colors.blue
- printButtons(optionsMenu)
- local e, side, X, Y = os.pullEvent("monitor_touch")
- if X >= item.X and X <= item.X+item.sizeX and Y >= item.Y and Y <= item.Y+item.sizeY then
- deleteScores()
- end
- item.text = "Delete"
- item.color = colors.red
- end
- local showOptions = function()
- term.setBackgroundColor(colors.black)
- term.clear()
- menu = optionsMenu
- local i = 0
- for k,v in pairs(options) do
- term.setCursorPos(5,6+8*i)
- term.write(v.name)
- i = i + 1
- end
- end
- local showHighScore = function()
- term.setBackgroundColor(colors.black)
- term.clear()
- menu = highscoreMenu
- highScores = loadScores()
- table.sort(highScores,function(a,b) return a.score > b.score end)
- local width = 28
- term.setCursorPos(math.floor((w-11)/2),2)
- term.write("High Scores")
- term.setCursorPos(math.floor((w-width)/2),3)
- term.write(string.rep(" ",width))
- local n = math.min(tableSize(highScores),maxHighScores)
- for i = 1,n do
- term.setCursorPos(5,3+i)
- local name = highScores[i].name:sub(1,10)
- local score = highScores[i].score
- local enum = tostring(i)
- local whitespaces = width-4-name:len()-tostring(score):len()
- term.write(enum.."."..string.rep(" ",4-enum:len())..name..string.rep(" ",whitespaces)..tostring(score))
- end
- for i=n+1,maxHighScores do
- term.setCursorPos(5,3+i)
- local enum = tostring(i)
- local whitespaces = width-8
- term.write(enum.."."..string.rep(" ",4-enum:len()).."..."..string.rep(" ",whitespaces).."0")
- end
- end
- local startGame = function()
- start = true
- end
- local showMainMenu = function()
- term.setBackgroundColor(colors.black)
- term.clear()
- printLogo()
- term.setBackgroundColor(colors.black)
- menu = mainMenu
- term.setCursorPos(2,h)
- term.write("Fuel:")
- local i = 1
- for k,v in pairs(ghosts) do
- term.setCursorPos(7+2*i,h)
- if v.fuel > 5000 then
- term.setTextColor(colors.lime)
- elseif v.fuel > 500 then
- term.setTextColor(colors.yellow)
- else
- term.setTextColor(colors.red)
- end
- term.write(k:sub(1,1))
- i = i+1
- end
- term.setTextColor(colors.white)
- end
- print("Setting up...")
- sleep(1)
- print("Finding ghosts...")
- for k,v in pairs(ghosts) do
- rednet.broadcast(k:lower())
- local id, message, dist = rednet.receive()
- message = textutils.unserialize(message)
- while message.text ~= "check" do
- id, message, dist = rednet.receive()
- message = textutils.unserialize(message)
- end
- print("Found "..k.."!")
- ghosts[k].fuel = message.fuel
- ghostnames[id] = k
- sleep(0.3)
- end
- print("Ghosts located!")
- print("Setting up menu.")
- mainMenu =
- {
- ["start"] = {},
- ["options"] = {},
- ["highscore"] = {}
- }
- mainMenu["start"].text = "Start"
- mainMenu["start"].X = math.floor((w-13)/2)
- mainMenu["start"].Y = 10
- mainMenu["start"].sizeX = 13
- mainMenu["start"].sizeY = 5
- mainMenu["start"].color = colors.red
- mainMenu["start"].colorFlash= colors.lime
- mainMenu["start"].func = startGame
- mainMenu["options"].text = "Options"
- mainMenu["options"].X = math.floor((w-13)/2)
- mainMenu["options"].Y = 17
- mainMenu["options"].sizeX = 13
- mainMenu["options"].sizeY = 5
- mainMenu["options"].color = colors.red
- mainMenu["options"].colorFlash = colors.lime
- mainMenu["options"].func = showOptions
- mainMenu["highscore"].text = "High Scores"
- mainMenu["highscore"].X = math.floor((w-13)/2)
- mainMenu["highscore"].Y = 24
- mainMenu["highscore"].sizeX = 13
- mainMenu["highscore"].sizeY = 5
- mainMenu["highscore"].color = colors.red
- mainMenu["highscore"].colorFlash = colors.lime
- mainMenu["highscore"].func = showHighScore
- optionsMenu = {}
- for k,v in pairs(options) do
- local tmp = {}
- local n = tableSize(optionsMenu)
- tmp.X = 30
- tmp.Y = 5+8*n
- if v.type == "boolean" then
- if v.value then
- tmp.text = "On"
- else
- tmp.text = "Off"
- end
- tmp.sizeX = 5
- tmp.sizeY = 3
- tmp.func = function() optionsToggle(k) end
- elseif v.type == "confirm" then
- tmp.text = "Delete"
- tmp.sizeX = 8
- tmp.sizeY = 3
- tmp.func = function() confirmCheck(k) end
- else
- tmp.sizeX = 3
- tmp.sizeY = 3
- tmp.func = nil
- end
- tmp.color = v.color
- tmp.colorFlash = v.color
- optionsMenu[k] = tmp
- end
- optionsMenu["back"] = {}
- optionsMenu["back"].text = "Back"
- optionsMenu["back"].X = 5
- optionsMenu["back"].Y = h-4
- optionsMenu["back"].sizeX = 8
- optionsMenu["back"].sizeY = 3
- optionsMenu["back"].color = colors.red
- optionsMenu["back"].colorFlash = colors.lime
- optionsMenu["back"].func = showMainMenu
- highscoreMenu = {}
- highscoreMenu["back"] = optionsMenu["back"]
- term.redirect(monitor)
- term.clear()
- term.setBackgroundColor(colors.black)
- --[[
- printLogo()
- term.setCursorPos(math.ceil((w-24)/2),math.floor(h/2))
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.red)
- term.write("Touch anywhere to start.")
- os.pullEvent("monitor_touch")
- term.setTextColor(colors.white)
- ]]--
- showMainMenu()
- while not start do
- printButtons(menu)
- local b = waitForButton(menu)
- term.restore()
- term.redirect(monitor)
- flashButton(menu[b])
- menu[b].func()
- end
- term.setBackgroundColor(colors.black)
- term.clear()
- monitor.setTextScale(2)
- term.setCursorPos(6,3)
- term.write("Click the")
- term.setCursorPos(3,4)
- term.write("Player Detector")
- term.setCursorPos(6,5)
- term.write("to begin.")
- local event, arg = os.pullEvent("player")
- playername = arg
- term.clear()
- w,h = monitor.getSize()
- term.setCursorPos(6,3)
- term.write("Good Luck")
- term.setTextColor(colors.red)
- term.setCursorPos(math.ceil((w-playername:len())/2),4)
- term.write(playername)
- term.setTextColor(colors.white)
- term.setCursorPos(5,11)
- term.write("Use the book")
- term.setCursorPos(5,12)
- term.write("to reach the")
- term.setCursorPos(4,13)
- term.write("starting area.")
- term.setCursorPos(5,8)
- term.write("Get equipment")
- term.setCursorPos(4,9)
- term.write("from the chest.")
- local yawToFacing = function(yaw)
- local ind = math.floor(math.fmod(math.abs(yaw)+45,360)/90)
- return facings[ind+1]
- end
- local worldToGame = function(X,Z)
- return {offset.Z+Z,offset.X-X}
- end
- local updateData = function()
- local details = prox.getTargetDetails(playername)
- if details ~= nil then
- local pos = worldToGame(details.Position.X,details.Position.Z)
- local facing = yawToFacing(details.Yaw)
- data.X = pos[1]
- data.Y = pos[2]
- if options["quitonexit"].value and data.started then
- if data.X < -2 or data.X > 32 or data.Y < 1 or data.Y > 31 then
- data.quit = true
- end
- end
- data.dX = facing[1]
- data.dY = facing[2]
- local g = 0
- local d = 0
- if not details.IsAlive then
- data.quit = true
- end
- if options["instakill"].value == true and details.Health < data.health then
- data.quit = true
- end
- for k,v in pairs(details.Inventory) do
- if v["Name"] == "Diamond" then
- d = d+v["Size"]
- elseif v["Name"] == "Gold Ore" then
- g = g+v["Size"]
- end
- end
- if g > data.gold then
- score = score + 10*(g-data.gold)
- data.gold = g
- end
- if d > data.diamonds then
- chatbox.tell(playername,"Energized!",1800)
- score = score + 50*(d-data.diamonds)
- data.diamonds = d
- end
- end
- end
- local quit = function()
- chatbox.tell(playername,"Game Over! Return to main screen.", 60)
- term.restore()
- print("Sending quit signal to ghosts.")
- local checks = {}
- while tableSize(checks) < 4 do
- rednet.broadcast(textutils.serialize(data))
- local id, message, dist = rednet.receive(0.2)
- local ghost = ghostnames[id]
- if ghost ~= nil and message == "quitting" then
- checks[ghost] = true
- rednet.send(id, "check")
- end
- end
- print("All ghosts report.")
- term.redirect(monitor)
- end
- updateData()
- while not (math.floor(data.X) == 14 and math.floor(data.Y) == 24) do
- sleep(0.3)
- updateData()
- end
- data.started = true
- sleep(0.5)
- term.clear()
- monitor.setTextScale(1)
- chatbox.tell(playername,"Go!",60)
- term.restore()
- print("Sending start message...")
- rednet.broadcast("start")
- while true do
- updateData()
- if data.quit then
- quit()
- break
- end
- local id, message, dist = rednet.receive(0.2)
- local ghost = ghostnames[id]
- if ghost ~= nil then
- message = textutils.unserialize(message)
- ghosts[ghost].X = message.X
- ghosts[ghost].Y = message.Y
- if ghost == "Blinky" then
- data.blinkyX = message.X
- data.blinkyY = message.Y
- end
- if message.state == "dead" and ghosts[ghost].state ~= "dead" then
- score = score + 400
- end
- ghosts[ghost].state = message.state
- rednet.send(id,textutils.serialize(data))
- end
- printMap()
- end
- term.restore()
- print("Player "..playername.." finished with a score: "..tostring(score))
- highScores = loadScores()
- local tmpscore = {}
- tmpscore.name = playername
- tmpscore.score = score
- table.insert(highScores,tmpscore)
- saveScores(highScores)
- term.redirect(monitor)
- term.setBackgroundColor(colors.black)
- term.clear()
- menu = highscoreMenu
- highScores = loadScores()
- table.sort(highScores,function(a,b) return a.score > b.score end)
- local width = 28
- term.setCursorPos(math.floor((w-11)/2),2)
- term.write("High Scores")
- term.setCursorPos(math.floor((w-width)/2),3)
- term.write(string.rep(" ",width))
- local n = math.min(tableSize(highScores),maxHighScores)
- for i = 1,n do
- term.setTextColor(colors.white)
- term.setCursorPos(5,3+i)
- local name = highScores[i].name:sub(1,10)
- local tmpscore = highScores[i].score
- local enum = tostring(i)
- local whitespaces = width-4-name:len()-tostring(score):len()
- if tonumber(tmpscore) == score and name == playername:sub(1,10) then
- term.setTextColor(colors.red)
- end
- term.write(enum.."."..string.rep(" ",4-enum:len())..name..string.rep(" ",whitespaces)..tostring(tmpscore))
- end
- term.setTextColor(colors.white)
- for i=n+1,maxHighScores do
- term.setCursorPos(5,3+i)
- local enum = tostring(i)
- local whitespaces = width-8
- term.write(enum.."."..string.rep(" ",4-enum:len()).."..."..string.rep(" ",whitespaces).."0")
- end
- term.setCursorPos(2,25)
- term.write("Touch anywhere to continue")
- os.pullEvent("monitor_touch")
- term.clear()
- term.restore()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement