Advertisement
Guest User

Untitled

a guest
Feb 17th, 2020
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.96 KB | None | 0 0
  1. --[[
  2. When an object has a different entrance and exit surface material, the damage lost is calculated using the average resistance of the two.
  3.  
  4. penmod: How easy it is for a bullet to go through the material (0.001 to 1.0).
  5. dmgmod: How much of the damaging power of the bullet is preserved while going through the material (0.001 to 1.0).
  6. ]]
  7.  
  8. local mat_translation = {
  9. [MAT_CONCRETE] = {
  10. name = "concrete",
  11. penmod = 0.5,
  12. dmgmod = 0.25
  13. },
  14. [MAT_DIRT] = {
  15. name = "dirt",
  16. penmod = 0.6,
  17. dmgmod = 0.3
  18. },
  19. [MAT_EGGSHELL] = "The egg sacs in the antlion tunnels in HL2: EP2",
  20. [MAT_FLESH] = {
  21. name = "flesh",
  22. penmod = 0.9,
  23. dmgmod = 0.5
  24. },
  25. [MAT_GRATE] = {
  26. name = "grate",
  27. penmod = 0.95,
  28. dmgmod = 0.99
  29. },
  30. [MAT_CLIP] = "Unused",
  31. [MAT_SNOW] = {
  32. name = "snow",
  33. penmod = 0.85,
  34. dmgmod = 0.5
  35. },
  36. [MAT_PLASTIC] = {
  37. name = "plastic",
  38. penmod = 0.3,
  39. dmgmod = 0.25
  40. },
  41. [MAT_METAL] = {
  42. name = "metal",
  43. penmod = 0.4,
  44. dmgmod = 0.3
  45. },
  46. [MAT_SAND] = {
  47. name = "sand",
  48. penmod = 0.3,
  49. dmgmod = 0.25
  50. },
  51. [MAT_FOLIAGE] = {
  52. name = "foliage",
  53. penmod = 0.95,
  54. dmgmod = 0.5
  55. },
  56. [MAT_COMPUTER] = {
  57. name = "computer",
  58. penmod = 0.4,
  59. dmgmod = 0.45
  60. },
  61. [MAT_SLOSH] = {
  62. name = "Water, slime",
  63. penmod = 0.3
  64. },
  65. [MAT_TILE] = {
  66. name = "tile",
  67. penmod = 0.7,
  68. dmgmod = 0.3
  69. },
  70. [MAT_VENT] = {
  71. name = "vent",
  72. penmod = 0.6,
  73. dmgmod = 0.45
  74. },
  75. [MAT_WOOD] = {
  76. name = "wood",
  77. penmod = 0.9,
  78. dmgmod = 0.6
  79. },
  80. [MAT_DEFAULT] = {
  81. name = "default",
  82. penmod = 1.0,
  83. dmgmod = 0.5
  84. },
  85. [MAT_GLASS] = {
  86. name = "glass",
  87. penmod = 0.99,
  88. dmgmod = 0.5
  89. },
  90. [MAT_WARPSHIELD] = "\"wierd-looking jello effect for advisor shield.\"",
  91. }
  92. mat_translation[MAT_GRASS] = table.Copy(mat_translation[MAT_DIRT])
  93. mat_translation[MAT_GRASS].name = "grass"
  94. mat_translation[MAT_ALIENFLESH] = table.Copy(mat_translation[MAT_FLESH])
  95. mat_translation[MAT_ALIENFLESH].name = "alien flesh"
  96. mat_translation[MAT_BLOODYFLESH] = table.Copy(mat_translation[MAT_FLESH])
  97. mat_translation[MAT_BLOODYFLESH].name = "bloody flesh"
  98. mat_translation[MAT_ANTLION] = table.Copy(mat_translation[MAT_FLESH])
  99. mat_translation[MAT_ANTLION].name = "antlion"
  100.  
  101. local function calc_lost_damage(wep, enter_trace, exit_trace, currentDamage)
  102. local enter_data = mat_translation[enter_trace.MatType] or mat_translation[MAT_DEFAULT]
  103. local exit_data = mat_translation[exit_trace.MatType] or mat_translation[MAT_DEFAULT]
  104.  
  105. local is_solid_surf = bit.band(bit.rshift(enter_trace.Contents, 3), CONTENTS_SOLID) ~= 0
  106. local is_light_surf = bit.band(bit.rshift(enter_trace.SurfaceFlags, 7), SURF_LIGHT) ~= 0
  107.  
  108. local thickness, modifier, lostDamage, finalDamageModifier, combinedPenetrationModifier
  109.  
  110. if enter_trace.MatType == MAT_GLASS or enter_trace.MatType == MAT_GRATE then
  111. combinedPenetrationModifier = 3
  112. finalDamageModifier = .05
  113. elseif is_solid_surf or is_light_surf then
  114. combinedPenetrationModifier = 1
  115. finalDamageModifier = .16
  116. else
  117. combinedPenetrationModifier = (enter_data.penmod + exit_data.penmod) / 2
  118. finalDamageModifier = .16
  119. end
  120.  
  121. if enter_trace.MatType == exit_trace.MatType then
  122. if enter_trace.MatType == MAT_DIRT or enter_trace.MatType == MAT_WOOD then
  123. combinedPenetrationModifier = 3
  124. elseif enter_trace.MatType == MAT_PLASTIC then
  125. combinedPenetrationModifier = 2
  126. end
  127. end
  128.  
  129. thickness = (exit_trace.HitPos - enter_trace.HitPos):LengthSqr()
  130. modifier = math.max(1 / combinedPenetrationModifier, 0)
  131.  
  132. local penetrationPower = wep.PenetrationPower or 1
  133. lostDamage = math.max(
  134. ((modifier * thickness) / 24)
  135. + ((currentDamage * finalDamageModifier)
  136. + (math.max(3.75 / penetrationPower, 0) * 3 * modifier)), 0)
  137.  
  138. if lostDamage > currentDamage then
  139. return currentDamage
  140. end
  141.  
  142. return lostDamage
  143. end
  144.  
  145. function SWEP:BulletCallback(atk, tr, dmg, pens)
  146. if CLIENT and not IsFirstTimePredicted() then return end
  147.  
  148. local impacts = sv_showimpacts:GetInt()
  149. local penetrations = sv_showimpacts_penetration:GetInt()
  150. pens = pens or 0
  151.  
  152. if impacts == 1 or (CLIENT and impacts == 2) or (SERVER and impacts == 3) then
  153. debugoverlay.Box(tr.HitPos, Vector(1,1,1), -Vector(1,1,1), sv_showimpacts_time:GetFloat(), CLIENT and Color(255,0,0,128) or Color(0,0,255,128))
  154. end
  155.  
  156. local mat = mat_translation[tr.MatType] or mat_translation[MAT_DEFAULT]
  157. if SERVER and penetrations ~= 0 then
  158. local nice_dist = util.NiceMetric(util.HUtoCM(tr.HitPos:Distance(tr.StartPos)))
  159.  
  160. debugoverlay.EntityTextAtPosition(tr.HitPos, -2, mat.name, sv_showimpacts_time:GetFloat(), Color(0,255,0, 64))
  161. debugoverlay.EntityTextAtPosition(tr.HitPos, 0, "^", sv_showimpacts_time:GetFloat(), Color(255, 154, 0, 64))
  162.  
  163. if penetrations == 2 then
  164. debugoverlay.EntityTextAtPosition(tr.HitPos, 1, dmg:GetDamage(), sv_showimpacts_time:GetFloat(), Color(255,0,0))
  165. debugoverlay.EntityTextAtPosition(tr.HitPos, 2, nice_dist, sv_showimpacts_time:GetFloat(), Color(255, 129, 62))
  166. else
  167. debugoverlay.EntityTextAtPosition(tr.HitPos, 1, string.format("DAMAGE APPLIED: %d", dmg:GetDamage()), sv_showimpacts_time:GetFloat(), Color(255,0,0))
  168. debugoverlay.EntityTextAtPosition(tr.HitPos, 2, string.format("TOTAL DISTANCE: %s", nice_dist), sv_showimpacts_time:GetFloat(), Color(255, 129, 62))
  169. end
  170. end
  171.  
  172. if pens > 3 then return end
  173. if tr.HitSky then return end
  174.  
  175. -- Bullet Penetration
  176. local dir = tr.Normal
  177. local back_tr
  178.  
  179. local filter = not tr.Entity:IsWorld() and tr.Entity or nil
  180. for i = 1, 1000 do
  181. local new_tr = util.TraceLine({
  182. endpos = tr.HitPos,
  183. start = tr.HitPos + dir * i,
  184. --filter = filter
  185. })
  186.  
  187. --print(new_tr.Entity, new_tr.HitNoDraw, new_tr.StartSolid, not (new_tr.HitNoDraw or new_tr.StartSolid))
  188.  
  189. if not (new_tr.HitNoDraw or new_tr.StartSolid) then
  190. --print("found back_tr", new_tr.Entity)
  191. back_tr = new_tr
  192. break
  193. end
  194. end
  195.  
  196. if not back_tr then return end
  197. local back_mat = mat_translation[back_tr.MatType] or mat_translation[MAT_DEFAULT]
  198.  
  199. local original_damage = dmg:GetDamage()
  200. local dmg_lost = calc_lost_damage(self, tr, back_tr, original_damage)
  201. dmg:SetDamage(original_damage - dmg_lost)
  202.  
  203. if dmg:GetDamage() <= 0 then
  204. --print("STOPPED!")
  205. return
  206. end
  207.  
  208. if SERVER and penetrations ~= 0 then
  209. local nice_dist = util.NiceMetric(util.HUtoCM(tr.HitPos:Distance(back_tr.StartPos)))
  210.  
  211. debugoverlay.Line(tr.HitPos, back_tr.StartPos, sv_showimpacts_time:GetFloat(), Color(16,192,192), true)
  212.  
  213. if penetrations == 2 then
  214. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -3, nice_dist, sv_showimpacts_time:GetFloat(), Color(255,128,128))
  215. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -2, string.format("%d", dmg:GetDamage() - original_damage), sv_showimpacts_time:GetFloat(), Color(255,0,0, 64))
  216. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -1, back_mat.name, sv_showimpacts_time:GetFloat(), Color(32,128,196, 64))
  217. else
  218. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -3, string.format("THICKNESS: %s", nice_dist), sv_showimpacts_time:GetFloat(), Color(255,128,128))
  219. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -2, string.format("LOST DAMAGE: %d", original_damage - dmg:GetDamage()), sv_showimpacts_time:GetFloat(), Color(255,0,0, 64))
  220. debugoverlay.EntityTextAtPosition(back_tr.HitPos, -1, back_mat.name, sv_showimpacts_time:GetFloat(), Color(32,128,196, 64))
  221. end
  222. end
  223.  
  224. local data = EffectData()
  225. data:SetOrigin(back_tr.HitPos)
  226. data:SetStart(back_tr.StartPos)
  227. data:SetSurfaceProp(back_tr.SurfaceProps)
  228. data:SetDamageType(dmg:GetDamageType())
  229. data:SetHitBox(back_tr.HitBox)
  230. data:SetEntity(back_tr.Entity)
  231.  
  232. if SERVER or (CLIENT and IsFirstTimePredicted()) then
  233. util.Effect("Impact", data, not game.SinglePlayer())
  234. end
  235.  
  236. self:FireBullets({
  237. Src = back_tr.HitPos,
  238. Dir = dir,
  239. Num = 1,
  240. AmmoType = self.Primary.Ammo,
  241. Tracer = 0,
  242. Attacker = self:GetOwner(),
  243. Spread = vector_origin,
  244. Damage = dmg:GetDamage(),
  245. Distance = self.BulletDistance,
  246. Callback = function(atk, tr, dmg) self:BulletCallback(atk, tr, dmg, pens + 1) end
  247. })
  248. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement