· 4 years ago · Aug 21, 2021, 12:50 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 = true
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 local y = 8
237
238 if not success then
239 term.write(data)
240 elseif not data then
241 DrawHeader("Imashe greshka", colors.red)
242 term.setCursorPos(3,6)
243 term.setBackgroundColor(colors.white)
244 term.setTextColor(colors.black)
245 term.write("Nyama namerena takava registratsiya")
246 else
247 term.write("Rezultat ot spravkata:")
248
249 for key, value in pairs(data) do
250 -- Display traits meaningfully
251 if key == "Traits" then
252 if value == 0 then
253 value = "Chasten avtomobil"
254 elseif value == 1 then
255 value = "Avtomobil na invalid"
256 elseif value == 2 then
257 value = "Firmen avtomobil"
258 elseif value == 3 then
259 value = "Lineika"
260 elseif value == 4 then
261 value = "Taksi"
262 elseif value == 5 then
263 value = "Avtomobil na ATI"
264 else
265 value = "[Error]"
266 end
267 end
268
269 -- Translate
270 if key == "Number" then
271 key = "Nomer"
272 elseif key == "Traits" then
273 key = "Belezhki"
274 elseif key == "Registration" then
275 key = "Registratsiya"
276 elseif key == "Owner" then
277 key = "Sobstvenik"
278 elseif key == "Block" then
279 key = "Seriya"
280 end
281
282 term.setTextColor(colors.gray)
283 term.setCursorPos(3, y)
284 term.write(key)
285 term.setCursorPos(20, y)
286 term.setTextColor(colors.black)
287 term.write(value)
288
289 y = y + 1
290 end
291 end
292
293 y = y + 1
294 DrawButton({
295 PosX = 3,
296 PosY = y,
297 BackgroundColor = colors.black,
298 TextColor = colors.white,
299 Text = "<<< Obratno v nachaloto",
300 Compact = false,
301 Callback = ShowMainScreen
302 })
303end
304
305function ShowRegistrationScreen()
306 ClearCallbacks()
307
308 local playerName = ""
309 local carBrand = ""
310 local color = ""
311 local ambulance = false
312
313 local function question5(previousAnswer)
314 ambulance = (previousAnswer == "DA")
315
316 term.setBackgroundColor(colors.white)
317 term.clear()
318
319 DrawHeader("Molya izchakaite...", colors.black)
320
321 term.setCursorPos(3,6)
322 term.setBackgroundColor(colors.white)
323 term.setTextColor(colors.black)
324 term.write("Sistemata vpisva vashata registratsiya...")
325
326 sleep(5)
327 local number = TiaAPI.RegisterVehicle(
328 playerName,
329 carBrand,
330 color,
331 PROVINCE_ID,
332 ambulance and 3 or 0
333 )
334 TiaAPI.PrintRegistration(number)
335
336 -- success/fail screen
337 term.setCursorBlink(false)
338
339 DrawHeader("Agenstiya Transport i Infrastruktura", colors.blue)
340
341 term.setBackgroundColor(colors.white)
342 term.setTextColor(colors.black)
343 term.setCursorPos(3,6)
344 term.clearLine()
345 term.setCursorPos(3,6)
346 term.write("Registraciyata vi be USPESHNA")
347 term.setCursorPos(3,8)
348 term.write("Molya otvorete PRINTERA pod tozi kompyutar, za")
349 term.setCursorPos(3,9)
350 term.write("vidite nomera na registratsiyata.")
351 term.setCursorPos(3,11)
352 term.setTextColor(colors.red)
353 term.write("MOLYA NE OSTAVYAITE LISTA OBRATNO V PRINTERA!")
354
355 DrawButton({
356 PosX = 3,
357 PosY = 13,
358 BackgroundColor = colors.blue,
359 TextColor = colors.white,
360 Text = "<<< Obratno v nachaloto",
361 Compact = false,
362 Callback = ShowMainScreen
363 })
364 end
365
366 local function question4(previousAnswer)
367 -- Traits
368 color = previousAnswer
369
370 PromptQuestion(
371 "Registratsiya - IV",
372 "Tova lineika li e?",
373 "Otgovorete s DA ili NE, vsichko drugo shte bude scheteno za NE",
374 2,
375 false,
376 question5
377 )
378 end
379
380 local function question3(previousAnswer)
381 -- Car color
382 carBrand = previousAnswer
383
384 PromptQuestion(
385 "Registratsiya - III",
386 "Tsvyat na avtomobila",
387 "Izpishete tsveta na avtomobila (napr. CHEREN iliORANZHEV)",
388 15,
389 false,
390 question4
391 )
392 end
393
394 local function question2(previousAnswer)
395 -- Car brand
396 playerName = previousAnswer
397
398 PromptQuestion(
399 "Registratsiya - II",
400 "Model na avtomobila",
401 "Izpishete modela na kolata, kakto go vizhdate v inventara",
402 25,
403 true,
404 question3
405 )
406 end
407
408 local function question1()
409 -- Player name
410 PromptQuestion(
411 "Registratsiya - I",
412 "Ime na sobstvenik",
413 "Molya izpishete vasheto ime",
414 16,
415 false,
416 question2
417 )
418 end
419
420 term.setBackgroundColor(colors.white)
421 term.clear()
422
423 DrawHeader("Registratsiya", colors.blue)
424
425 term.setCursorPos(8,6)
426 term.setBackgroundColor(colors.white)
427 term.setTextColor(colors.black)
428 term.write("Shte budete pitani nyakolko vaprosa za")
429 term.setCursorPos(8,7)
430 term.write("avtomobila. Molya, otgovorete na vseki")
431 term.setCursorPos(16,8)
432 term.write("s tochna informatsiya.")
433
434 DrawButton({
435 PosX = 21,
436 PosY = 10,
437 BackgroundColor = colors.black,
438 TextColor = colors.white,
439 Text = "Napred >>>",
440 Compact = false,
441 Callback = question1
442 })
443
444 DrawButton({
445 PosX = 3,
446 PosY = 15,
447 BackgroundColor = colors.gray,
448 TextColor = colors.white,
449 Text = "<<< Obratno v nachaloto",
450 Compact = false,
451 Callback = ShowMainScreen
452 })
453end
454
455function PromptQuestion(headerText,
456 questionText,
457 questionTip,
458 maxLength,
459 allowSpaces,
460 nextQuestionFunc)
461 ClearCallbacks()
462 term.setBackgroundColor(colors.white)
463 term.clear()
464
465 DrawHeader(headerText, colors.purple)
466
467 term.setCursorPos(3,6)
468 term.setBackgroundColor(colors.white)
469 term.setTextColor(colors.black)
470 term.write(questionText)
471
472 local pushY = 0
473
474 term.setCursorPos(3,7)
475 term.setTextColor(colors.gray)
476
477 term.write(string.sub(questionTip, 1, 48))
478
479 if string.len(questionTip) > 48 then
480 term.setCursorPos(3,8)
481 term.write(string.sub(questionTip, 49))
482 pushY = 1
483 end
484
485 term.setCursorPos(3,9)
486 DrawButton({
487 PosX = 3,
488 PosY = 9 + pushY,
489 BackgroundColor = colors.lightGray,
490 TextColor = colors.black,
491 Text = string.rep(" ", 32),
492 Compact = false,
493 Callback = nil
494 })
495
496 TextField = {
497 Active = true,
498 PosX = 8,
499 PosY = 10 + pushY,
500 Text = "",
501 MaxLength = maxLength,
502 AllowSpaces = allowSpaces
503 }
504
505 DrawButton({
506 PosX = 39,
507 PosY = 9 + pushY,
508 BackgroundColor = colors.black,
509 TextColor = colors.white,
510 Text = "Produlzhi",
511 Compact = true,
512 Callback = function()
513 if TextField.Text == "" then
514 return
515 end
516
517 nextQuestionFunc(TextField.Text)
518 end
519 })
520
521 DrawButton({
522 PosX = 3,
523 PosY = 15,
524 BackgroundColor = colors.gray,
525 TextColor = colors.white,
526 Text = "<<< Otkaz i obratno v nachaloto",
527 Compact = false,
528 Callback = ShowMainScreen
529 })
530
531 term.setBackgroundColor(colors.lightGray)
532 term.setTextColor(colors.black)
533 term.setCursorPos(4, 10 + pushY)
534 term.setCursorBlink(true)
535end
536
537ShowMainScreen()
538
539-- input handling
540local shiftHeld = false
541
542while true do
543 local data = {os.pullEvent()}
544 local event = data[1]
545
546 -- (shift)
547 if event == "key" and ((data[2] == 340) or (data[2] == 344)) then
548 shiftHeld = true
549 elseif event == "key_up" and ((data[2] == 340) or (data[2] == 344)) then
550 shiftHeld = false
551 end
552
553 if event == "mouse_click" then
554 local button = data[2]
555 local x = data[3]
556 local y = data[4]
557 if button == 1 then
558 for _, callbackData in pairs(ButtonCallbacks) do
559 if x >= callbackData.StartX
560 and x <= callbackData.EndX
561 and y >= callbackData.StartY
562 and y <= callbackData.EndY
563 and callbackData.Callback then
564 callbackData.Callback()
565 end
566 end
567 end
568 elseif TextField.Active and event == "key" then
569 local key = data[2]
570
571 local function addLetter(letter)
572 local textLen = string.len(TextField.Text)
573 if textLen < TextField.MaxLength then
574 TextField.Text = TextField.Text .. letter
575 term.write(letter)
576 end
577 end
578
579 if key >= 65 and key <= 90 then
580 local keyText = keys.getName(key)
581 keyText = string.upper(keyText)
582
583 addLetter(keyText)
584 elseif (key == 32) and TextField.AllowSpaces then
585 addLetter(" ")
586 elseif (key == 45) and TextField.AllowSpaces then
587 addLetter("-")
588 elseif (key >= 48 and key <= 57) or (key >= 320 and key <= 329) then
589 local keyText
590
591 -- I AM SORRY.
592 -- The keys API sucks.
593 if key == 48 or key == 320 then
594 keyText = "0"
595 elseif key == 49 or key == 321 then
596 keyText = "1"
597 elseif key == 50 or key == 322 then
598 keyText = "2"
599 elseif key == 51 or key == 323 then
600 keyText = "3"
601 elseif key == 52 or key == 324 then
602 keyText = "4"
603 elseif key == 53 or key == 325 then
604 keyText = "5"
605 elseif key == 54 or key == 326 then
606 keyText = "6"
607 elseif key == 55 or key == 327 then
608 keyText = "7"
609 elseif key == 56 or key == 328 then
610 keyText = "8"
611 elseif key == 57 or key == 329 then
612 keyText = "9"
613 end
614
615 addLetter(keyText)
616 elseif key == 259 then
617 local textLen = string.len(TextField.Text)
618 if textLen > 0 then
619 TextField.Text = string.sub(TextField.Text, 1, textLen - 1)
620 local cX, cY = term.getCursorPos()
621 cX = cX - 1
622 term.setCursorPos(cX, cY)
623 term.write(" ")
624 term.setCursorPos(cX, cY)
625 end
626 elseif (key == 45) and shiftHeld then
627 addLetter("_")
628 end
629 end
630end