Advertisement
Guest User

shotlog samp

a guest
Nov 17th, 2019
244
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.28 KB | None | 0 0
  1. local events = require 'lib.samp.events'
  2.  
  3. local settings = {
  4. max_lines = 30,
  5. fake_afk = false,
  6. remove_on_quit = false
  7. }
  8.  
  9. function create_empty_item()
  10. return {
  11. shots = 0,
  12. hits = 0,
  13. accuracy = 0,
  14. last = 0,
  15. nick = '',
  16. lines = {}, sum=0
  17. }
  18. end
  19.  
  20. function get_speed_safely(id)
  21. if id == select(2, sampGetPlayerIdByCharHandle(1)) then return math.floor(getCharSpeed(1) * 3) end
  22. local res, ped = sampGetCharHandleBySampPlayerId(id)
  23. if not res then return 'UNK' else
  24. return math.floor(getCharSpeed(ped) * 3) end
  25. end
  26.  
  27. function get_vspeed_safely(id)
  28. local res, car = sampGetCarHandleBySampVehicleId(id)
  29. if not res then return 'UNK' else
  30. return math.floor(getCarSpeed(car) * 3) end
  31. end
  32.  
  33. function get_vehicle_model(id)
  34. local res, car = sampGetCarHandleBySampVehicleId(id)
  35. if res then return getNameOfVehicleModel(getCarModel(car)) else return 'UNK ' .. tostring(id) end
  36. end
  37.  
  38. function get_weapon_name(id)
  39. local weapons = {
  40. [22] = 'glock',
  41. [23] = 's glock',
  42. [24] = 'deagle',
  43. [25] = 'shotgun',
  44. [26] = 'sawn',
  45. [27] = 'spac12',
  46. [28] = 'uzi',
  47. [29] = 'mp5',
  48. [30] = 'ak47',
  49. [31] = 'm4',
  50. [32] = 'tec9',
  51. [33] = 'rifle',
  52. [34] = 'sniper',
  53. [38] = 'minigun'
  54. }
  55. return weapons[id] or 'UNK ' .. tostring(id)
  56. end
  57.  
  58. local pool = {}
  59.  
  60. local shotspec = false
  61. local shotspec_id = -1
  62.  
  63. function process_warning(id, data)
  64. local O, T = data.origin, data.target
  65. if data.targetType == 1 and not isLineOfSightClear(O.x, O.y, O.z, T.x, T.y, T.z, true, false, false, true, true) then
  66. return ' {CCAA00}(стрельба сквозь текстуры){ABCDEF}'
  67. end
  68. return ''
  69. end
  70.  
  71. function events.onSendBulletSync(data)
  72. process_bullet_sync(select(2, sampGetPlayerIdByCharHandle(1)), data)
  73. end
  74.  
  75. function events.onBulletSync(id, data)
  76. process_bullet_sync(id, data)
  77. end
  78.  
  79. function events.onPlayerQuit(id)
  80. if settings.remove_on_quit and pool[id] then
  81. pool[id] = create_empty_item()
  82. end
  83. end
  84.  
  85. function process_bullet_sync(id, data)
  86. if not pool[id] or pool[id].nick ~= sampGetPlayerNickname(id) then pool[id] = create_empty_item() end
  87.  
  88. local O, T = data.origin, data.target
  89. local distance = math.sqrt((O.x - T.x) ^ 2 + (O.y - T.y) ^ 2 + (O.z - T.z) ^ 2)
  90. local dist_text = ''
  91. if data.targetType == 1 or data.targetType == 2 then dist_text = ', ' .. math.floor(distance) .. 'm' end
  92.  
  93. local hit_name = 'ПРОМАХ'
  94. if data.targetType == 1 then hit_name = sampGetPlayerNickname(data.targetId) end
  95. if data.targetType == 2 then hit_name = get_vehicle_model(data.targetId) end
  96.  
  97. local speed_vs = ''
  98. if data.targetType == 1 then speed_vs = ', ' .. get_speed_safely(id) .. ' vs ' .. get_speed_safely(data.targetId) end
  99. if data.targetType == 2 then speed_vs = ', ' .. get_speed_safely(id) .. ' vs ' .. get_vspeed_safely(data.targetId) end
  100.  
  101. local time_since = os.clock() - pool[id].last
  102. if time_since > 5 and pool[id].shots > 0 then pool[id].lines[#pool[id].lines + 1] = '' end
  103. if time_since > 1 then time_since = 'ok' else time_since = math.floor(1000 * time_since) .. 'ms' end
  104.  
  105. pool[id].nick = sampGetPlayerNickname(id)
  106. pool[id].last = os.clock()
  107. pool[id].shots = pool[id].shots + 1
  108. if data.targetType == 1 or data.targetType == 2 then pool[id].hits = pool[id].hits + 1 end
  109. pool[id].accuracy = math.floor(100 * pool[id].hits / pool[id].shots)
  110.  
  111. local line = string.format(
  112. '%s > %s%s, %s%s > %s%s',
  113. pool[id].nick, get_weapon_name(data.weaponId), dist_text, time_since, speed_vs, hit_name, process_warning(id, data)
  114. )
  115. pool[id].lines[#pool[id].lines + 1] = '[' .. os.date('%H:%M:%S') .. '] ' .. line
  116. if shotspec and shotspec_id == id then sampAddChatMessage('[SHOT] ' .. line, -1) end
  117. end
  118.  
  119. function onSendPacket(id)
  120. if settings.fake_afk and (id == 200 or id == 207 or id == 211) then -- sampAddChatMessage(1,-1);
  121. if sampIsDialogActive() then
  122. local did = sampGetCurrentDialogId()
  123. if did == 5555 or did == 5556 then return false end
  124. end
  125. end
  126. end
  127.  
  128. local pids = {}
  129. function show_list()
  130. --[[local output = ''
  131. for i = 0, 999 do
  132. if pool[i] then
  133. output = output .. pool[i].nick .. ' [ID ' .. i .. ']\t' ..
  134. pool[i].hits .. '/' .. pool[i].shots .. ' (' .. pool[i].accuracy .. '%)\n'
  135. end
  136. end
  137. sampShowDialog(5556, 'Статистика стрельбы', output, 'Select', 'X', 4)]]
  138. -- ### I know this is fucked up
  139. pids = {}
  140. local output = ''
  141. local sorted = {}
  142. local sorted_len = 0
  143. local pool_len = 0
  144. for i = 0, 999 do if pool[i] then pool_len = pool_len + 1 end end
  145. if pool_len == 0 then return sampAddChatMessage('В статистике стрельбы нет ни одной записи.', 0xAFAFAF) end
  146. while sorted_len ~= pool_len do
  147. local highest = -1
  148. local max = 0
  149. for i = 0, 999 do
  150. if pool[i] and not sorted[i] then
  151. if pool[i].accuracy >= max then
  152. max = pool[i].accuracy
  153. highest = i
  154. end
  155. end
  156. end
  157. sorted[highest] = true
  158. sorted_len = sorted_len + 1
  159. local off = off_mark(highest)
  160. output = output .. pool[highest].nick .. ' [ID ' .. highest .. ']' .. off .. '\t' ..
  161. pool[highest].hits .. '/' .. pool[highest].shots .. ' (' .. pool[highest].accuracy .. '%)\n'
  162. pids[#pids+1] = highest
  163. end
  164. sampShowDialog(5556, 'Статистика стрельбы', output, '>>', 'X', 4)
  165. end
  166.  
  167. local arrow_shown = false
  168. function show_stats(id, arrow)
  169. arrow_shown = arrow or false
  170. local off = off_mark(id)
  171. local output = '{ABCDEF}Статистика попаданий: ' .. pool[id].hits .. '/' .. pool[id].shots .. ' (' .. pool[id].accuracy .. '%)\n'
  172. local start = #pool[id].lines > settings.max_lines and #pool[id].lines - settings.max_lines or 1
  173. for i = start, #pool[id].lines do
  174. output = output .. '\n' .. pool[id].lines[i]
  175. end
  176. if arrow then
  177. sampShowDialog(5555, 'Лог выстрелов ' .. pool[id].nick .. ' [ID ' .. id .. ']' .. off, output, '<<', 'X')
  178. else
  179. sampShowDialog(5555, 'Лог выстрелов ' .. pool[id].nick .. ' [ID ' .. id .. ']' .. off, output, 'X')
  180. end
  181. end
  182.  
  183. function off_mark(id)
  184. if id == select(2, sampGetPlayerIdByCharHandle(1)) then return '' end
  185. if not sampIsPlayerConnected(id) or pool[id].nick ~= sampGetPlayerNickname(id) then return ' {AA0000}OFF{FFFFFF}'
  186. else return '' end
  187. end
  188.  
  189. function main()
  190. while not isSampAvailable() do wait(100) end
  191. sampRegisterChatCommand('shotlog', function (id)
  192. if id == '' then return show_list() end
  193. id = tonumber(id)
  194. if not id then return sampAddChatMessage('Подсказка: /shotlog [ID]', 0xAFAFAF) end
  195. if not pool[id] then return sampAddChatMessage('Лог выстрелов указанного игрока пуст.', 0xAFAFAF) end
  196. show_stats(id)
  197. end)
  198. sampRegisterChatCommand('shotspec', function (id)
  199. if shotspec then
  200. shotspec = false
  201. return sampAddChatMessage('Режим shotspec выключен.', 0xAFAFAF)
  202. end
  203. id = tonumber(id)
  204. if not id then return sampAddChatMessage('Подсказка: /shotspec [ID]', 0xAFAFAF) end
  205. shotspec = true
  206. shotspec_id = id
  207. sampAddChatMessage('Режим shotspec включен.', 0xAFAFAF)
  208. end)
  209. while true do
  210. wait(1)
  211. local res, btn, item = sampHasDialogRespond(5556)
  212. if res and btn == 1 then show_stats(pids[item + 1], true) end
  213. local res2, btn2 = sampHasDialogRespond(5555)
  214. if res2 and arrow_shown and btn2 == 1 then show_list() end
  215. end
  216. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement