Advertisement
Jak92

Untitled

Aug 8th, 2020
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.98 KB | None | 0 0
  1. /*
  2. Hey you! You are reading my code!
  3. I want to say that my code is far from perfect, and if you see that I'm doing something
  4. in a really wrong/dumb way, please give me advices instead of saying "LOL U BAD CODER"
  5. Thanks
  6. - MadJawa
  7. */
  8.  
  9. LaserLib = LaserLib or {};
  10.  
  11.  
  12. //////////////////////////////
  13. //// Shared Functions ////
  14. //////////////////////////////
  15.  
  16. function LaserLib.GetReflectedVector( incidentVector, surfaceNormal )
  17.  
  18. return incidentVector - 2 * ( surfaceNormal:DotProduct( incidentVector ) * surfaceNormal );
  19.  
  20. end
  21.  
  22. function LaserLib.DoBeam ( laserEnt, beamDir, beamStart, beamLength, ... )
  23. local trace = {};
  24.  
  25. local beamStart = util.LocalToWorld(laserEnt, beamStart);
  26.  
  27. laserEnt.IgnoreList = laserEnt.IgnoreList or {};
  28. local beamFilter = table.Copy(laserEnt.IgnoreList);
  29. table.insert(beamFilter, laserEnt);
  30.  
  31. if ( SERVER ) then
  32. inflictor = laserEnt.ply;
  33. beamDamage = unpack(arg);
  34. laserEnt.Targets = {}; -- we'll store here what we hit
  35. end
  36.  
  37. if ( CLIENT ) then
  38. beamPoints = { beamStart };
  39. beamIgnore = {};
  40. beamWidth, beamMaterial = unpack(arg);
  41. end
  42.  
  43. local bounces = 0;
  44.  
  45. repeat
  46. if ( StarGate ~= nil ) then
  47. trace = StarGate.Trace:New( beamStart, beamDir:Normalize() * beamLength, beamFilter );
  48. else
  49. trace = util.QuickTrace( beamStart, beamDir:Normalize() * beamLength, beamFilter );
  50. end
  51.  
  52. if ( CLIENT ) then table.insert( beamPoints, trace.HitPos ); end
  53.  
  54. -- we can bounce!
  55. if ( trace.Entity and trace.Entity:IsValid() and
  56. ( ( (trace.Entity:GetClass() == "event_horizon" and ValidEntity(trace.Entity.Target)
  57. and trace.Entity:GetForward():DotProduct(trace.Normal) < 0 and trace.Entity ~= trace.Entity.Target)
  58. or trace.Entity:GetModel() == "models/madjawa/laser_reflector.mdl"
  59. or trace.Entity:GetMaterial() == "debug/env_cubemap_model" )
  60. and trace.Entity:GetClass() ~= "gmod_laser_crystal" ) ) then
  61.  
  62. isMirror = true;
  63.  
  64. beamFilter = table.Copy(laserEnt.IgnoreList);
  65. table.insert(beamFilter, trace.Entity);
  66. if (trace.Entity:GetClass() == "event_horizon") then
  67. if (not (CLIENT and not trace.Entity.DrawRipple) // HAX
  68. and not (SERVER and (not trace.Entity:IsOpen() or trace.Entity.ShuttingDown))) then -- STARGATE!
  69. beamStart, beamDir = trace.Entity:GetTeleportedVector(trace.HitPos, beamDir);
  70. if (CLIENT) then
  71. local n = table.insert( beamPoints, beamStart );
  72. beamIgnore[n] = true; -- prevents from rendering a beam between the two stargates
  73. end
  74. table.insert(beamFilter, trace.Entity.Target);
  75. if (SERVER) then
  76. trace.Entity:EnterEffect(trace.HitPos, laserEnt:GetBeamWidth());
  77. trace.Entity.Target:EnterEffect(beamStart, laserEnt:GetBeamWidth());
  78. end
  79. else isMirror = false;
  80. end
  81. else
  82. beamStart = trace.HitPos;
  83. beamDir = LaserLib.GetReflectedVector( beamDir, trace.HitNormal );
  84. end
  85. beamLength = beamLength - beamLength * trace.Fraction;
  86.  
  87. elseif (SERVER and ValidEntity(trace.Entity) and trace.Entity:GetClass() == "event_horizon") then
  88. trace.Entity:EnterEffect(trace.HitPos, laserEnt:GetBeamWidth());
  89. else
  90. isMirror = false;
  91. end
  92.  
  93. bounces = bounces + 1;
  94.  
  95. if ( SERVER ) then
  96. if ( ValidEntity(trace.Entity) and
  97. ( trace.Entity:GetClass() == "gmod_laser_reflector" or trace.Entity:GetClass() == "gmod_laser_crystal" )
  98. and not table.HasValue( trace.Entity.Hits, laserEnt ) ) then
  99. trace.Entity:UpdateBounceCount(laserEnt);
  100. end
  101. end
  102.  
  103. if (SERVER and ValidEntity(trace.Entity)) then table.insert(laserEnt.Targets, trace.Entity); end
  104.  
  105. until ( isMirror == false or bounces > GetConVar("laser_maxbounces"):GetInt() )
  106.  
  107. if( SERVER and beamDamage > 0 and trace.Entity and trace.Entity:IsValid() and trace.Entity:GetClass() ~= "gmod_laser_crystal" and
  108. trace.Entity:GetClass() ~= "gmod_laser" and trace.Entity:GetModel() ~= "models/madjawa/laser_reflector.mdl" ) then
  109.  
  110. LaserLib.DoDamage( trace.Entity, trace.HitPos, trace.Normal, beamDir, beamDamage, inflictor,
  111. laserEnt:GetDissolveType(), laserEnt:GetPushProps(), laserEnt:GetKillSound(), laserEnt );
  112.  
  113. end
  114.  
  115. if ( CLIENT ) then
  116. --Fucking FIXME: weird bugs/shadows/laser disappearing seem to caused by renderbounds
  117. local prevPoint = beamPoints[1];
  118. local bbmin, bbmax = laserEnt:GetRenderBounds();
  119.  
  120. if not matTab or not matTab[beamMaterial] then
  121. matTab[beamMaterial] = Material(beamMaterial);
  122. end
  123. render.SetMaterial( matTab[beamMaterial] );
  124.  
  125. for k, v in pairs ( beamPoints ) do
  126. if ( prevPoint ~= v and not beamIgnore[k]==true) then
  127. render.DrawBeam( prevPoint, v, beamWidth, 13*CurTime(), 13*CurTime() - ( v - prevPoint ):Length()/9, Color( 255, 255, 255, 255 ) );
  128. end
  129. prevPoint = v;
  130.  
  131. local pos = laserEnt:WorldToLocal(v);
  132. if ( pos.x < bbmin.x ) then bbmin.x = pos.x; end
  133. if ( pos.y < bbmin.y ) then bbmin.y = pos.y; end
  134. if ( pos.z < bbmin.z ) then bbmin.z = pos.z; end
  135. if ( pos.x > bbmax.x ) then bbmax.x = pos.x; end
  136. if ( pos.y > bbmax.y ) then bbmax.y = pos.y; end
  137. if ( pos.z > bbmax.z ) then bbmax.z = pos.z; end
  138. end
  139.  
  140. laserEnt.NextEffect = laserEnt.NextEffect or CurTime();
  141. if ( not trace.HitSky and laserEnt:GetEndingEffect() and CurTime() >= laserEnt.NextEffect ) then
  142. if ( trace.Entity and trace.Entity:IsValid() and trace.Entity:GetClass() == "gmod_laser_crystal" ) then return; end
  143.  
  144. if not (trace.Entity:IsValid() and trace.Entity:GetClass() == "event_horizon") then
  145. local effectdata = EffectData();
  146. effectdata:SetStart( trace.HitPos );
  147. effectdata:SetOrigin( trace.HitPos );
  148. effectdata:SetNormal( trace.HitNormal );
  149. effectdata:SetScale( 1 );
  150. util.Effect( "AR2Impact", effectdata );
  151. end
  152. laserEnt.NextEffect = CurTime() + 0.1;
  153. end
  154.  
  155. laserEnt:SetRenderBounds( bbmin, bbmax, Vector()*6 );
  156. end
  157.  
  158. return trace.Entity;
  159. end
  160.  
  161.  
  162. //////////////////////////////
  163. //// Server Functions ////
  164. //////////////////////////////
  165.  
  166. if ( SERVER ) then
  167.  
  168. AddCSLuaFile( "autorun/laserlib.lua" );
  169.  
  170. function LaserLib.SpawnDissolver( ent, position, attacker, dissolveType )
  171. Dissolver = ents.Create( "env_entity_dissolver" );
  172. Dissolver.Target = "laserdissolve"..ent:EntIndex();
  173. Dissolver:SetKeyValue( "dissolvetype", dissolveType );
  174. Dissolver:SetKeyValue( "magnitude", 0 );
  175. Dissolver:SetPos( position );
  176. Dissolver:SetPhysicsAttacker( attacker );
  177. Dissolver:Spawn();
  178.  
  179. return Dissolver;
  180. end
  181.  
  182. function LaserLib.DoDamage( target, hitPos, normal, beamDir, damage, attacker, dissolveType, pushProps, killSound, laserEnt )
  183.  
  184. laserEnt.NextLaserDamage = laserEnt.NextLaserDamage or CurTime();
  185.  
  186. if ( pushProps and target:GetPhysicsObject():IsValid() ) then
  187. local phys = target:GetPhysicsObject();
  188. local mass = phys:GetMass();
  189. local mul = math.Clamp( mass * 10, 0, 2000 );
  190. if ( mul ~= 0 and mass <= 500 ) then
  191. phys:ApplyForceOffset( beamDir * mul, hitPos );
  192. end
  193. end
  194.  
  195. if ( target:GetClass() == "weapon_striderbuster" ) then return end;
  196.  
  197. if ( CurTime() >= laserEnt.NextLaserDamage ) then
  198. if ( target:IsVehicle() and target:GetDriver():IsValid() ) then -- we must kill the driver!
  199. target = target:GetDriver();
  200. target:Kill(); -- takedamage doesn't seem to work on a player inside a vehicle
  201. end
  202.  
  203. if ( target:GetClass() == "shield" ) then
  204. target:Hit( laserEnt, hitPos, math.Clamp( damage / 2500 * 3, 0, 4), -1*normal );
  205. laserEnt.NextLaserDamage = CurTime() + 0.3;
  206. return; -- we stop here because we hit a shield
  207. end
  208.  
  209. if ( target:Health() <= damage ) then
  210. if ( target:IsNPC() or target:IsPlayer() ) then
  211. local dissolverEnt = LaserLib.SpawnDissolver( laserEnt, target:GetPos(), attacker, dissolveType );
  212.  
  213. -- dissolving the NPC's weapon too
  214. if ( target:IsNPC() and target:GetActiveWeapon():IsValid() ) then target:GetActiveWeapon():SetName( dissolverEnt.Target ); end
  215.  
  216. target:TakeDamage( damage, attacker, laserEnt ); -- we kill the player/NPC to get his ragdoll
  217.  
  218. if ( target:IsPlayer() ) then
  219. if ( not target:GetRagdollEntity() or not target:GetRagdollEntity():IsValid() ) then return; end
  220. target:GetRagdollEntity():SetName( dissolverEnt.Target ); -- thanks to Nevec for the player ragdoll idea, allowing us to dissolve him the cleanest way
  221. else
  222. if ( target.DeathRagdoll and target.DeathRagdoll:IsValid() ) then -- if Keep Corpses is disabled, DeathRagdoll is nil, so we need to check this
  223. target.DeathRagdoll:SetName( dissolverEnt.Target );
  224. else
  225. target:SetName( dissolverEnt.Target );
  226. end
  227. end
  228.  
  229. dissolverEnt:Fire( "Dissolve", dissolverEnt.Target, 0 );
  230. dissolverEnt:Fire( "Kill", "", 0.1 );
  231. dissolverEnt:Remove(); -- Makes sure it's removed. It MIGHT prevent the "no free edicts" error (I don't see what other entity could cause it right now)
  232. end
  233.  
  234. if ( killSound ~= nil and ( target:Health() ~= 0 or target:IsPlayer() ) ) then
  235. WorldSound( Sound( killSound ), target:GetPos() );
  236. target:EmitSound( Sound( killSound ) );
  237. end
  238. else
  239. laserEnt.NextLaserDamage = CurTime() + 0.3;
  240. end
  241.  
  242. target:TakeDamage( damage, attacker, laserEnt );
  243. end
  244. end
  245.  
  246. function LaserLib.AssignNPCRagdoll( entity, ragdoll )
  247. -- it seems that's the only clean way to get the NPC's ragdoll in the DoDamage function -- Thanks to Kogitsune
  248. entity.DeathRagdoll = ragdoll;
  249. end
  250.  
  251. hook.Add( "CreateEntityRagdoll", "LaserLib.AssignNPCRagdoll", LaserLib.AssignNPCRagdoll );
  252.  
  253. end
  254.  
  255.  
  256. //////////////////////////////
  257. //// Client Functions ////
  258. //////////////////////////////
  259.  
  260. if ( CLIENT ) then
  261. matTab = matTab or {};
  262.  
  263. function LaserLib.UpdateIgnoreList(um)
  264. local laserEnt = ents.GetByIndex(um:ReadLong());
  265. local nbEnt = um:ReadLong();
  266.  
  267. laserEnt.IgnoreList = {};
  268. for i=1, nbEnt do
  269. table.insert(laserEnt.IgnoreList, ents.GetByIndex(um:ReadLong()));
  270. end
  271. end
  272. usermessage.Hook("Laser.UpdateIgnoreList", LaserLib.UpdateIgnoreList)
  273. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement