· 4 years ago · Aug 21, 2021, 12:00 PM
1-- Traffic & Infrastructure Agency
2-- Vehicle Self-Registration Kiosk
3
4PROVINCE_ID = 1
5
6TiaAPI = require("tia-shared-api")
7
8ButtonCallbacks = {}
9TextField = { Active = false }
10
11function DrawButton(data)
12 -- buttonData:
13 -- PosX 1
14 -- PosY 1
15 -- BackgroundColor colors.white
16 -- TextColor colors.black
17 -- Text "Button"
18 -- Compact true
19 -- Callback nil
20
21 -- Set default values
22 local posX = data.PosX or 1
23 local posY = data.PosY or 1
24 local bgColor = data.BackgroundColor or colors.white
25 local fgColor = data.TextColor or colors.black
26 local text = data.Text or "Button"
27 local compact = true
28 local callback = data.Callback
29 if data.Compact ~= nil then
30 compact = data.Compactd
31 end
32
33 -- For padding for non-compact buttons
34 -- +2 padding on the sidesd
35 local textLength = string.len(text) + 2
36
37 term.setBackgroundColor(bgColor)
38 term.setTextColor(fgColor)
39
40 if not compact then
41 term.setCursorPos(posX, posY)
42 for i=1, textLength do
43 term.write(" ")
44 end
45 end
46
47 term.setCursorPos(posX, compact and posY or posY+1)
48 term.write(" " .. text .. " ")
49
50 if not compact then
51 term.setCursorPos(posX, posY + 2)
52 for i=1, textLength do
53 term.write(" ")
54 end
55 end
56
57 if callback then
58 table.insert(ButtonCallbacks, {
59 StartX = posX,
60 EndX = posX + textLength,
61 StartY = posY,
62 EndY = posY + (compact and 0 or 2),
63 Callback = callback
64 })
65 end
66end
67
68function ClearCallbacks()
69 ButtonCallbacks = {}
70 TextField = { Active = false }
71 term.setCursorBlink(false)
72end
73
74function DrawHeader(text, bgColor)
75 -- Colors
76 term.setBackgroundColor(bgColor)
77 term.setTextColor(colors.white)
78
79 -- Background
80 term.setCursorPos(1,1)
81 term.clearLine()
82 term.setCursorPos(1,2)
83 term.clearLine()
84 term.setCursorPos(1,3)
85 term.clearLine()
86
87 -- Text
88 term.setCursorPos(3,2)
89 term.write(text)
90end
91
92function ShowMainScreen()
93 ClearCallbacks()
94
95 -- Background
96 term.setBackgroundColor(colors.white)
97 term.clear()
98
99 -- Draw header
100 DrawHeader("Agentsiya Transport i Infrastruktura", colors.green)
101 term.setBackgroundColor(colors.white)
102 term.setTextColor(colors.black)
103
104 -- Primary text
105 term.setCursorPos(3,6)
106 term.write("Dobre doshli v terminala na Agentsiya Transport")
107 term.setCursorPos(5,7)
108 term.write("i Infrastruktura. Molya, izberete procedura:")
109
110 DrawButton({
111 PosX = 8,
112 PosY = 9,
113 BackgroundColor = colors.red,
114 TextColor = colors.white,
115 Text = "Spravki",
116 Compact = false,
117 Callback = ShowQueriesScreen
118 })
119
120 DrawButton({
121 PosX = 18,
122 PosY = 9,
123 BackgroundColor = colors.blue,
124 TextColor = colors.white,
125 Text = "Registratsiya na avtomobil",
126 Compact = false,
127 Callback = ShowRegistrationScreen
128 })
129
130 local _, lastLine = term.getSize()
131 term.setCursorPos(1, lastLine)
132 term.setBackgroundColor(colors.lightGray)
133 term.clearLine()
134 term.setTextColor(colors.black)
135 term.write("ATI " .. TiaAPI.ProvinceNames[PROVINCE_ID])
136end
137
138function ShowQueriesScreen()
139 ClearCallbacks()
140
141 term.setBackgroundColor(colors.white)
142 term.clear()
143
144 DrawHeader("ATI - Spravki", colors.red)
145
146 term.setCursorPos(7,6)
147 term.setBackgroundColor(colors.white)
148 term.setTextColor(colors.black)
149 term.write("Dobre doshli v modula za spravki na ATI!")
150 term.setCursorPos(5,7)
151 term.write("Molya izpishete nomera na avtomobila otdolu:")
152
153 DrawButton({
154 PosX = 7,
155 PosY = 9,
156 BackgroundColor = colors.lightGray,
157 Text = " ",
158 Compact = true,
159 Callback = nil
160 })
161
162 TextField = {
163 Active = true,
164 PosX = 8,
165 PosY = 10,
166 Text = "",
167 MaxLength = 8,
168 AllowSpaces = false
169 }
170
171 DrawButton({
172 PosX = 38,
173 PosY = 9,
174 BackgroundColor = colors.black,
175 TextColor = colors.white,
176 Text = "Tursene",
177 Compact = false,
178 Callback = SearchQuery
179 })
180
181 DrawButton({
182 PosX = 3,
183 PosY = 15,
184 BackgroundColor = colors.gray,
185 TextColor = colors.white,
186 Text = "<<< Obratno v nachaloto",
187 Compact = false,
188 Callback = ShowMainScreen
189 })
190
191 term.setBackgroundColor(colors.lightGray)
192 term.setTextColor(colors.black)
193 term.setCursorPos(8, 10)
194 term.setCursorBlink(true)
195end
196
197function SearchQuery()
198 local queryText = TextField.Text
199
200 ClearCallbacks()
201
202 DrawHeader("Tursene...", colors.blue)
203
204 local success, message = pcall(function()
205 return TiaAPI.FetchData(queryText)
206 end)
207
208 if not success then
209 message = string.sub(message, -1)
210 if message == "1" then
211 ShowResults(false, "Nyama namerena registratsiya " .. queryText)
212 elseif message == "2" then
213 ShowResults(false, "Nevaliden kod na oblast " .. string.sub(queryText, 1, 2))
214 end
215 else
216 ShowResults(true, message)
217 end
218end
219
220function ShowResults(success, data)
221 ClearCallbacks()
222
223 term.setBackgroundColor(colors.white)
224 term.clear()
225
226 if success then
227 DrawHeader("Rezultati", colors.green)
228 else
229 DrawHeader("Imashe greshka", colors.red)
230 end
231
232 term.setBackgroundColor(colors.white)
233 term.setTextColor(colors.black)
234 term.setCursorPos(3,6)
235
236 if not success then
237 term.write(data)
238 end
239
240 local y = 8
241
242 if success then
243 term.write("Rezultat ot spravkata:")
244
245 for key, value in pairs(data) do
246 -- Display traits meaningfully
247 if key == "Traits" then
248 if value == 0 then
249 value = "-"
250 elseif value == 1 then
251 value = "Avtomobil na invalid"
252 elseif value == 2 then
253 value = "Firmen avtomobil"
254 elseif value == 3 then
255 value = "Lineika"
256 elseif value == 4 then
257 value = "Taksi"
258 elseif value == 5 then
259 value = "Avtomobil na ATI"
260 else
261 value = "[Error]"
262 end
263 end
264
265 -- Translate
266 if key == "Number" then
267 key = "Nomer"
268 elseif key == "Traits" then
269 key = "Belezhki"
270 elseif key == "Registration" then
271 key = "Registratsiya"
272 elseif key == "Owner" then
273 key = "Sobstvenik"
274 elseif key == "Block" then
275 key = "Seriya"
276 end
277
278 term.setTextColor(colors.gray)
279 term.setCursorPos(3, y)
280 term.write(key)
281 term.setCursorPos(20, y)
282 term.setTextColor(colors.black)
283 term.write(value)
284
285 y = y + 1
286 end
287 end
288
289 y = y + 1
290 DrawButton({
291 PosX = 3,
292 PosY = y,
293 BackgroundColor = colors.black,
294 TextColor = colors.white,
295 Text = "<<< Obratno v nachaloto",
296 Compact = false,
297 Callback = ShowMainScreen
298 })
299end
300
301function ShowRegistrationScreen()
302 ClearCallbacks()
303
304 local playerName = ""
305 local carBrand = ""
306 local color = ""
307 local ambulance = false
308
309 local function question5(previousAnswer)
310 ambulance = (previousAnswer == "DA")
311
312 term.setBackgroundColor(colors.white)
313 term.clear()
314
315 DrawHeader("Molya izchakaite...", colors.black)
316
317 term.setCursorPos(3,6)
318 term.setBackgroundColor(colors.white)
319 term.setTextColor(colors.black)
320 term.write("Sistemata vpisva vashata registratsiya...")
321
322 sleep(5)
323 local number = TiaAPI.RegisterVehicle(
324 playerName,
325 carBrand,
326 color,
327 PROVINCE_ID,
328 ambulance and 3 or 0
329 )
330 TiaAPI.PrintRegistration(number)
331
332 -- success/fail screen
333 term.setCursorBlink(false)
334
335 DrawHeader("Agenstiya Transport i Infrastruktura", colors.blue)
336
337 term.setBackgroundColor(colors.white)
338 term.setTextColor(colors.black)
339 term.setCursorPos(3,6)
340 term.clearLine()
341 term.setCursorPos(3,6)
342 term.write("Registraciyata vi be USPESHNA")
343 term.setCursorPos(3,8)
344 term.write("Molya otvorete PRINTERA pod tozi kompyutar, za")
345 term.setCursorPos(3,9)
346 term.write("vidite nomera na registratsiyata.")
347 term.setCursorPos(3,11)
348 term.setTextColor(colors.red)
349 term.write("MOLYA NE OSTAVYAITE LISTA OBRATNO V PRINTERA!")
350
351 DrawButton({
352 PosX = 3,
353 PosY = 13,
354 BackgroundColor = colors.blue,
355 TextColor = colors.white,
356 Text = "<<< Obratno v nachaloto",
357 Compact = false,
358 Callback = ShowMainScreen
359 })
360 end
361
362 local function question4(previousAnswer)
363 -- Traits
364 color = previousAnswer
365
366 PromptQuestion(
367 "Registratsiya - IV",
368 "Tova lineika li e?",
369 "Otgovorete s DA ili NE, vsichko drugo shte bude scheteno za NE",
370 2,
371 false,
372 question5
373 )
374 end
375
376 local function question3(previousAnswer)
377 -- Car color
378 carBrand = previousAnswer
379
380 PromptQuestion(
381 "Registratsiya - III",
382 "Tsvyat na avtomobila",
383 "Izpishete tsveta na avtomobila (napr. CHEREN iliORANZHEV)",
384 15,
385 false,
386 question4
387 )
388 end
389
390 local function question2(previousAnswer)
391 -- Car brand
392 playerName = previousAnswer
393
394 PromptQuestion(
395 "Registratsiya - II",
396 "Model na avtomobila",
397 "Izpishete modela na kolata, kakto go vizhdate v inventara",
398 25,
399 true,
400 question3
401 )
402 end
403
404 local function question1()
405 -- Player name
406 PromptQuestion(
407 "Registratsiya - I",
408 "Ime na sobstvenik",
409 "Molya izpishete vasheto ime",
410 16,
411 false,
412 question2
413 )
414 end
415
416 term.setBackgroundColor(colors.white)
417 term.clear()
418
419 DrawHeader("Registratsiya", colors.blue)
420
421 term.setCursorPos(8,6)
422 term.setBackgroundColor(colors.white)
423 term.setTextColor(colors.black)
424 term.write("Shte budete pitani nyakolko vaprosa za")
425 term.setCursorPos(8,7)
426 term.write("avtomobila. Molya, otgovorete na vseki")
427 term.setCursorPos(16,8)
428 term.write("s tochna informatsiya.")
429
430 DrawButton({
431 PosX = 21,
432 PosY = 10,
433 BackgroundColor = colors.black,
434 TextColor = colors.white,
435 Text = "Napred >>>",
436 Compact = false,
437 Callback = question1
438 })
439
440 DrawButton({
441 PosX = 3,
442 PosY = 15,
443 BackgroundColor = colors.gray,
444 TextColor = colors.white,
445 Text = "<<< Obratno v nachaloto",
446 Compact = false,
447 Callback = ShowMainScreen
448 })
449end
450
451function PromptQuestion(headerText,
452 questionText,
453 questionTip,
454 maxLength,
455 allowSpaces,
456 nextQuestionFunc)
457 ClearCallbacks()
458 term.setBackgroundColor(colors.white)
459 term.clear()
460
461 DrawHeader(headerText, colors.purple)
462
463 term.setCursorPos(3,6)
464 term.setBackgroundColor(colors.white)
465 term.setTextColor(colors.black)
466 term.write(questionText)
467
468 local pushY = 0
469
470 term.setCursorPos(3,7)
471 term.setTextColor(colors.gray)
472
473 term.write(string.sub(questionTip, 1, 48))
474
475 if string.len(questionTip) > 48 then
476 term.setCursorPos(3,8)
477 term.write(string.sub(questionTip, 49))
478 pushY = 1
479 end
480
481 term.setCursorPos(3,9)
482 DrawButton({
483 PosX = 3,
484 PosY = 9 + pushY,
485 BackgroundColor = colors.lightGray,
486 TextColor = colors.black,
487 Text = string.rep(" ", 32),
488 Compact = false,
489 Callback = nil
490 })
491
492 TextField = {
493 Active = true,
494 PosX = 8,
495 PosY = 10 + pushY,
496 Text = "",
497 MaxLength = maxLength,
498 AllowSpaces = allowSpaces
499 }
500
501 DrawButton({
502 PosX = 39,
503 PosY = 9 + pushY,
504 BackgroundColor = colors.black,
505 TextColor = colors.white,
506 Text = "Produlzhi",
507 Compact = true,
508 Callback = function()
509 if TextField.Text == "" then
510 return
511 end
512
513 nextQuestionFunc(TextField.Text)
514 end
515 })
516
517 DrawButton({
518 PosX = 3,
519 PosY = 15,
520 BackgroundColor = colors.gray,
521 TextColor = colors.white,
522 Text = "<<< Otkaz i obratno v nachaloto",
523 Compact = false,
524 Callback = ShowMainScreen
525 })
526
527 term.setBackgroundColor(colors.lightGray)
528 term.setTextColor(colors.black)
529 term.setCursorPos(4, 10 + pushY)
530 term.setCursorBlink(true)
531end
532
533ShowMainScreen()
534
535-- input handling
536local shiftHeld = false
537
538while true do
539 local data = {os.pullEvent()}
540 local event = data[1]
541
542 -- (shift)
543 if event == "key" and ((data[2] == 340) or (data[2] == 344)) then
544 shiftHeld = true
545 elseif event == "key_up" and ((data[2] == 340) or (data[2] == 344)) then
546 shiftHeld = false
547 end
548
549 if event == "mouse_click" then
550 local button = data[2]
551 local x = data[3]
552 local y = data[4]
553 if button == 1 then
554 for _, callbackData in pairs(ButtonCallbacks) do
555 if x >= callbackData.StartX
556 and x <= callbackData.EndX
557 and y >= callbackData.StartY
558 and y <= callbackData.EndY
559 and callbackData.Callback then
560 callbackData.Callback()
561 end
562 end
563 end
564 elseif TextField.Active and event == "key" then
565 local key = data[2]
566
567 local function addLetter(letter)
568 local textLen = string.len(TextField.Text)
569 if textLen < TextField.MaxLength then
570 TextField.Text = TextField.Text .. letter
571 term.write(letter)
572 end
573 end
574
575 if key >= 65 and key <= 90 then
576 local keyText = keys.getName(key)
577 keyText = string.upper(keyText)
578
579 addLetter(keyText)
580 elseif (key == 32) and TextField.AllowSpaces then
581 addLetter(" ")
582 elseif (key == 45) and TextField.AllowSpaces then
583 addLetter("-")
584 elseif (key >= 48 and key <= 57) or (key >= 320 and key <= 329) then
585 local keyText
586
587 -- I AM SORRY.
588 -- The keys API sucks.
589 if key == 48 or key == 320 then
590 keyText = "0"
591 elseif key == 49 or key == 321 then
592 keyText = "1"
593 elseif key == 50 or key == 322 then
594 keyText = "2"
595 elseif key == 51 or key == 323 then
596 keyText = "3"
597 elseif key == 52 or key == 324 then
598 keyText = "4"
599 elseif key == 53 or key == 325 then
600 keyText = "5"
601 elseif key == 54 or key == 326 then
602 keyText = "6"
603 elseif key == 55 or key == 327 then
604 keyText = "7"
605 elseif key == 56 or key == 328 then
606 keyText = "8"
607 elseif key == 57 or key == 329 then
608 keyText = "9"
609 end
610
611 addLetter(keyText)
612 elseif key == 259 then
613 local textLen = string.len(TextField.Text)
614 if textLen > 0 then
615 TextField.Text = string.sub(TextField.Text, 1, textLen - 1)
616 local cX, cY = term.getCursorPos()
617 cX = cX - 1
618 term.setCursorPos(cX, cY)
619 term.write(" ")
620 term.setCursorPos(cX, cY)
621 end
622 elseif (key == 45) and shiftHeld then
623 addLetter("_")
624 end
625 end
626end