· last year · Nov 15, 2023, 07:00 AM
1--[[MIT License
2
3Copyright (c) 2022 Cod0fDuty
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE.]]--
22
23
24--If you use this program in a video/post, I would greatly appreciate it if you would credit my Youtube channel https://www.youtube.com/c/Cod0fDuty.
25--Please let me know if you have any questions or suggestions, feel free to contact me at cod0fdutyt@gmail.com.
26
27
28local apiName = "touchpoint"
29local pasteLink = "pFHeia96"
30local infoName = "info"
31
32term.clear()
33term.setCursorPos(1,1)
34
35if not fs.exists(apiName) then
36 shell.run("pastebin get " .. pasteLink .. " " .. apiName) --downloads the API
37end
38
39os.loadAPI(apiName)
40peripheral.find("modem", rednet.open)
41local monitor = peripheral.find("monitor")
42monitor.setTextScale(0.5)
43monitor.clear()
44
45local monitorWidth, monitorHeight = monitor.getSize()
46if monitorWidth >= 36 and monitorHeight >= 24 then --changes text scale depending on the monitor size
47 monitor.setTextScale(1)
48 monitorWidth, monitorHeight = monitor.getSize()
49end
50
51local monitorSide
52for _,name in ipairs(peripheral.getNames()) do --gets the side the monitor is on
53 if peripheral.getType(name) == "monitor" then
54 monitorSide = name
55 end
56end
57
58term.clear()
59term.setCursorPos(1,1)
60print("A ComputerCraft Program by Cod0fDuty")
61print("Touchpoint API by Lyqyd")
62print("Elevator Screen Module")
63
64local floor = ""
65local id = ""
66local currentPage
67
68while not fs.exists(infoName) or not floor or not id do --check if file exists
69 term.setCursorPos(1,6)
70 term.clearLine()
71 term.setCursorPos(1,5)
72 term.clearLine()
73 local h = fs.open("info", "w")
74 term.write("Total number of floors: ")
75 floor = tonumber(read())
76 term.write("ID of receiving computer: ")
77 id = tonumber(read())
78 currentPage = 1
79 local infoTable = {floor, id, currentPage}
80 h.write(textutils.serialize(infoTable))
81 h.close()
82end
83
84local h = fs.open(infoName, "r") --reads from a file
85local infoTable = textutils.unserialize(h.readAll())
86if not infoTable then
87 fs.delete(infoName)
88 os.reboot()
89end
90floor = tonumber(infoTable[1])
91id = tonumber(infoTable[2])
92currentPage = tonumber(infoTable[3])
93term.setCursorPos(1,5)
94print("Total number of floors: " .. floor)
95print("ID of receiving computer: " .. id)
96h.close()
97
98local buttonsPerColumn = math.floor((monitorHeight)/2)
99local numberOfColumns = math.min(math.ceil(floor/buttonsPerColumn), 3)
100local maxButtonsInOnePage = buttonsPerColumn * 3
101local numberOfPages = math.ceil(floor/maxButtonsInOnePage)
102local buttonWidth = monitorWidth - 2
103
104if floor * 2 >= monitorHeight then
105 buttonWidth = math.floor((monitorWidth-numberOfColumns - 3)/numberOfColumns) --calculates the width of buttons
106end
107
108if currentPage > numberOfPages then --if monitor size is changed, current page will be set to the maximum number of pages
109 currentPage = numberOfPages
110end
111
112local page = {}
113for i = 1, numberOfPages do
114 page[i] = touchpoint.new(monitorSide) --add pages
115 if i ~= numberOfPages then
116 page[i]:add(">>", nil, monitorWidth-3, monitorHeight, monitorWidth, monitorHeight, colors.black, colors.white)
117 end
118 if i ~= 1 then
119 page[i]:add("<<", nil, 1, monitorHeight, 4, monitorHeight, colors.black, colors.white)
120 end
121 if numberOfPages > 1 then
122 local pageLabel
123 if monitorWidth == 15 then
124 pageLabel = "P." .. i
125 else --add page number
126 pageLabel = "Page " .. i
127 end
128 page[i]:add(pageLabel, nil, 5, monitorHeight, monitorWidth-4, monitorHeight, colors.black, colors.black)
129 end
130end
131
132local minX = 2
133local minY = 1
134local maxX = monitorWidth - 1
135local maxY = minY
136
137local pageIndex = 1
138local topFloor = floor - 1
139
140if topFloor < buttonsPerColumn then
141 for i = topFloor, 0, -1 do
142 page[pageIndex]:add(tostring(i), nil, minX, minY, maxX, maxY, colors.red, colors.lime) --adds buttons in reverse
143 minY = minY + 2
144 maxY = minY
145 end
146else
147 minX = 2
148 maxX = minX + buttonWidth
149 minY = monitorHeight - 1
150 maxY = minY
151 for i = 0, topFloor do
152 page[pageIndex]:add(tostring(i), nil, minX, minY, maxX, maxY, colors.red, colors.lime)
153 local remainingFloors = topFloor - i
154 minY = maxY - 2
155 maxY = minY
156 if maxY <= 0 then --move buttons to the next column
157 minX = maxX + 2
158 maxX = minX + buttonWidth
159 minY = monitorHeight - 1
160 maxY = minY
161 if maxX > monitorWidth then --change to next page
162 pageIndex = pageIndex + 1
163 minX = 2
164 maxX = minX + buttonWidth
165 minY = monitorHeight - 1
166 maxY = minY
167 end
168 if remainingFloors < buttonsPerColumn then --moves the buttons up if there are spaces
169 minY = monitorHeight - 1 - ((buttonsPerColumn - remainingFloors) * 2)
170 maxY = minY
171 end
172 end
173 end
174end
175
176term.setCursorPos(1,8)
177print("Press E to clear data...")
178
179while true do
180 page[currentPage]:draw() --draws the buttons on the monitor
181 local h = fs.open(infoName, "w")
182 local infoTable = {floor, id, currentPage}
183 h.write(textutils.serialize(infoTable))
184 h.close()
185 local event, p1 = page[currentPage]:handleEvents(os.pullEvent())
186 if event == "button_click" then --wait for button clicks
187 local chosen = tonumber(p1)
188 page[currentPage]:flash(p1)
189 if chosen ~= nil then
190 rednet.send(id, chosen, "call")
191 rs.setOutput("bottom", true)
192 elseif p1 == ">>" then
193 currentPage = currentPage + 1
194 elseif p1 == "<<" then
195 currentPage = currentPage - 1
196 end
197 elseif event == "key" and p1 == keys.e then
198 fs.delete(infoName) --deletes the file
199 term.setCursorPos(1,9)
200 print("Cleared!")
201 sleep(1)
202 os.reboot()
203 end
204end
205
206
207--[[
208⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
209⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣶⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
210⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⠿⠟⠛⠻⣿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
211⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣆⣀⣀⠀⣿⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
212⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠻⣿⣿⣿⠅⠛⠋⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
213⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⢼⣿⣿⣿⣃⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
214⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣟⡿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
215⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣛⣛⣫⡄⠀⢸⣦⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
216⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣾⡆⠸⣿⣿⣿⡷⠂⠨⣿⣿⣿⣿⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
217⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣤⣾⣿⣿⣿⣿⡇⢀⣿⡿⠋⠁⢀⡶⠪⣉⢸⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
218⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⣿⡏⢸⣿⣷⣿⣿⣷⣦⡙⣿⣿⣿⣿⣿⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
219⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣿⣿⣿⣿⣿⣿⣿⣿⣇⢸⣿⣿⣿⣿⣿⣷⣦⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
220⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
221⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀
222⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀
223⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀
224⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀
225⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢹⣿⣵⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣯⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
226--]]
227
228--https://www.youtube.com/watch?v=dQw4w9WgXcQ