Advertisement
Bolodefchoco_LUAXML

[Script / Funcorp] #signal

Nov 29th, 2018
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.50 KB | None | 0 0
  1. local module = {
  2.     owner = "Bolodefchoco#0000",
  3.     map_file = 20
  4. }
  5.  
  6. -- Translations
  7. local translations = {
  8.     en = {
  9.         -- Init
  10.         welcome = "Welcome to <PS>#Signal<S>! Follow the traffic lights and join the hole! Use !help to read more informations and send maps in https://atelier801.com/topic?f=6&t=859064.\n\tReport any issue to Bolodefchoco#0000",
  11.        
  12.         -- Info
  13.         info = {
  14.             [1] = {"Run", "Run as fast as you can. Do not stop!"},
  15.             [2] = {"Attention", "Pay attention! You can die in the next few seconds!"},
  16.             [3] = {"Stop", "Stop or die!"},
  17.         },
  18.        
  19.         -- Simple words
  20.         close = "Close",
  21.     },
  22.     br = {
  23.         welcome = "Bem-vindo ao <PS>#Signal<S>! Siga o semáforo e entre na toca!  Use !help para ler mais informações e envie mapas em https://atelier801.com/topic?f=6&t=859064.\n\tReporte qualquer problema para Bolodefchoco#0000",
  24.  
  25.         info = {
  26.             [1] = {"Corra", "Corra o mais rápido que puder. Não pare!"},
  27.             [2] = {"Atenção", "Preste atenção! Você poderá morrer a qualquer momento!"},
  28.             [3] = {"Pare", "Pare ou morra!"},
  29.         },
  30.  
  31.         close = "Fechar",
  32.     },
  33.     pl = {
  34.         welcome = "Witaj w <PS>#Signal<S>! Patrz na tabliczke i wejdź do norki! Użyj komendy !help, aby przeczytać więcej informacji and send maps in https://atelier801.com/topic?f=6&t=859064.\n\tZgłoś wszystkie błędy jakie znajdziesz do Bolodefchoco#0000",
  35.        
  36.         info = {
  37.             [1] = {"Biegnij", "Biegnij jak najszybciej do norki. Nie zatrzymuj się!"},
  38.             [2] = {"Uważaj", "Uważaj! Możesz zginąć za kilka sekund!"},
  39.             [3] = {"Stój", "Stój albo zgiń!"},
  40.         },
  41.        
  42.         close = "Zamknij",
  43.     },
  44.     hu = {
  45.         welcome = "Üdv a <PS>#Signal<S> modulban! Kövesd a jelzőlámpákat, és érj be a lyukba! Használd a !help parancsot, hogy több információt tudj meg, és küldj be pályákat az https://atelier801.com/topic?f=6&t=859064 oldalon.\n\tA hibákat Bolodefchoco#0000 játékosnak jelentheted.",
  46.        
  47.         info = {
  48.             [1] = {"Futás", "Fuss olyan gyorsan, ahogyan csak tudsz. Ne állj meg!"},
  49.             [2] = {"Vigyázat", "Figyelj oda! Meghalhatsz pár másodpercen belül!"},
  50.             [3] = {"Állj", "Állj meg vagy meghalsz!"},
  51.         },
  52.        
  53.         close = "Bezár",
  54.     },
  55. }
  56. local translation = translations[tfm.get.room.community] or translations.en
  57.  
  58. --[[ Data ]]--
  59. local info = {}
  60. local mapEvaluators = {
  61.     ["Bolodefchoco#0000"] = true,
  62.     ["Grapeup#0000"] = true
  63. }
  64. local review = false
  65.  
  66. --[[ Maps ]]--
  67. local maps = { "#17" }
  68. local mapHashes = { }
  69. local mapsToAdd = { }
  70.  
  71. local loading_maps = false
  72. local reloader
  73. reloader = system.newTimer(function()
  74.     if not loading_maps then
  75.         eventFileLoaded(20, "7086363@7355559@7352151@7473347@4999966@6635132@7073744@7100080@7512026@7274358@7273852@294522@#7@7352091@7378592@7101000@7352444@7355817@7361951@7329946@7211820@7418998@430219@7355667@6695858@1234152@7400017@7444443@2008918@4234152@7361945@7285919@7271345@3296011@7355616@7352089@1385156@7426268@7521251@7117463@7351961@7352794@6549484@1147672@7352090@7227540@6528318@#17@5939773@7510448@7434474@7528581@7434476@1803787@2975244@4891147")
  76.     end
  77. end, 1000, true)
  78.  
  79. --[[ API ]]--
  80. math.clamp = function(value, min, max)
  81.     return value < min and min or value > max and max or value
  82. end
  83.  
  84. string.split = function(value, pattern, f)
  85.     local out = {}
  86.     for v in string.gmatch(value, pattern) do
  87.         out[#out + 1] = (not f and v or f(v))
  88.     end
  89.     return out
  90. end
  91. system.isPlayer = function(n)
  92.     --[[
  93.         The player must not be a souris;
  94.         The player must have played Transformice for at least 5 days
  95.     ]]
  96.     return not not (string.sub(n, 1, 1) ~= "*" and tfm.get.room.playerList[n] and (os.time() - (tfm.get.room.playerList[n].registrationDate or os.time())) >= 432e6)
  97. end
  98. system.players = function(alivePlayers)
  99.     local alive, total = 0, 0
  100.     if alivePlayers then
  101.         alive = {}
  102.     end
  103.  
  104.     for k, v in next, tfm.get.room.playerList do
  105.         if system.isPlayer(k) then
  106.             total = total + 1
  107.             if not (v.isDead or v.isVampire) then
  108.                 if alivePlayers then
  109.                     alive[#alive + 1] = k
  110.                 else
  111.                     alive = alive + 1
  112.                 end
  113.             end
  114.         end
  115.     end
  116.  
  117.     return alive, total
  118. end
  119.  
  120. table.find = function(list, value, index, f)
  121.     for k, v in next, list do
  122.         local i = (type(v) == "table" and index) and v[index] or v
  123.         if (not f and i or f(i)) == value then
  124.             return true, k
  125.         end
  126.     end
  127.     return false, 0
  128. end
  129. table.random = function(t)
  130.     return t[math.random(#t)]
  131. end
  132. table.shuffle = function(t)
  133.     local len = #t
  134.     for i = len, 1, -1 do
  135.         local rand = math.random(len)
  136.         t[i], t[rand] = t[rand], t[i]
  137.     end
  138.     return t
  139. end
  140.  
  141. ui.banner = function(image, aX, aY, n, time)
  142.     time = time or 5
  143.     aX = aX or 100
  144.     aY = aY or 100
  145.  
  146.     local img = tfm.exec.addImage(image .. ".png", "&0", aX, aY, n)
  147.     system.newTimer(function()
  148.         tfm.exec.removeImage(img)
  149.     end, time * 1000, false)
  150. end
  151.  
  152. local xml = {}
  153. xml.parseParameters = function(currentXml)
  154.     currentXml = string.match(currentXml, "<P (.-)/>") or ""
  155.     local out = {}
  156.     for tag, _, value in string.gmatch(currentXml, "([%-%w]+)=([\"'])(.-)%2") do
  157.         out[tag] = value
  158.     end
  159.     return out, currentXml
  160. end
  161. xml.attribFunc = function(currentXml, funcs)
  162.     local attributes, properties = xml.parseParameters(currentXml)
  163.     for k, v in next, funcs do
  164.         if attributes[v.attribute] then
  165.             v.func(attributes[v.attribute])
  166.         end
  167.     end
  168.     return properties
  169. end
  170.  
  171. --[[ Settings ]]--
  172. -- New Game
  173. local sys = {0, 1}
  174. local discrepancy = 0
  175. local lights = {"15b52f8717d", "15b52f8583a", "15b52f88765"}
  176. local lightId = -1
  177. local lightTime = {{3, 5}, {2, 3}, {7, 13}}
  178. local rounds = 0
  179.  
  180. --[[ System ]]--
  181. -- UpdateLight
  182. local update = function(id)
  183.     tfm.exec.removeImage(lightId)
  184.     lightId = tfm.exec.addImage(lights[sys[2]] .. ".png", "&0", 375, 30)
  185.     local color = ({0x1CB70C, 0xF4D400, 0xEC0000})[sys[2]]
  186.     for k, v in next, info do
  187.         if id == 1 then
  188.             if not v.afk and v.canRev then
  189.                 tfm.exec.respawnPlayer(k)
  190.             end
  191.         end
  192.         tfm.exec.setNameColor(k, color)
  193.     end
  194. end
  195. -- Load new map
  196. local loadMap = function()
  197.     rounds = rounds + 1
  198.     if rounds > #maps then
  199.         maps = table.shuffle(maps)
  200.         rounds = 1
  201.     end
  202.    
  203.     tfm.exec.newGame(maps[rounds])
  204. end
  205. -- Valid map code
  206. local mapCode = function(x)
  207.     if string.sub(x, 1, 1) == "@" then
  208.         x = string.sub(x, 2)
  209.     end
  210.  
  211.     local str = x
  212.     x = tonumber(x)
  213.     return x, not not x and #str > 3
  214. end
  215.  
  216. --[[ UI ]]--
  217. local displayInfo = function(n, id)
  218.     local color = ({"<VP>", "<J>", "<R>"})[id]
  219.     ui.addTextArea(1, "<p align='center'><font size='25'>" .. color .. translation.info[id][1] .. "\n</font></p><p align='left'><font size='14'>" .. translation.info[id][2], n, 250, 110, 300, 181, 0x324650, 0x27343A, 1, true)
  220.     ui.addTextArea(2, "<font size='2'>\n</font><p align='center'><font size='16'><a href='event:close'>" .. translation.close, n, 250, 300, 300, 30, 0x27343A, 0x27343A, 1, true)
  221.     ui.addTextArea(3, "<p align='center'><font size='20'><a href='event:info.1'><VP>•</a> <a href='event:info.2'><J>•</a> <a href='event:info.3'><R>•</a>", n, 250, 145, 300, 30, 1, 1, 0, true)
  222.     tfm.exec.removeImage(info[n].imageId)
  223.     info[n].imageId = tfm.exec.addImage(lights[id] .. ".png", "&1", 375, 200, n)
  224. end
  225.  
  226. --[[ Events ]]--
  227. -- NewPlayer
  228. eventNewPlayer = function(n)
  229.     if not info[n] then
  230.         info[n] = {
  231.             isMoving = {false, false, false, false},
  232.             imageId = -1,
  233.             afk = true,
  234.             skipped = false,
  235.             canRev = true,
  236.         }
  237.     end
  238.     for i = 0, 3 do
  239.         system.bindKeyboard(n, i, true, true)
  240.         system.bindKeyboard(n, i, false, true)
  241.     end
  242.     tfm.exec.chatMessage("<S>" .. translation.welcome, n)
  243.     tfm.exec.lowerSyncDelay(n)
  244.     --ui.banner("15d60d9212c", 220, 130, n)
  245. end
  246. -- NewGame
  247. eventNewGame = function()
  248.     ui.setMapName(tfm.get.room.xmlMapInfo.author .. " <BL>- " .. tfm.get.room.currentMap .. "   <G>|   <N>Round : <V>" .. rounds)
  249.    
  250.     for k, v in next, info do
  251.         v.isMoving = {false, false, false, false}
  252.         v.afk = true
  253.         v.skipped = false
  254.         v.canRev = true
  255.     end
  256.    
  257.     sys = {0, 1}
  258.     update(sys[2])
  259.    
  260.     lightTime = {{7, 13}, {2, 3}, {3, 5}}
  261.     xml.attribFunc((tfm.get.room.xmlMapInfo or {}).xml or "", {
  262.         [1] = {
  263.             attribute = "light",
  264.             func = function(value)
  265.                 value = string.lower(value)
  266.                
  267.                 local normalizator = function(v)
  268.                     return math.clamp(tonumber(v), 1, 13)
  269.                 end
  270.                
  271.                 local axis, interval = string.match(value, "^([gyr]);(%d+ ?, ?%d+)")
  272.                 if axis and interval then
  273.                     local _, index = table.find({'g', 'y', 'r'}, axis)
  274.                     interval = string.split(interval, "[^ ?, ?]+", normalizator)
  275.                     table.sort(interval)
  276.                     lightTime[tonumber(index)] = interval
  277.                 else
  278.                     axis = string.split(value, "[^;]+")
  279.                     if #axis > 0 then
  280.                         for i = 1, #axis do
  281.                             interval = string.split(axis[i], "[^ ?, ?]+", normalizator)
  282.                             table.sort(interval)
  283.                             lightTime[i] = interval
  284.                         end
  285.                     end
  286.                 end
  287.             end
  288.         }
  289.     })
  290.  
  291.     if review then
  292.         for k in next, mapEvaluators do
  293.             tfm.exec.chatMessage(string.format("<PS>" .. tfm.get.room.currentMap .. " : <PT>|%s:%s| <J>|%s:%s| <R>|%s:%s|", lightTime[1][1], lightTime[1][2], lightTime[2][1], lightTime[2][2], lightTime[3][1], lightTime[3][2]), k)
  294.         end
  295.     end
  296. end
  297. -- Keyboard
  298. eventKeyboard = function(n, k, d)
  299.     if sys[2] == 3 and d and os.time() > discrepancy then
  300.         tfm.exec.killPlayer(n)
  301.     else
  302.         info[n].isMoving[k + 1] = d
  303.     end
  304.     info[n].afk = false
  305. end
  306. -- Loop
  307. eventLoop = function(currentTime, leftTime)
  308.     if currentTime > 8000 then
  309.         if os.time() > sys[1] then
  310.             sys[2] = (sys[2] % 3) + 1
  311.             sys[1] = os.time() + ({math.random(lightTime[1][1], lightTime[1][2]), math.random(lightTime[2][1], lightTime[2][2]), math.random(lightTime[3][1], lightTime[3][2])})[sys[2]] * 1000
  312.             update(sys[2])
  313.             discrepancy = os.time() + 520
  314.         end
  315.     end
  316.  
  317.     if leftTime > 2000 and system.players() > 0 then
  318.         if sys[2] == 3 and os.time() > discrepancy then
  319.             for k, v in next, info do
  320.                 for i, j in next, v.isMoving do
  321.                     if j then
  322.                         tfm.exec.killPlayer(k)
  323.                         break
  324.                     end
  325.                 end
  326.             end
  327.         end
  328.     else
  329.         if not review then
  330.             loadMap()
  331.         end
  332.     end
  333. end
  334. -- TextAreaCallback
  335. eventTextAreaCallback = function(i, n, c)
  336.     local p = string.split(c, "[^%.]+")
  337.     if p[1] == "info" then
  338.         displayInfo(n, tonumber(p[2]))
  339.     elseif p[1] == "close" then
  340.         tfm.exec.removeImage(info[n].imageId)
  341.         for i = 1, 3 do
  342.             ui.removeTextArea(i, n)
  343.         end
  344.     end
  345. end
  346. -- ChatCommand
  347. eventChatCommand = function(n, c)
  348.     local p = string.split(c, "%S+", string.lower)
  349.  
  350.     if p[1] == "info" or p[1] == "help" or p[1] == "?" then
  351.         eventTextAreaCallback(nil, n, "info." .. sys[2])
  352.     elseif p[1] == "speak" and n == module.owner then
  353.         tfm.exec.chatMessage("<S><B>[#signal] " .. table.concat(p, " ", 2) .. "</B>")
  354.     else
  355.         if mapEvaluators[n] then
  356.             if p[1] == "review" then
  357.                 review = not review
  358.                 tfm.exec.chatMessage("<S>REVIEW : " .. string.upper(tostring(review)))
  359.                 tfm.exec.disableAfkDeath(review)
  360.             elseif p[1] == "ls" then
  361.                 local m = { }
  362.                 for k, v in next, maps do
  363.                     m[k] = (mapsToAdd[v] and "<R>@" or "@") .. v
  364.                 end
  365.  
  366.                 tfm.exec.chatMessage("Total maps: <J>" .. #maps .. " <BL>: " .. table.concat(m, ", "), n)
  367.             elseif p[1] == "data" and n == module.owner then
  368.                 if #maps == 0 then
  369.                     tfm.exec.chatMessage("<R>You can not save an empty queue.", n)
  370.                 else
  371.                     mapsToAdd = { }
  372.  
  373.                     local data = table.concat(maps, '@')
  374.                     system.saveFile(data, module.map_file)
  375.  
  376.                     for name in next, mapEvaluators do
  377.                         tfm.exec.chatMessage("[database] Total maps: <J>" .. #maps .. " <BL>: @" .. table.concat(maps, ", @"), name)
  378.                     end
  379.                 end
  380.             elseif p[2] then
  381.                 if (p[1] == "np" or p[1] == "map") and review then
  382.                     tfm.exec.newGame(p[2])
  383.                 elseif not reloader then
  384.                     local data = table.concat(p, " ", 2)
  385.                     if p[1] == "add" then
  386.                         local entries = string.split(data, "[^, ]+")
  387.  
  388.                         if entries then
  389.                             for map = 1, #entries do
  390.                                 local code, isCode = mapCode(entries[map])
  391.                                 if isCode and not mapHashes[code] then
  392.                                     maps[#maps + 1] = code
  393.                                     mapHashes[code] = true
  394.                                     mapsToAdd[code] = true
  395.                                     tfm.exec.chatMessage("<BL>The map <J>@" .. code .. "</J> is now in the map queue.")
  396.                                 end
  397.                             end
  398.                         end
  399.                     elseif p[1] == "del" then
  400.                         local entries = string.split(data, "[^, ]+")
  401.  
  402.                         if entries then
  403.                             for map = 1, #entries do
  404.                                 local code, isCode = mapCode(entries[map])
  405.                                 if isCode and mapHashes[code] then
  406.                                     for o_map = 1, #maps do
  407.                                         if maps[o_map] == code then
  408.                                             table.remove(maps, o_map)
  409.                                             break
  410.                                         end
  411.                                     end
  412.                                     mapHashes[code] = nil
  413.                                     tfm.exec.chatMessage("<BL>The map <J>@" .. code .. "</J> was removed from the map queue.")
  414.                                 end
  415.                             end
  416.                         end
  417.                     end
  418.                 end
  419.             end
  420.  
  421.             if not string.find(tfm.get.room.name, "^*?#signal%d*$") then
  422.                 if p[1] == "next" then
  423.                     loadMap()
  424.                 elseif p[1] == "again" then
  425.                     tfm.exec.newGame(tfm.get.room.currentMap)
  426.                 end
  427.             end
  428.         end
  429.     end
  430. end
  431. -- PlayerWon
  432. eventPlayerWon = function(n)
  433.     info[n].canRev = review
  434.     tfm.exec.setGameTime(40, false)
  435.    
  436.     if review then
  437.         tfm.exec.respawnPlayer(n)
  438.     end
  439. end
  440. -- FileLoaded
  441. eventFileLoaded = function(id, data)
  442.     system.removeTimer(reloader)
  443.     reloader = nil
  444.  
  445.     local counter = 0
  446.     maps, mapHashes = { }, { }
  447.     string.gsub(data, "[^@]+", function(code)
  448.         counter = counter + 1
  449.  
  450.         code = tonumber(code) or code
  451.         maps[counter] = code
  452.         mapHashes[code] = true
  453.     end)
  454.     maps = table.shuffle(maps)
  455. end
  456.  
  457. for _, f in next, {"AutoShaman", "AutoNewGame", "AutoTimeLeft", "PhysicalConsumables"} do
  458.     tfm.exec["disable"..f]()
  459. end
  460. table.foreach(tfm.get.room.playerList, eventNewPlayer)
  461.  
  462. system.disableChatCommandDisplay(nil, true)
  463.  
  464. maps = table.shuffle(maps)
  465.  
  466. loadMap()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement