Mousetat

Murderer by Brenower

Jan 7th, 2017
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.08 KB | None | 0 0
  1. --[[
  2. #Murder
  3. Created by Brenower
  4.  
  5. To-do list:
  6.  
  7. Murder:
  8. - A cada 8 jogadores é +1 murer
  9. - Faca com cooldown de x segundos
  10. - Flashbang com cooldown de x segundos
  11. - Deixar o rato assassinado como um cadaver
  12.  
  13. Inocente:
  14. - A cada 2 murders selecionar um inocente como arma
  15. - Implantar os objetos brilhantes e verde no mapa
  16. - Quando colocar 5 objetos recebe ...
  17.  
  18. Mapa:
  19. - "Modo Noite": a cada 30 segundos os jogadores podem ter uma área de visão melhor
  20. - Quando algum time ganhar aparecer uma textarea tipo a do murder (gmod)
  21.  
  22. Pontuações:
  23. - Ganhar o round +10 pontos
  24. - Matar um inocente +1 pontos
  25. - Matar um murder +5 pontos
  26. - Ser o melhor jogador quando acabarem os rounds +30 pontos
  27.  
  28. Perfil:
  29. Geral:
  30. - Rounds jogados
  31. - Vitórias / Derrotas
  32. - Pontos
  33.  
  34. Murder:
  35. - Rounds como murder
  36. - Vitórias / Derrotas
  37. - Inocentes assassinados
  38. - Perk atual
  39. Inocente:
  40. - Rounds jogados
  41. - Vitórias / Derrotas
  42. - Murders assassinados
  43. - Perk atual
  44.  
  45. Loja de habilidades:
  46. - A cada 150 pontos libera uma perk de inocente
  47. - A cada 300 pontos libera uma perk de murder
  48. Inocente:
  49. - Perk 1: Você começa com uma área de visão maior (nivel 2)
  50. - Perk 2: Você pode colocar um clone falso no mapa, se um murder tentar matar-ló deixara seu rastro por 10 segundos
  51. - Perk 3: Você já começa com um objeto coletado
  52. - Perk 4: O tempo que você é afetado por flashbangs é diminuido em 50%
  53. Murder:
  54. - Perk 1: Verifica se tem jogadores a uma área quadrada de ypx
  55. - Perk 2: Os jogadores deixam pegadas de onde passam
  56. - Perk 3: Suas flashbangs duram +1 segundo
  57. - Perk 4: Você pode coletar objetos e quando chega em 5 pode trocar o seu corpo pelo de um cadaver
  58.  
  59. Lojas de death note:
  60. - A cada 50 pontos uma death note é liberada
  61. - Death note é mostrada ao jogador quando ele morre
  62.  
  63. ]]
  64.  
  65. -- class
  66.  
  67. local dataHandler = {}
  68. dataHandler.__index = dataHandler
  69.  
  70. function dataHandler.construct(moduleID, dataModel)
  71. local self = setmetatable({}, dataHandler)
  72. self.model = dataModel
  73. self.moduleID = moduleID
  74. self.moduleData = {}
  75. self.recordedPlayers = {}
  76. self.higherIndex = 0
  77. for key, valueTable in pairs(self.model) do
  78. if valueTable.index > self.higherIndex then
  79. self.higherIndex = valueTable.index
  80. end
  81. end
  82. return self
  83. end
  84.  
  85. function dataHandler:insert(player, key, value)
  86. local data = self.recordedPlayers[player]
  87. if data then
  88. data = data[key]
  89. if data and type(data) == "table" then
  90. table.insert(data, value)
  91. end
  92. end
  93. end
  94.  
  95. function dataHandler:remove(player, key, value)
  96. local data = self.recordedPlayers[player]
  97. if data then
  98. data = data[key]
  99. if data and type(data) == "table" then
  100. for i,v in pairs(data) do
  101. if value == v then
  102. table.remove(data, i)
  103. break;
  104. end
  105. end
  106. end
  107. end
  108. end
  109.  
  110. function dataHandler:recordPlayer(player, streamData)
  111. local moduleData = string.split(streamData, "?")
  112.  
  113. local j
  114. for i = 1, #moduleData do
  115. if moduleData[i]:find(self.moduleID) then
  116. j = i
  117. break
  118. end
  119. end
  120.  
  121. local streamData = j and string.split(moduleData[j]:gsub(self.moduleID..'=', ''), ",") or {}
  122.  
  123. if j then table.remove(moduleData, j) end
  124.  
  125. self.moduleData[player] = table.concat(moduleData, '?')
  126.  
  127. self.recordedPlayers[player] = {}
  128. for key, valueTable in pairs(self.model) do
  129. if valueTable.index and valueTable.type then
  130. local value = streamData[valueTable.index] or valueTable.default or "null"
  131. streamData[valueTable.index] = "{"..tostring(key).."}"
  132. if valueTable.type == "boolean" then
  133. self.recordedPlayers[player][key] = value == 1
  134. elseif valueTable.type == "number" then
  135. self.recordedPlayers[player][key] = tonumber(value) or 0
  136. elseif valueTable.type == "string" then
  137. self.recordedPlayers[player][key] = value or ""
  138. elseif valueTable.type == "table" then
  139. self.recordedPlayers[player][key] = string.split(value, "#") or table.copy(valueTable.default) or string.split(valueTable.default, "#")
  140. elseif valueTable.type == "ctable" then
  141. if type(value) == 'string' then
  142. local values = string.split(value, "#")
  143. self.recordedPlayers[player][key] = {}
  144. for _, v in pairs(values) do
  145. local data = string.split(v, "&")
  146. if data[1] and data[2] then
  147. self.recordedPlayers[player][key][data[1]] = data[2] or "null"
  148. end
  149. end
  150. elseif type(value) == 'table' then
  151. self.recordedPlayers[player][key] = table.copy(valueTable.default)
  152. end
  153. else
  154. return false
  155. end
  156. else
  157. return false
  158. end
  159. end
  160. self.recordedPlayers[player].stringData = self:normalizeData(streamData)
  161. return true
  162. end
  163.  
  164. function dataHandler:query(player, key)
  165. local data = self.recordedPlayers[player]
  166. data = data and data[key] or false
  167. return data, type(data)
  168. end
  169.  
  170. function dataHandler:queryAll(key)
  171. local queryData = {}
  172. for player in pairs(self.recordedPlayers) do
  173. table.insert(queryData, {player, key or false, type(key)})
  174. end
  175. return queryData
  176. end
  177.  
  178. function dataHandler:set(player, key, value)
  179. local data = self.recordedPlayers[player]
  180. if data then
  181. data = data[key]
  182. if data then
  183. if type(data) == type(value) then
  184. self.recordedPlayers[player][key] = value
  185. return true, self.recordedPlayers[player][key]
  186. else
  187. return false
  188. end
  189. else
  190. return false
  191. end
  192. else
  193. return false
  194. end
  195. return false
  196. end
  197.  
  198. function dataHandler:setAll(key, value)
  199. for player, streamData in pairs(self.recordedPlayers) do
  200. local success = self:set(player, key, value)
  201. if not success then
  202. return false, player
  203. end
  204. end
  205. return true
  206. end
  207.  
  208. function dataHandler:normalizeData(data)
  209. for i = 1, self.higherIndex do
  210. data[i] = data[i] or "0"
  211. end
  212. return table.concat(data, ",")
  213. end
  214.  
  215. function dataHandler:retrievePlayer(player)
  216. local data = self.recordedPlayers[player].stringData
  217. data = string.gsub(data, "\{(.-)\}", function(key)
  218. local value = self.recordedPlayers[player][key]
  219. local valueType = self.model[key].type or ""
  220. if valueType == "boolean" then
  221. value = tostring(value and 1 or 0)
  222. elseif valueType == "table" then
  223. value = table.concat(value, "#") or "#"
  224. elseif valueType == "ctable" then
  225. local stringValue = {}
  226. if type(value) == "table" then
  227. for k, v in pairs(value) do
  228. if k and v then
  229. table.insert(stringValue, tostring(k).."&"..tostring(v))
  230. end
  231. end
  232. stringValue = table.concat(stringValue, "#")
  233. value = stringValue
  234. else
  235. value = "#"
  236. end
  237. else
  238. value = tostring(value)
  239. end
  240. return value
  241. end)
  242. return self.moduleID..'='..data..(self.moduleData[player] ~= '' and '?'..self.moduleData[player] or '')
  243. end
  244.  
  245. function string.split(s, pattern, n)
  246. local st = {}
  247. for sb in string.gmatch(s, "[^"..pattern.."]+") do
  248. if not n or n > -1 then
  249. table.insert(st,sb)
  250. else
  251. st[#st] = st[#st]..pattern..sb
  252. end
  253. n = n and n-1 or false
  254. end
  255. return st
  256. end
  257.  
  258. function table.copy(t)
  259. if type(t) == 'table' then
  260. local nt = {}
  261. for k, v in pairs(t) do
  262. nt[k] = v
  263. end
  264. return nt
  265. else
  266. return false
  267. end
  268. end
  269.  
  270. local timerList = {}
  271. function addTimer(callback, ms, loops, label, ...)
  272. local id = #timerList+1
  273. timerList[id] = {
  274. callback = callback,
  275. label = label,
  276. arguments = {...},
  277. time = ms,
  278. currentTime = 0,
  279. currentLoop = 0,
  280. loops = loops or 1,
  281. isComplete = false
  282. }
  283. return id
  284. end
  285.  
  286. function removeTimer(id)
  287. if timerList[id] then
  288. timerList[id] = 0
  289. return true
  290. end
  291. return false
  292. end
  293.  
  294. function clearTimers() timerList = {} end
  295.  
  296. -- arrays
  297. local translations = {
  298. ["EN"] = {
  299. ["help-1"]= "<p align=\"center\"><b><font size=\"18\" face=\"Arial\"><VP>#murder</VP></font></b></p>Welcome to <j><b>#murder</b>!</j> Created by <j><b>Brenower</b></j>.<br><br><BV><b>• Innocent:</b></BV><br>As innocent your objective is get way from <r><b>murder</b></r> and find <vp><b>green</b></vp>,</vp> when you got <j><b>5 objects</b></j> you get <j><b>a gun</b></j>, but be carefful the <r><b>murder</b></r> will try to stop you from collecting.<br><br><bv><b>• Innocent with a gun:</b></bv><br>For every <j><b>3</b></j><r> <b>murders</b></r> a <bv><b>innocent</b></bv> is select to have a gun and kill the <b><r>murders</b> by <ch><b>clicking on the player.</b></ch><br><br><r><b>• Murder:</b></r><br>The <r><b>murder</b></r> have a <r><b>knife</b>,</r> it takes <j><b>1 second</b></j> to use it (in that tim the knife is visible to everyone) and you can kill a player pressing <ch><b>space</b></ch> next to your target.",
  300. ["teamWin"] = "<p align='center'><font size=\"18\"><VP><b>The team of %s win the round!</b></VP></font><br><br><font size=\"12\"><b><J>Best scores:</J></b></font><br>",
  301. ["profile"] = "<p align=\"center\"><J><font size=\"18\"><b>%s</b></font></J></p><br><font face=\"Verdana\"><ch><b>• General stats:</b></ch><br>Rounds played: <vp><b>%i</b></vp><br>Wins: <vp><b>%i</b></vp><br>Points:<vp><b>%i</b></vp><br><br><bv><b>• As innocent:</b></bv><br>Murders slaughtered: <vp><b>%i</b></vp><br><br><r><b>• As murder:</b></r><br>Innocents slaughtered: <vp><b>%i</b></vp><br><br><ch><b>• Medals:</b></ch><br><v><b>[???]</b></v>",
  302. ["welcome"] = "<VP><b>Send your maps:</b></VP>\n<v>http://atelier801.com/topic?f=745381&t=892082</v>\n<ROSE>Welcome to <r><b>#murder</b></r>! If you need help say <j><b>!help</b>",
  303. ["prepKnife"] = "You can now use your <r><b>knife</b></r>! Press <ch><b>space</b></ch> next of a player.",
  304. ["colKnife"] = "Your <r><b>knife</b></r> is on countdown of <j><b>%i second(s).</b></j>",
  305. ["mrK"] = "You killed <v><b>%s</b> (+1)</v>, you need to wait <j><b>11 seconds.</b></j> to use your knife again.",
  306. ["prepGun"] = "You can now use your <j><b>gun</b></j>!<ch><b>Click on your target</b></ch> to kill him.",
  307. ["colGun"] = "Your <j><b>gun</b></j> is on countdown of <j><b>%i seconds(s).</b></j>",
  308. ["obj"] = "You collected <vp><b>one object</b></vp><v> (+1)</v>, total: <v><b>%i / 5</b></v>",
  309. ["obj-5"] = "Now you have a <j><b>gun!</b></j> Press <ch><b>space</b></ch> to wield it.",
  310. ["flb"] = "Your <n2><b>flashbang</b></n2> is on countdown of <j><b>%i second(s).</b></j>",
  311. --["useGun"] = "Your knife <j><b>arma</b></j> entrou em cooldown de <j><b>1 segundo</b></j>",
  312. ["suicide"] = "The <ch><b>%s</b></ch> commited suicide for killing the <bv><b>innocent</b></bv> <ch><b>%s</b></ch>!",
  313. ["inK"] = "The <r><b>murder</b></r> <ch><b>%s</b></ch> was killed by <ch><b>%s</b></ch><v> (+5)</v>!",
  314. ["inK-2"] = "It was your last bullet! Go and collect other weapon",
  315. ["map"] = "<J>%s</J> <BL>| <N>Murders alive: </N><R>%i <BL>| <N>Innocents alive:</BV> <V>%i",
  316. ["team1Win"] = "The <bv><b>innocents</b></bv> won the round!",
  317. ["team2Win"] = "The <r><b>murders</b></r> won the round!",
  318. ["draw"] = "The round ended in a draw!",
  319. ["newGameI"] = "You're a <bv><b>innocent</b></bv>, collect <vp><b>green</b></vp> objects by map pressing <ch><b>space</b></ch>, try to get away from murder.",
  320. ["newGameIG"] = "You're a <bv><b>innocent with a gun</b></bv>, press <ch><b>space</b></ch> to wield it and after <ch><b>click on your target</b></ch> to kill him.",
  321. ["newGameM"] = "You're a <r><b>murder</b></r>, press <ch><b>space</b></ch> to wield your <r><b>knife</b></r> and press kill other players.",
  322. ["newGameM-2"] = "Say with other murders using <j>!tc <bl>[text]</bl></j>\nYou have acess to the <n2><b>flashbang</b></n2> press <ch><b>H</b></ch> to use it.",
  323. ["team-1"] = "<bv>innocents</bv>",
  324. ["team-2"] = "<r>murders</r>"
  325. },
  326. ["BR"] = {
  327. ["help-1"] = "<p align=\"center\"><b><font size=\"18\" face=\"Arial\"><VP>Murder</VP></font></b></p>Bem vindo ao <j><b>#murder</b>!</j> Criado por <j><b>Brenower</b></j>.<br><br><BV><b>• Inocente:</b></BV><br>Como inocente seu objetivo é escapar do <r><b>assassino</b></r> e procurar por objetos com brilho <vp><b>verde</b>,</vp> quando você obtém <j><b>5 objetos</b></j> você ganha <j><b>uma arma</b></j> para tornar o jogo mais fácil, mas cuidado <r><b>assassino</b></r> vai tentar interromper a coleta desses objetos.<br><br><bv><b>• Inocente com arma:</b></bv><br>A cada <j><b>3</b></j><r> <b>assassinos</b></r> um jogador inocente é selecionado para ter uma arma especial e pode usar-lá para matar outros <b><r>assassinos</r></b> <ch><b>clicando no jogador.</b></ch><br><br><r><b>• Assassino:</b></r><br>O assassino tem uma <r><b>faca</b>,</r> ele demora <j><b>1 segundo</b></j> para empunhar-lá (nesse tempo a faca fica visível aos jogadores) e então pode usar-lá em um jogador apertando <ch><b>espaço</b></ch> proxima ao jogador alvo. Ele também tem pode usar uma granada de flashbang que pode cegar a sua visão por <j><b>1 segundo</b></j> e cada vez que ele mata alguém a granada é jogada automaticamente cegando sua visão por mais tempo!",
  328. ["teamWin"] = "<p align='center'><font size=\"18\"><VP><b>O time dos %s ganhou a partida!</b></VP></font><br><br><font size=\"12\"><b><J>Melhores pontuações:</J></b></font><br>",
  329. ["profile"] = "<p align=\"center\"><J><font size=\"18\"><b>%s</b></font></J></p><br><font face=\"Verdana\"><ch><b>• Estatísticas Gerais:</b></ch><br>Rounds jogados: <vp><b>%i</b></vp><br>Vitórias: <vp><b>%i</b></vp><br>Pontos:<vp><b>%i</b></vp><br><br><bv><b>• Como inocente:</b></bv><br>Assassinos abatidos: <vp><b>%i</b></vp><br><br><r><b>• Como assassino:</b></r><br>Inocentes abatidos: <vp><b>%i</b></vp><br><br><ch><b>• Medalhas:</b></ch><br><v><b>[Em Breve]</b></v>",
  330. ["welcome"] = "<VP><b>Envie seus mapas:</b></VP>\n<v>http://atelier801.com/topic?f=745381&t=892082</v>\n<ROSE>Bem vindo ao <r><b>#murder</b></r>! Se precisar de ajuda use <j><b>!help</b>",
  331. ["prepKnife"] = "Você empunhou a sua <r><b>faca</b></r>! Aperte <ch><b>espaço</b></ch> de um jogador para mata-ló.",
  332. ["colKnife"] = "A sua <r><b>faca</b></r> está em countdown de <j><b>%i segundos.</b></j>",
  333. ["mrK"] = "Você matou <v><b>%s</b> (+1)</v>, sua faca entrou em countdown de <j><b>11 segundos.</b></j>",
  334. ["prepGun"] = "Sua <j><b>arma</b></j> foi empunhada!<ch><b>Clique em um jogador</b></ch> para atirar em alguém.",
  335. ["colGun"] = "Sua <j><b>arma</b></j> está em countdown de <j><b>%i segundos.</b></j>",
  336. ["obj"] = "Você coletou <vp><b>um objeto</b></vp><v> (+1)</v>, você tem no total: <v><b>%i / 5</b></v>",
  337. ["obj-5"] = "Agora você tem uma <j><b>arma!</b></j> Aperte <ch><b>espaço</b></ch> para empunhar ela.",
  338. ["flb"] = "A sua <n2><b>flashbang</b></n2> está em countdown de <j><b>%i segundos.</b></j>",
  339. --["useGun"] = "A sua <j><b>arma</b></j> entrou em cooldown de <j><b>1 segundo</b></j>",
  340. ["suicide"] = "O(A) <ch><b>%s</b></ch> suicidou-se por ter matado o(a) <bv><b>inocente</b></bv> <ch><b>%s</b></ch>!",
  341. ["inK"] = "O(A) <r><b>assassino</b></r> <ch><b>%s</b></ch> foi morto por <ch><b>%s</b></ch><v> (+5)</v>!",
  342. ["inK-2"] = "Era a última bala restante! Vá coletar outra arma.",
  343. ["map"] = "<J>%s</J> <BL>| <N>Assassinos vivos: </N><R>%i <BL>| <N>Inocentes vivos:</BV> <V>%i",
  344. ["team1Win"] = "Os <bv><b>inocentes</b></bv> ganharam a partida!",
  345. ["team2Win"] = "Os <r><b>assassinos</b></r> ganharam a partida!",
  346. ["draw"] = "O round acabou em empate!",
  347. ["newGameI"] = "Você é um <bv><b>inocente</b></bv>, colete objetos <vp><b>verdes</b></vp> e brilhantes espalhados pelo mapa apertando <ch><b>espaço</b></ch>, tente escapar do assassino.",
  348. ["newGameIG"] = "Você é um <bv><b>inocente com arma</b></bv>, aperte <ch><b>espaço</b></ch> para empunhar a sua <j><b>arma</b></j> e em seguida <ch><b>clique em um jogador</b></ch> para atirar.",
  349. ["newGameM"] = "Você é um <r><b>assassino</b></r>, aperte <ch><b>espaço</b></ch> para empunhar a sua <r><b>faca</b></r> e use-a para matar outros jogadores.",
  350. ["newGameM-2"] = "Fale com outros assassinos usando <j>!tc <bl>[text]</bl></j>\nVocê tem acesso a <n2><b>flashbang</b></n2> aperte <ch><b>H</b></ch> para usar-lá.",
  351. ["team-1"] = "<bv>inocentes</bv>",
  352. ["team-2"] = "<r>murders</r>"
  353. }
  354. }
  355.  
  356. local skelet = {
  357. points = {index = 1, type = "number", default = 0},
  358. victories = {index = 2, type = "number", default = 0},
  359. rounds = {index = 3, type = "number", default = 0},
  360. asK = {index = 4, type = "number", default = 0},
  361. inK = {index = 5, type = "number", default = 0}
  362. }
  363. local handler = dataHandler.construct("murder", skelet)
  364. local playerData = {};
  365.  
  366. local room = {
  367. ["timers"] = {
  368. ["resetOnNewGame"] = {};
  369. },
  370. ["txtNames"] = 0;
  371. ["imgNi"] = 0;
  372. ["objs"] = {};
  373. ["newGameTimer"] = false;
  374. ["currentObjs"] = {};
  375. ["murders"] = {};
  376. }
  377.  
  378. local maps = {"@6983192", "@6930472", "@6793860", "@6949300", "@6983699", "@6984074", "@6842313", "@6984402", "@6849540", "@6984339", "@6843395", "@6984781", '@6984643', '@6984930', '@6985881', '@6984979', '@6986325', '@6986486', '@6987451', '@6988840'}
  379. local imgs = {
  380. ["objs"] = {"15937381d5c.png", "159373a6025.png", "159373b56e1.png"};
  381. ["flashID"] = 1000;
  382. }
  383.  
  384. local skeletFile = {
  385. ranking = {
  386. index = 1,
  387. type = "string",
  388. default = ""
  389. }
  390. }
  391. local fileHandler = dataHandler.construct("mur", skeletFile)
  392. fileHandler:recordPlayer("Jarvis", "")
  393. local fileLoaded = false;
  394. local globalRanking = {};
  395. -- functions
  396.  
  397. function translate(p, text)
  398. local trans = tfm.get.room.playerList[p] and translations[tfm.get.room.playerList[p].community:upper()] or translations[tfm.get.room.community] or translations["EN"];
  399. return trans[text] or "nil";
  400. end
  401.  
  402. function message(p, text, ...)
  403. local text = text or "close";
  404. if p then
  405. if tfm.get.room.playerList[p] then
  406. tfm.exec.chatMessage(string.format(translate(p, text), ...) or "nil", p)
  407. end
  408. else
  409. for pname in pairs(tfm.get.room.playerList) do
  410. message(pname, text, ...)
  411. end
  412. end
  413. end
  414.  
  415. function ui.addWindow(id, text, player, x, y, width, height, alpha, corners, closeButton, buttonText)
  416. id = tostring(id)
  417. ui.addTextArea(id, "000000000", player, x, y, width, height, 0x573926, 0x573926, alpha, true)
  418. ui.addTextArea(id.."0", "", player, x+1, y+1, width-2, height-2, 0x8a583c, 0x8a583c, alpha, true)
  419. ui.addTextArea(id.."00", "", player, x+3, y+3, width-6, height-6, 0x2b1f19, 0x2b1f19, alpha, true)
  420. ui.addTextArea(id.."000", "", player, x+4, y+4, width-8, height-8, 0xc191c, 0xc191c, alpha, true)
  421. ui.addTextArea(id.."0000", "", player, x+5, y+5, width-10, height-10, 0x2d5a61, 0x2d5a61, alpha, true)
  422. ui.addTextArea(id.."00000", text, player, x+5, y+6, width-10, height-12, 0x142b2e, 0x142b2e, alpha, true)
  423. local imageId = {}
  424. if corners then
  425. table.insert(imageId, tfm.exec.addImage("155cbe97a3f.png", "&1", x-7, (y+height)-22, player))
  426. table.insert(imageId, tfm.exec.addImage("155cbe99c72.png", "&1", x-7, y-7, player))
  427. table.insert(imageId, tfm.exec.addImage("155cbe9bc9b.png", "&1", (x+width)-20, (y+height)-22, player))
  428. table.insert(imageId, tfm.exec.addImage("155cbea943a.png", "&1", (x+width)-20, y-7, player))
  429. end
  430. if closeButton then
  431. ui.addTextArea(id.."000000", "", player, x+14, y+height-24, width-27, 13, 0x7a8d93, 0x7a8d93, alpha, true)
  432. ui.addTextArea(id.."0000000", "", player, x+15, y+height-23, width-27, 13, 0xe1619, 0xe1619, alpha, true)
  433. ui.addTextArea(id.."00000000", "", player, x+15, y+height-23, width-28, 12, 0x314e57, 0x314e57, alpha, true)
  434. ui.addTextArea(id.."", buttonText, player, x+15, y+height-26, width-28, nil, 0x314e57, 0x314e57, 0, true)
  435. end
  436. return imageId
  437. end
  438.  
  439. function deepcopy(orig)
  440. local orig_type = type(orig)
  441. local copy
  442. if orig_type == 'table' then
  443. copy = {}
  444. for orig_key, orig_value in next, orig, nil do
  445. copy[deepcopy(orig_key)] = deepcopy(orig_value)
  446. end
  447. setmetatable(copy, deepcopy(getmetatable(orig)))
  448. else -- number, string, boolean, etc
  449. copy = orig
  450. end
  451. return copy
  452. end
  453.  
  454. function shuffle(a)
  455. if type(a) ~= "table" or #a < 2 then
  456. return a;
  457. end
  458. local a = a;
  459. local rnd,trem,getn,ins = math.random,table.remove,table.getn,table.insert;
  460. local r = {};
  461. while #a > 0 do
  462. local k = rnd(#a)
  463. r[#r+1] = a[k]
  464. trem(a, k)
  465. end
  466. return r;
  467. end
  468.  
  469. function help(p)
  470. local ids = ui.addWindow(50, translate(p, "help-1"), p, 75, 50, 650, 300, 1, true, true, "<p align='center'><a href='event:closeWindow'>Close<br></a></p>")
  471. --tfm.exec.chatMessage("<VP>Com:</VP> <v>!p <bl>[jogador] |</bl> !help</v>", p)
  472. for i = 1,#ids do
  473. table.insert(playerData[p].imagesIDS, ids[i])
  474. end
  475. end
  476.  
  477. function win(team)
  478. local textTeam = team == 0 and translate(nil, "team-1") or translate(nil, "team-2");
  479. local scoreTxt = {};
  480. local pls = {};
  481. for i,v in pairs(tfm.get.room.playerList) do
  482. if #pls < 10 then
  483. table.insert(pls, {["name"] = i, ["team"] = playerData[i].team == 0 and "<bv>Innocent</bv>" or "<r>Murder</r>"; ["points"] = playerData[i].points})
  484. end
  485. handler:set(i, "points", handler:query(i, "points") + playerData[i].points)
  486. if playerData[i].team == team and tfm.get.room.uniquePlayers > 6 then
  487. handler:set(i, "victories", handler:query(i, "victories") + 1)
  488. end
  489. end
  490.  
  491. table.sort(pls, function(a, b) return a.points > b.points end)
  492. for i,v in pairs(pls) do
  493. table.insert(scoreTxt, "<b><BL>"..v.name.." - "..v.team.." - </BL><V>"..v.points)
  494. end
  495.  
  496. local ids = ui.addWindow(51, string.format(translate(nil, "teamWin"), textTeam)..table.concat(scoreTxt, "<br>"), nil, 200, 75, 400, 250, 1, true, true, "<p align='center'><a href='event:closeWindow'>Close<br></a></p>")
  497. for i = 1,#ids do
  498. for p in pairs(tfm.get.room.playerList) do
  499. table.insert(playerData[p].imagesIDS, ids[i])
  500. end
  501. end
  502. end
  503.  
  504. function profile(p, p2)
  505. local p2 = p2 or p;
  506. if playerData[p2] then
  507. local points, rounds, victories, inK, asK = handler:query(p2, "points"), handler:query(p2, "rounds"), handler:query(p2, "victories"), handler:query(p2, "inK"), handler:query(p2, "asK");
  508. local ids = ui.addWindow(53, string.format(translate(p, "profile"), p2, rounds, victories, points, inK, asK), p, 275, 75, 250, 250, 1, true, true, "<p align='center'><a href='event:closeWindow'>Close<br></a></p>")
  509. for i = 1,#ids do
  510. for p in pairs(tfm.get.room.playerList) do
  511. table.insert(playerData[p].imagesIDS, ids[i])
  512. end
  513. end
  514. end
  515. end
  516.  
  517. function shopTop10(p)
  518. if globalRanking then
  519. local textNames = {};
  520. local textRounds = {};
  521. local textScore = {};
  522. local textWins = {};
  523.  
  524. for i = 1, #globalRanking do
  525. local player = globalRanking[i]
  526. textNames[#textNames+1] = player.name
  527. textScore[#textScore+1] = player.score
  528. textRounds[#textRounds+1] = player.rounds;
  529. textWins[#textWins+1] = player.wins
  530. end
  531.  
  532. local ids = ui.addWindow(60, [[<p align='center'><font size="16"><J><b>Ranking</b></J></font></p>   <b>#         Player                     Rounds       Points          Wins</b>]], p, 205, 85, 390+65, 230, 1, true, true, "<p align='center'><a href='event:closeRanking'>Close<br></a></p>")
  533. local ids2 = ui.addWindow(61, [[<p align='center'><CH><b>1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10</b></CH></p>]], p, 215, 135, 20+20, 135, 1, true, false)
  534. local ids3 = ui.addWindow(62, [[<p align='center'><N><b>]]..table.concat(textNames, '<br>')..[[</b></N></p>]], p, 260+10, 135, 100+20, 135, 1, true, false)
  535. local ids4 = ui.addWindow(63, [[<p align='center'><V><b>]]..table.concat(textRounds, '<br>')..[[</b></V></p>]], p, 385+25, 135, 50+20, 135, 1, true, false)
  536. local ids5 = ui.addWindow(64, [[<p align='center'><V><b>]]..table.concat(textScore, '<br>')..[[</b></V></p>]], p, 460+35, 135, 50+20, 135, 1, true, false)
  537. local ids6 = ui.addWindow(65, [[<p align='center'><V><b>]]..table.concat(textWins, '<br>')..[[</b></V></p>]], p, 535+45, 135, 50+20, 135, 1, true, false)
  538. for i = 1,#ids do
  539. for p in pairs(tfm.get.room.playerList) do
  540. table.insert(playerData[p].imagesIDS, ids[i])
  541. table.insert(playerData[p].imagesIDS, ids2[i])
  542. table.insert(playerData[p].imagesIDS, ids3[i])
  543. table.insert(playerData[p].imagesIDS, ids4[i])
  544. table.insert(playerData[p].imagesIDS, ids5[i])
  545. table.insert(playerData[p].imagesIDS, ids6[i])
  546. end
  547. end
  548. end
  549. end
  550. --[[function checkAlive()
  551. local mur = 0;
  552. local ino = 0;
  553. for i,v in pairs(tfm.get.room.playerList) do
  554. if not v.isDead then
  555. if playerData[i].team == 2 then
  556. mur = mur + 1;
  557. else
  558. ino = ino + 1;
  559. end
  560. end
  561. end
  562.  
  563. print(mur.." - "..ino)
  564. if mur == 0 then
  565. --tfm.exec.chatMessage("Todos os assassinos estão mortos! Os inocentes ganharam!")
  566. --system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  567. elseif ino == 0 then
  568. tfm.exec.chatMessage("Todos os inocentes estão mortos! Os assassinos ganharam!")
  569. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  570. elseif mur == 0 and ino == 0 then
  571. tfm.exec.chatMessage("O round acabou em empate!")
  572. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  573. end
  574. end]]--
  575.  
  576. -- tfm events
  577. function eventNewPlayer(p)
  578. print(name)
  579. playerData[p] = {
  580. ["imgNi"] = 10000;
  581. ["imagesIDS"] = {};
  582. ["team"] = 0;
  583. ["gunCol"] = false;
  584. ["haveGun"] = false;
  585. ["prepGun"] = false;
  586. ["imageGun"] = 10000;
  587. ["objs"] = 0;
  588. ["alive"] = false;
  589. ["flashBang"] = false;
  590. ["points"] = 0;
  591. ["loaded"] = false;
  592. ["calCol"] = os.time();
  593. }
  594. help(p)
  595. handler:recordPlayer(p, "")
  596. tfm.exec.lowerSyncDelay(p)
  597. for i,v in pairs{32, 72} do
  598. system.bindKeyboard(p, v, false)
  599. end
  600. system.loadPlayerData(p)
  601. system.bindMouse(p)
  602. ui.addWindow(70, "<p align='center'><font size='12px'><b><a href='event:menu'>» Menu</a></b></font></p>", p, 8, 28, 70, 22+7, 1, false, false)
  603. message(p, "welcome")
  604. --tfm.exec.chatMessage("<VP><b>Envie seus mapas:</b></VP>\n<v>http://atelier801.com/topic?f=745381&t=892082</v>\n<ROSE>Bem vindo ao <r><b>#murder</b></r>! Se precisar de ajuda use <j><b>!help</b>", p)
  605. end
  606.  
  607. function eventKeyboard(p, k, d, x, y)
  608. if k == 32 and playerData[p].team == 2 and playerData[p].alive then
  609. if not playerData[p].prepGun then
  610. if playerData[p].gunCol < os.time() then
  611. playerData[p].gunCol = os.time()+500;
  612. playerData[p].prepGun = true;
  613. --tfm.exec.chatMessage("Você empunhou a sua <r><b>faca</b></r>! Aperte <ch><b>espaço</b></ch> de um jogador para mata-ló.", p)
  614. message(p, "prepKnife")
  615. playerData[p].imageGun = tfm.exec.addImage("159364b2ac8.png", "$"..p, -20, 0)
  616. else
  617. local gunCol = math.floor((playerData[p].gunCol - os.time())/1000)
  618. --tfm.exec.chatMessage("A sua <r><b>faca</b></r> está em countdown de <j><b>"..gunCol.." segundos.</b></j>", p)
  619. message(p, "colKnife", gunCol)
  620. end
  621. elseif playerData[p].prepGun and playerData[p].gunCol < os.time()-500 then
  622. playerData[p].gunCol = os.time();
  623. for i,v in pairs(tfm.get.room.playerList) do
  624. if x > v.x-20 and x < v.x+20 and y > v.y-20 and y < v.y+20 and i ~= p and not v.isDead and playerData[i].team < 2 then
  625. --tfm.exec.chatMessage("Você matou <v><b>"..i.."</b> (+1)</v>, sua faca entrou em countdown de <j><b>9 segundos.</b></j>", p)
  626. message(p, "mrK", i)
  627. if tfm.get.room.uniquePlayers > 6 then
  628. handler:set(p, "inK", handler:query(p, "inK") + 1)
  629. end
  630. --tfm.exec.chatMessage("O <bv><b>inocente</b></bv> <ch><b>"..i.."</b></ch> foi morto(a) por um <r><b>assassino(a)!</b></r>")
  631. room.txtNames = room.txtNames + 1;
  632. ui.addTextArea(room.txtNames, "<font size=\"10\"><BV>"..i.."</BV></font>", nil, v.x-25, v.y-25, nil, 19, 0x080808, 0x000000, 0.1, false)
  633. tfm.exec.addImage("15938ae765f.png", "!1", v.x-15, v.y-15)
  634. playerData[p].points = playerData[p].points + 2;
  635. tfm.exec.killPlayer(i)
  636. playerData[p].prepGun = false;
  637. tfm.exec.removeImage(playerData[p].imageGun)
  638. playerData[p].gunCol = os.time()+11*1000;
  639. return;
  640. end
  641. end
  642. end
  643. elseif k == 32 and playerData[p].haveGun and not playerData[p].prepGun and playerData[p].alive then
  644. if playerData[p].gunCol < os.time() then
  645. --tfm.exec.chatMessage("Sua <j><b>arma</b></j> foi empunhada!<ch><b>Clique em um jogador</b></ch> para atirar em alguém.", p)
  646. message(p, "prepGun")
  647. playerData[p].prepGun = true;
  648. playerData[p].imageGun = tfm.exec.addImage("15936b18f2a.png", "$"..p, 0, -10)
  649. else
  650. local gunCol = math.floor((playerData[p].gunCol - os.time()) / 1000)
  651. message(p, "colGun", gunCol)
  652. --tfm.exec.chatMessage("Sua <j><b>arma</b></j> está em countdown de <j><b>"..gunCol.." segundos.</b></j>", p)
  653. end
  654. elseif k == 32 and playerData[p].alive and not playerData[p].haveGun and playerData[p].team == 0 then
  655. if playerData[p].gunCol < os.time()-750 then
  656. playerData[p].gunCol = os.time();
  657. local objs = room.currentObjs;
  658. for i,v in pairs(objs) do
  659. if x > v[2]-30 and x < v[2]+30 and y > v[3]-30 and y < v[3]+30 and room.currentObjs[i] then
  660. tfm.exec.removeImage(v[1])
  661. playerData[p].objs = playerData[p].objs + 1;
  662. --tfm.exec.chatMessage("Você coletou <vp><b>um objeto</b></vp><v> (+1)</v>, você tem no total: <v><b>"..playerData[p].objs.." / 5</b></v>", p)
  663. message(p, "obj", playerData[p].objs)
  664. playerData[p].points = playerData[p].points + 1;
  665. if playerData[p].objs >= 5 then
  666. --tfm.exec.chatMessage("Agora você tem uma <j><b>arma!</b></j> Aperte <ch><b>espaço</b></ch> para empunhar ela.", p)
  667. message(p, "obj-5")
  668. playerData[p].objs = 0;
  669. playerData[p].prepGun = false;
  670. playerData[p].haveGun = true;
  671. playerData[p].gunCol = os.time()+1*1000;
  672. end
  673. table.remove(room.currentObjs, i)
  674. break;
  675. end
  676. end
  677. end
  678. end
  679. if k == 72 and playerData[p].alive and playerData[p].flashBang and playerData[p].flashBang < os.time() then
  680. addTimer(function(i)
  681. if i == 1 then
  682. tfm.exec.removeImage(room.flashID)
  683. room.flashID = tfm.exec.addImage("15937b95aa1.png", "&1", 0, 0)
  684. elseif i == 2 then
  685. tfm.exec.removeImage(room.flashID)
  686. room.flashID = tfm.exec.addImage("15937b97d74.png", "&1", 0, 0)
  687. elseif i == 3 then
  688. tfm.exec.removeImage(room.flashID)
  689. room.flashID = tfm.exec.addImage("15937b9a1f9.png", "&1", 0, 0)
  690. elseif i == 5 then
  691. tfm.exec.removeImage(room.flashID)
  692. end
  693. end, 500, 5)
  694. playerData[p].flashBang = os.time()+40*1000;
  695. elseif k == 72 and playerData[p].alive and playerData[p].flashBang then
  696. local flashCol = math.floor((playerData[p].flashBang - os.time())/1000)
  697. --tfm.exec.chatMessage("A sua <n2><b>flashbang</b></n2> está em countdown de <j><b>"..flashCol.." segundos.</b></j>", p)
  698. message(p, "flb", flashCol)
  699. end
  700. end
  701.  
  702. function eventMouse(p, x, y)
  703. if playerData[p].haveGun and playerData[p].prepGun and playerData[p].gunCol < os.time()-1000 and playerData[p].alive then
  704. playerData[p].gunCol = os.time();
  705. --tfm.exec.chatMessage("A sua <j><b>arma</b></j> entrou em cooldown de <j><b>1 segundo</b></j>", p)
  706. for i,v in pairs(tfm.get.room.playerList) do
  707. if x > v.x-25 and x < v.x+25 and y > v.y-25 and y < v.y+25 and i ~= p and not v.isDead then
  708. tfm.exec.removeImage(playerData[p].imageGun)
  709. if playerData[i].team == 0 then
  710. --tfm.exec.chatMessage("O(A) <ch><b>"..p.."</b></ch> suicidou-se por ter matado o(a) <bv><b>inocente</b></bv> <ch><b>"..i.."</b></ch>!")
  711. message(nil, "suicide", p, i)
  712. tfm.exec.killPlayer(p)
  713. tfm.exec.killPlayer(i)
  714. break;
  715. else
  716. --tfm.exec.chatMessage("O(A) <r><b>assassino</b></r> <ch><b>"..i.."</b></ch> foi morto por <ch><b>"..p.."</b></ch><v> (+5)</v>!")
  717. message(nil, "inK", i, p)
  718. if tfm.get.room.uniquePlayers > 6 then
  719. handler:set(p, "asK", handler:query(p, "asK") + 1)
  720. end
  721. --tfm.exec.chatMessage("Era a última bala restante! Vá coletar outra arma.", p)
  722. message(p, "inK-2")
  723. playerData[p].points = playerData[p].points + 5;
  724. playerData[p].haveGun = false;
  725. tfm.exec.killPlayer(i)
  726. break;
  727. end
  728. end
  729. end
  730. end
  731. end
  732.  
  733. function eventPlayerDataLoaded(p, dt)
  734. handler:recordPlayer(p, dt)
  735. playerData[p].loaded = true;
  736. end
  737.  
  738. function eventPlayerDied(p)
  739. playerData[p].alive = false;
  740. local ino = 0;
  741. local mur = 0;
  742. for i,v in pairs(tfm.get.room.playerList) do
  743. if not v.isDead then
  744. if playerData[i].team == 0 then
  745. ino = ino + 1;
  746. elseif playerData[i].team == 2 then
  747. mur = mur + 1;
  748. end
  749. end
  750. end
  751.  
  752. ui.setMapName(string.format(translate(p, "map"), tfm.get.room.xmlMapInfo.author, mur, ino))
  753.  
  754. if not room.newGameTimer then
  755. if mur == 0 then
  756. win(0)
  757. --tfm.exec.chatMessage("Os <bv><b>inocentes</b></bv> ganharam a partida!")
  758. message(nil, "team1Win")
  759. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  760. room.newGameTimer = true;
  761. elseif ino == 0 then
  762. win(2)
  763. --tfm.exec.chatMessage("Os <r><b>assassinos</b></r> ganharam a partida!")
  764. message(nil, "team2Win")
  765. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  766. room.newGameTimer = true;
  767. elseif mur == 0 and ino == 0 then
  768. win(0)
  769. --tfm.exec.chatMessage("O round acabou em empate!")
  770. message(nil, "draw")
  771. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  772. room.newGameTimer = true;
  773. end
  774. end
  775. end
  776.  
  777. local id = 0;
  778. function eventNewGame()
  779. local np = 0;
  780. room.newGameTimer = false;
  781. tfm.exec.setGameTime(3*60+3)
  782. local pls = {};
  783.  
  784. room.murders = {};
  785. room.objs = {};
  786. --test
  787. room.currentObjs = {};
  788. for i = 1,#room.timers.resetOnNewGame do
  789. system.removeTimer(room.timers.resetOnNewGame[i])
  790. end
  791. room.timers.resetOnNewGame = {};
  792.  
  793. for i = 1,room.txtNames do
  794. ui.removeTextArea(i)
  795. end
  796. room.txtNames = 0;
  797.  
  798. for i,v in pairs(tfm.get.room.playerList) do
  799. playerData[i].imgNi = tfm.exec.addImage("159341ae791.png", "$"..i, -1000, -1000, i)
  800. table.insert(pls, i)
  801. playerData[i].team = 0;
  802. playerData[i].haveGun = false;
  803. playerData[i].gunCol = os.time()+15*1000;
  804. playerData[i].prepGun = false;
  805. playerData[i].objs = 0;
  806. room.imgNi = 0;
  807. playerData[i].alive = true;
  808. playerData[i].flashBang = false;
  809. playerData[i].points = 0;
  810. np = np + 1;
  811. tfm.exec.setPlayerScore(i, handler:query(i, "points"), false)
  812. if tfm.get.room.uniquePlayers > 6 then
  813. handler:set(i, "rounds", handler:query(i, "rounds") + 1)
  814. end
  815. if playerData[i].loaded then
  816.  
  817. end
  818. if v.registrationDate == 0 then
  819. tfm.exec.killPlayer(i)
  820. end
  821. end
  822. pls = shuffle(pls)
  823. local nm = np > 4 and math.floor(np/5) or 1;
  824. local gm = nm > 2 and math.floor(nm/3) or 0;
  825.  
  826. ui.setMapName(string.format(translate(nil, "map"), tfm.get.room.xmlMapInfo.author, nm, np-nm))
  827.  
  828. for i = 1,#pls do
  829. if nm ~= 0 then
  830. playerData[pls[i]].team = 2;
  831. nm = nm - 1;
  832. playerData[pls[i]].flashBang = os.time()+26*1000;
  833. elseif gm > 0 then
  834. playerData[pls[i]].team = 0;
  835. playerData[pls[i]].haveGun = true;
  836. gm = gm - 1;
  837. else
  838. break;
  839. end
  840. end
  841. --playerData["Brenower"].team = 0;
  842. --playerData.Brenower.haveGun = false;
  843. for i,v in pairs(pls) do
  844. if playerData[v].team == 0 and not playerData[v].haveGun then
  845. --tfm.exec.chatMessage("Você é um <bv><b>inocente</b></bv>, colete objetos <vp><b>verdes</b></vp> e brilhantes espalhados pelo mapa apertando <ch><b>espaço</b></ch>, tente escapar do assassino.", v)
  846. message(v, "newGameI")
  847. elseif playerData[v].haveGun then
  848. --tfm.exec.chatMessage("Você é um <bv><b>inocente com arma</b></bv>, aperte <ch><b>espaço</b></ch> para empunhar a sua <j><b>arma</b></j> e em seguida <ch><b>clique em um jogador</b></ch> para atirar.", v)
  849. message(v, "newGameIG")
  850. elseif playerData[v].team == 2 then
  851. --tfm.exec.chatMessage("Você é um <r><b>assassino</b></r>, aperte <ch><b>espaço</b></ch> para empunhar a sua <r><b>faca</b></r> e use-a para matar outros jogadores.", v)
  852. --tfm.exec.chatMessage("Você tem acesso a <n2><b>flashbang</b></n2> aperte <ch><b>H</b></ch> para usar-lá.", v)
  853. table.insert(room.murders, v)
  854. message(v, "newGameM")
  855. message(v, "newGameM-2")
  856. end
  857. end
  858.  
  859. table.insert(room.timers.resetOnNewGame ,system.newTimer(function()
  860. room.imgNi = room.imgNi + 1;
  861. if room.imgNi > 5 then
  862. return;
  863. end
  864. for i,v in pairs(tfm.get.room.playerList) do
  865. if not v.isDead then
  866. tfm.exec.removeImage(playerData[i].imgNi)
  867. if room.imgNi == 1 then
  868. playerData[i].imgNi = tfm.exec.addImage("159341a53d4.png", "$"..i, -1000, -1000, i)
  869. else
  870. playerData[i].imgNi = tfm.exec.addImage("159341ac243.png", "$"..i, -1000, -1000, i)
  871. end
  872. end
  873. end
  874. end, 40*1000, true))
  875.  
  876. for xml in tfm.get.room.xmlMapInfo.xml:gmatch("<O[^/]+/>") do
  877. if tonumber(xml:match('C="(%d+)"')) == 14 then
  878. room.objs[#room.objs+1] = {tonumber(xml:match('X="(%d+)"')), tonumber(xml:match('Y="(%d+)"'))} -- x, y
  879. end
  880. end
  881.  
  882. table.insert(room.timers.resetOnNewGame, system.newTimer(function()
  883. local tob = np > 9 and math.floor(np/10) or 1;
  884. for i = 1,tob do
  885. local rnd = room.objs[math.random(#room.objs)]
  886. if #room.currentObjs > 2 then
  887. return;
  888. end
  889. --id = id + 1;
  890. room.currentObjs[#room.currentObjs+1] = {tfm.exec.addImage(imgs.objs[math.random(#imgs.objs)], "!1", rnd[1], rnd[2]-30), rnd[1], rnd[2]}
  891. --tfm.exec.addPhysicObject(id, rnd[1]+15, rnd[2], {["type"]=1;["width"]=48;["height"]=48})
  892. end
  893. end, 3000, true))
  894.  
  895. --table.insert(room.timers.resetOnNewGame, system.newTimer(function() checkAlive() end), 5*1000, true)
  896. end
  897.  
  898. function eventTextAreaCallback(id, p, event)
  899. if playerData[p].calCol < os.time()-750 then
  900. playerData[p].calCol = os.time();
  901. if event == "closeWindow" then
  902. local ids = {id, id.."0", id.."00", id.."000", id.."0000", id.."00000", id.."000000", id.."0000000", id.."00000000", id.."000000000"}
  903. for i = 1,#ids do
  904. ui.removeTextArea(ids[i], p)
  905. end
  906. if playerData[p] and #playerData[p].imagesIDS > 0 then
  907. for i in pairs(playerData[p].imagesIDS) do
  908. tfm.exec.removeImage(playerData[p].imagesIDS[i])
  909. end
  910. playerData[p].imagesIDS = {};
  911. end
  912. elseif event == "closeRanking" then
  913. for i = 60,65 do
  914. local id = i;
  915. local ids = {id, id.."0", id.."00", id.."000", id.."0000", id.."00000", id.."000000", id.."0000000", id.."00000000", id.."000000000"}
  916. for i = 1,#ids do
  917. ui.removeTextArea(ids[i], p)
  918. end
  919. end
  920. if playerData[p] and #playerData[p].imagesIDS > 0 then
  921. for i in pairs(playerData[p].imagesIDS) do
  922. tfm.exec.removeImage(playerData[p].imagesIDS[i])
  923. end
  924. playerData[p].imagesIDS = {};
  925. end
  926. elseif event == "menu" then
  927. ui.addWindow(71, "<p align='center'><font size='12px'><b><a href='event:closeMenu'>» Close</a></b></font></p>", p, 8, 28, 70, 22+7, 1, false, false)
  928. ui.addWindow(72, "<CH><p align='center'><font size='11px'><b><a href='event:help'>» Help</a></b></font></p>", p, 8, 59+8, 70, 22+7, 1, false, false)
  929. ui.addWindow(73, "<CH><p align='center'><font size='10px'><b><a href='event:profile'>» Profile</a></b></font></p>", p, 8, 90+15, 70, 22+7, 1, false, false)
  930. ui.addWindow(74, "<CH><p align='center'><font size='10px'><b><a href='event:ranking'>» Rank</a></b></font></p>", p, 8, 121+23, 70, 22+7, 1, false, false)
  931. ui.addWindow(75, "<CH><p align='center'><font size='10px'><b><a href='event:skins'>» ???</a></b></font></p>", p, 8, 152+30, 70, 22+7, 1, false, false)
  932. elseif event == "closeMenu" then
  933. for i = 71,75 do
  934. local id = i;
  935. local ids = {id, id.."0", id.."00", id.."000", id.."0000", id.."00000", id.."000000", id.."0000000", id.."00000000", id.."000000000"}
  936. for i = 1,#ids do
  937. ui.removeTextArea(ids[i], p)
  938. end
  939. end
  940. elseif event == "help" then
  941. help(p)
  942. elseif event == "profile" then
  943. profile(p, p)
  944. elseif event == "ranking" then
  945. shopTop10(p)
  946. end
  947. end
  948. end
  949.  
  950. function eventLoop(ct, rt)
  951. if rt <= 0 and not room.newGameTimer then
  952. --tfm.exec.chatMessage("O round acababou em empate!")
  953. message(nil, "draw")
  954. system.newTimer(function() tfm.exec.newGame(maps[math.random(#maps)]) end, 2500)
  955. room.newGameTimer = true;
  956. win(0)
  957. end
  958.  
  959. local timersToRemove = {}
  960. for id = 1, #timerList do
  961. local timer = timerList[id]
  962. if type(timer) == 'table' then
  963. if not timer.isComplete then
  964. timer.currentTime = timer.currentTime + 500
  965. if timer.currentTime >= timer.time then
  966. timer.currentTime = 0
  967. timer.currentLoop = timer.currentLoop + 1
  968. if timer.loops > 0 then
  969. if timer.currentLoop >= timer.loops then
  970. timer.isComplete = true
  971. end
  972. end
  973. if type(timer.callback) == 'function' then
  974. timer.callback(timer.currentLoop, table.unpack(timer.arguments))
  975. end
  976. end
  977. end
  978. if timer.isComplete then
  979. if type(eventTimerComplete) == 'function' then
  980. eventTimerComplete(id, timer.label)
  981. end
  982. timersToRemove[#timersToRemove+1] = id
  983. end
  984. end
  985. end
  986. for i = 1, #timersToRemove do
  987. removeTimer(timersToRemove[i])
  988. end
  989. end
  990.  
  991. function eventFileLoaded(id, data)
  992. local id = tonumber(id:match('%d+'))
  993. fileHandler:recordPlayer("Jarvis", data)
  994.  
  995. if id == 5 then
  996. local dRanking = fileHandler:query("Jarvis", "ranking")
  997. local localTop10 = {}
  998.  
  999. for name, rounds, score, victories in string.gmatch(dRanking, '([0-9a-zA-Z_]+)!([0-9]+)!([0-9]+)!([0-9]+);?') do
  1000. --tfm.exec.chatMessage('carregou '..name)
  1001. localTop10[#localTop10+1] = {
  1002. name = name,
  1003. rounds = rounds,
  1004. score = score,
  1005. wins = victories
  1006. }
  1007. end
  1008.  
  1009. local rankingString = {}
  1010.  
  1011. for i = #localTop10, 1, -1 do
  1012. if tfm.get.room.playerList[localTop10[i].name] then
  1013. table.remove(localTop10, i)
  1014. end
  1015. end
  1016.  
  1017. for name in pairs(tfm.get.room.playerList) do
  1018. localTop10[#localTop10+1] = {name=name, wins=handler:query(name, 'victories'), score=handler:query(name, 'points'), rounds=handler:query(name, 'rounds')}
  1019. end
  1020.  
  1021. table.sort(localTop10, function(a, b) return tonumber(a.score) > tonumber(b.score) end)
  1022.  
  1023. if #localTop10 > 10 then
  1024. local len = #localTop10
  1025. for i = len, 11, -1 do
  1026. table.remove(localTop10, i)
  1027. end
  1028. end
  1029.  
  1030. for _, player in pairs(localTop10) do
  1031. rankingString[#rankingString+1] = string.format('%s!%i!%i!%i', player.name or "", player.rounds or 0, player.score or 0, player.wins or 0)
  1032. end
  1033.  
  1034. rankingString = table.concat(rankingString, ';');
  1035. fileHandler:set("Jarvis", "ranking", rankingString)
  1036.  
  1037.  
  1038. globalRanking = {}
  1039. globalRanking = deepcopy(localTop10)
  1040. --tfm.exec.chatMessage("<rose>carregou")
  1041. end
  1042. end
  1043.  
  1044. function eventChatCommand(p, cmd)
  1045. local params = {};
  1046. for param in cmd:gmatch('[^%s]+') do
  1047. params[#params+1] = param;
  1048. end
  1049.  
  1050. if params[1] == "help" then
  1051. help(p)
  1052. return;
  1053. elseif params[1] == "p" then
  1054. params[2] = params[2] or p;
  1055. local target = params[2]:lower():gsub('%a', string.upper, 1);
  1056. profile(p, params[2])
  1057. return
  1058. elseif params[1] == "see" then
  1059. tfm.exec.chatMessage(handler:retrievePlayer(p), p)
  1060. return
  1061. elseif params[1] == "ranking" or params[1] == "rank" then
  1062. shopTop10(p)
  1063. return
  1064. elseif params[1] == "tc" and playerData[p] and (p == "Brenower" or playerData[p].team == 2) then
  1065. for i,v in pairs(room.murders) do
  1066. tfm.exec.chatMessage("<R>• <b>[#Murder] ["..p.."]</b></R> <N>"..table.concat(params, " ", 2), v)
  1067. end
  1068. return;
  1069. end
  1070.  
  1071. if p == "Brenower" then
  1072. if params[1] == "msg" then
  1073. tfm.exec.chatMessage("<font color='#fe9d4d'>• <b>[Jarvis]</b></font> <N>"..table.concat(params, " ", 2))
  1074. return;
  1075. elseif params[1] == "np" then
  1076. pcall(tfm.exec.newGame, params[2])
  1077. elseif params[1] == "addmap" then
  1078. table.insert(maps, params[2])
  1079. elseif params[1] == "acc" then
  1080. tfm.exec.chatMessage("[color=#30BA76]@"..tfm.get.room.xmlMapInfo.mapCode.."[/color][color=#6C77C1] - [/color][color=#BABD2F]"..tfm.get.room.xmlMapInfo.author.."[/color][color=#6C77C1] - Aceito[/color]", p)
  1081. elseif params[1] == "rec" then
  1082. params[2] = params[2] or "";
  1083. tfm.exec.chatMessage("[color=#CB546B]@"..tfm.get.room.xmlMapInfo.mapCode.."[/color][color=#6C77C1] - [/color][color=#BABD2F]"..tfm.get.room.xmlMapInfo.author.."[/color][color=#6C77C1] - "..table.concat(params, " ", 2).."[/color]", p)
  1084. end
  1085. end
  1086. end
  1087.  
  1088. for i,v in pairs{"help", "msg", "np", "addmap", "p", "see", "rank", "ranking", "tc"} do
  1089. system.disableChatCommandDisplay(v)
  1090. end
  1091.  
  1092. for i in pairs(tfm.get.room.playerList) do
  1093. eventNewPlayer(i)
  1094. end
  1095.  
  1096. tfm.exec.disableAutoNewGame()
  1097. tfm.exec.disableAutoScore()
  1098. tfm.exec.disableAutoShaman()
  1099. tfm.exec.disableAutoTimeLeft()
  1100. tfm.exec.disableWatchCommand()
  1101. tfm.exec.disableDebugCommand()
  1102. tfm.exec.setAutoMapFlipMode(false)
  1103. tfm.exec.setRoomMaxPlayers(28)
  1104. tfm.exec.newGame('@6983192')
  1105.  
  1106. system.loadFile(5) -- carrega a primeira vez que o module carrega ai dps só no timer abaixo
  1107.  
  1108. system.newTimer(function()
  1109. system.loadFile(5)
  1110. end, 1000 * 65 + 1, true)
  1111.  
  1112. --ui.addTextArea(0, "<p align=\"center\"><b><font size=\"18\" face=\"Arial\"><VP>Murder</VP></font></b></p><br>Bem vindo ao <j><b>#murder</b>!</j> A cada rodada você recebe um nome diferente e uma cor para identifica-ló, não revele a sua verdadeira identidade ou poderá ter consequências graves!<br><br><BV><b>• Inocente:</b></BV><br>Como inocente seu objetivo é escapar do <r><b>assassino</b></r> e procurar por objetos com brilho <v><b>verde</b>,</v> quando você obtém <j><b>5 objetos</b></j> você ganha <j><b>em breve</b></j> para tornar o jogo mais fácil, mas cuidado <r><b>assassino</b></r> vai tentar interromper a coleta desses objetos.<br><br><bv><b>• Inocente com arma:</b></bv><br>Quando tiver mais de <j><b>3 </b></j><r><b>assassinos</b></r> um jogador inocente é selecionado para ter uma arma especial, para empunhar a arma tem um delay de <j><b>2 segundos</b></j> e pode ficar-lá na mão por no máximo <j><b>10 segundos</b></j> antes de entrar em tempo de recarga.<br><br><r><b>• Assassino:</b></r><br>O assassino tem uma <r><b>faca</b>,</r> ele demora <j><b>1 segundo</b></j> para empunhar-lá (nesse tempo a faca fica visível aos jogadores) e então pode usar-lá em um jogador apertando <ch><b>espaço</b></ch> proxima ao jogador alvo. Ele também tem pode usar uma granada de flashbang que pode cegar a sua visão por <j><b>1 segundo</b></j> e cada vez que ele mata alguém a granada é jogada automaticamente cegando sua visão por mais tempo!", nil, 75, 50, 650, 300, 0x0a1f1d, 0x000000, 1, true)
Advertisement
Add Comment
Please, Sign In to add comment