Advertisement
Guest User

LUA Lag Compensation Version 0.4

a guest
Nov 19th, 2010
263
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.07 KB | None | 0 0
  1. --LUA Lag Compensation version 0.4 by FlooD
  2. --thx to Jermuk for his custom server, which first encouraged me to make lag compensation.
  3. --thx to lasthope and def3ct for initial testing.
  4. --thx to 3rr0r for ideas and suggestions for refining the code.
  5.  
  6. BUFFER_SIZE = 25
  7. frame = 0
  8.  
  9. buffer = {}
  10. buffer[1] = {} --x buffer
  11. buffer[2] = {} --y buffer
  12.  
  13. function clearbuffer(id)
  14.     buffer[1][id] = {}
  15.     buffer[2][id] = {}
  16. end
  17.  
  18. for i = 1, 32 do
  19.     clearbuffer(i)
  20. end
  21.  
  22. addhook("leave", "clearbuffer")
  23. addhook("die", "clearbuffer")
  24.  
  25. addhook("always", "updatebuffer")
  26. function updatebuffer()
  27.     frame = frame + 1
  28.     for i = 1, 32 do
  29.         buffer[1][i][frame], buffer[2][i][frame] = player(i, "x"), player(i, "y")
  30.         buffer[1][i][frame - BUFFER_SIZE], buffer[2][i][frame - BUFFER_SIZE] = nil, nil
  31.     end
  32. end
  33.  
  34. addhook("hit", "onhit")
  35. function onhit(v,id,wpn)
  36.     if wpn ~= 51 then
  37.         return 1
  38.     end
  39. end
  40.  
  41. addhook("attack", "onattack")
  42. function onattack(id)
  43.     local wpn = player(id, "weapon")
  44.     if wpn == 51 then
  45.         return
  46.     end
  47.     simulate_attack(id, wpn)
  48. end
  49.  
  50. addhook("attack2", "onattack2")
  51. function onattack2(id, mode)
  52.     local wpn = player(id, "weapon")
  53.     if wpn == 50 then
  54.         simulate_attack(id, wpn, itemtype(wpn, "dmg_z1") * game("mp_damagefactor"))
  55.     end
  56. end
  57.  
  58. --[[simulates the shooting of a bullet of damage (dmg) from (wpn) by (id) with
  59. angle (rot). it has two parts. part 1 finds bullet's path before hitting
  60. a wall; part 2 calculates hits on other players (with lag compensation).]]
  61. function simulate_attack(id, wpn, dmg, rot, range)
  62.     if not wpn then wpn = player(id, "weapon") end
  63.     if not dmg then dmg = itemtype(wpn, "dmg") * game("mp_damagefactor") end
  64.     if not rot then rot = player(id, "rot") end
  65.     if not range then range = itemtype(wpn, "range") end
  66.  
  67.     local start_x = player(id, "x")
  68.     local start_y = player(id, "y")
  69.     local end_x = start_x + (3 * range) * math.sin(math.rad(rot))
  70.     local end_y = start_y - (3 * range) * math.cos(math.rad(rot))
  71.     local tile_x = math.floor(start_x / 32)
  72.     local tile_y = math.floor(start_y / 32)
  73.  
  74.     --part 1 - find the intersection of the bullet with the first wall it hits.
  75.     local inc_x, inc_y
  76.  
  77.     if rot < 0 then
  78.         inc_x = -1
  79.     elseif rot > 0 and rot ~= 180 then
  80.         inc_x = 1
  81.     end
  82.  
  83.     if math.abs(rot) > 90 then
  84.         inc_y = 1
  85.     elseif math.abs(rot) < 90 then
  86.         inc_y = -1
  87.     end
  88.  
  89.     while not tile(tile_x, tile_y, "wall") do
  90.         local temp_x, temp_y = tile_x, tile_y
  91.         if inc_x and intersect(start_x, start_y, end_x, end_y, topixel(temp_x + inc_x), topixel(temp_y), 32) then
  92.             tile_x = temp_x + inc_x
  93.         end
  94.         if inc_y and intersect(start_x, start_y, end_x, end_y, topixel(temp_x), topixel(temp_y + inc_y), 32) then
  95.             tile_y = temp_y + inc_y
  96.         end
  97.         if tile_x == temp_x and tile_y == temp_y then
  98.             break
  99.         end
  100.     end
  101.  
  102.     end_x, end_y = intersect(start_x, start_y, end_x, end_y, topixel(tile_x), topixel(tile_y), 32)
  103.     --part 2 - detect hits
  104.     local frames = math.floor(player(id, "ping") / 20)
  105.     if frames > (BUFFER_SIZE - 1) then
  106.         frames = (BUFFER_SIZE - 1)
  107.     end
  108.  
  109.     local alive = player(0, "tableliving")
  110.     for _, v in ipairs(alive) do
  111.         if ((game("sv_friendlyfire") == 1) or (player(v, "team") ~= player(id, "team"))) and (v ~= id) and intersect(start_x, start_y, end_x, end_y, buffer[1][v][frame - frames], buffer[2][v][frame - frames], 24) then
  112.             local newarmor = player(v, "armor") - dmg
  113.             if newarmor < 0 then
  114.                 newarmor = 0
  115.             end
  116.             local newhealth = player(v, "health") - (dmg - math.floor(game("mp_kevlar") * (player(v, "armor") - newarmor)))
  117.             if newhealth > 0 then
  118.                 parse("sethealth "..v.." "..newhealth)
  119.                 parse("setarmor "..v.." "..newarmor)
  120.             else
  121.                 parse("customkill "..id.." "..itemtype(wpn, "name").." "..v)
  122.             end
  123.         end
  124.     end
  125. end
  126.  
  127. --the following three functions are used in simulate_attack.
  128.  
  129. --converts a tile number to the tile's center pixel.
  130. function topixel(tile)
  131.     return (tile * 32) + 16
  132. end
  133.  
  134. --quick test to see if i is in between s and e. used in intersect().
  135. function isinorder(s, i, e)
  136.     return (e >= i and i >= s) or (e <= i and i <= s)
  137. end
  138.  
  139. --[[returns the first point of intersection between a box centered at (bx, by) with
  140. side length (bl) and a line segment starting from (sx, sy) and ending at (ex, ey).
  141. if the line segment is enclosed by the box, (ex, ey) is returned.]]
  142. function intersect(sx, sy, ex, ey, bx, by, bl)
  143.     bl = bl / 2
  144.  
  145.     if math.abs(sx - bx) <= bl and math.abs(sy - by) <= bl then
  146.         if math.abs(ex - bx) <= bl and math.abs(ey - by) <= bl then
  147.             return ex, ey
  148.         else
  149.             return intersect(ex, ey, sx, sy, bx, by, bl)
  150.         end
  151.     end
  152.  
  153.     local i_x, i_y
  154.  
  155.     if ey > sy then
  156.         i_y = by - bl
  157.     elseif ey < sy then
  158.         i_y = by + bl
  159.     end
  160.     if i_y and isinorder(sy, i_y, ey) then
  161.         i_x = ((ex - sx) * i_y + (sx * ey - sy * ex)) / (ey - sy)
  162.         if math.abs(i_x - bx) <= bl and isinorder(sx, i_x, ex) then
  163.             return i_x, i_y
  164.         end
  165.     end
  166.  
  167.     if ex > sx then
  168.         i_x = bx - bl
  169.     elseif ex < sx then
  170.         i_x = bx + bl
  171.     end
  172.     if i_x and isinorder(sx, i_x, ex) then
  173.         i_y = ((ey - sy) * i_x + (sy * ex - sx * ey)) / (ex - sx)
  174.         if math.abs(i_y - by) <= bl and isinorder(sy, i_y, ey) then
  175.             return i_x, i_y
  176.         end
  177.     end
  178. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement