Advertisement
Guest User

Untitled

a guest
Feb 17th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.10 KB | None | 0 0
  1. local module = {
  2. owner = "Sky#1999",
  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 = system.loadFile(module.map_file)
  72. local reloader
  73. reloader = system.newTimer(function()
  74. if not loading_maps then
  75. system.loadFile(module.map_file)
  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