Advertisement
Guest User

Untitled

a guest
Nov 17th, 2019
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.05 KB | None | 0 0
  1. AddCSLuaFile()
  2.  
  3. DEFINE_BASECLASS( "base_anim" )
  4.  
  5. ENT.Spawnable = false
  6. ENT.DisableDuplicator = true
  7.  
  8. ENT.RenderGroup = RENDERGROUP_BOTH
  9.  
  10. local snd = false
  11.  
  12. if ( IsMounted( "ep2" ) ) then
  13.  
  14. snd = true
  15.  
  16. util.PrecacheSound( "npc/ministrider/flechette_impact_stick1.wav" )
  17. util.PrecacheSound( "npc/ministrider/flechette_impact_stick2.wav" )
  18. util.PrecacheSound( "npc/ministrider/flechette_impact_stick3.wav" )
  19. util.PrecacheSound( "npc/ministrider/flechette_impact_stick4.wav" )
  20. util.PrecacheSound( "npc/ministrider/flechette_impact_stick5.wav" )
  21.  
  22. else
  23.  
  24. util.PrecacheSound( "physics/metal/sawblade_stick1.wav" )
  25. util.PrecacheSound( "physics/metal/sawblade_stick2.wav" )
  26. util.PrecacheSound( "physics/metal/sawblade_stick3.wav" )
  27.  
  28. end
  29.  
  30. util.PrecacheSound( "ambient/machines/zap1.wav" )
  31. util.PrecacheSound( "ambient/machines/zap2.wav" )
  32. util.PrecacheSound( "ambient/machines/zap3.wav" )
  33.  
  34. util.PrecacheModel( "models/weapons/w_hexshield_grenade.mdl" )
  35.  
  36. ENT.Hexshield_NoTarget = true
  37.  
  38. function ENT:SetupDataTables()
  39.  
  40. self:NetworkVar( "Entity", 0, "Shield" )
  41. self:NetworkVar( "Entity", 1, "SurfaceEntity" )
  42. self:NetworkVar( "Bool", 0, "IsAttached" )
  43.  
  44. self:NetworkVar( "Vector", 0, "ShieldPos" )
  45. self:NetworkVar( "Angle", 0, "ShieldAng" )
  46.  
  47. self:NetworkVar( "Vector", 1, "ShieldColor" )
  48.  
  49. end
  50.  
  51. if ( SERVER ) then
  52.  
  53. function ENT:Initialize()
  54.  
  55. self.Events = {}
  56.  
  57. self:SetModel( "models/weapons/w_hexshield_grenade.mdl" )
  58. self:PhysicsInit( SOLID_VPHYSICS )
  59. self:SetCollisionGroup( COLLISION_GROUP_WEAPON )
  60.  
  61. local physobj = self:GetPhysicsObject()
  62.  
  63. if ( IsValid( physobj ) ) then
  64.  
  65. physobj:SetDamping( 0, 0 )
  66.  
  67. end
  68.  
  69. local shield_color = self:GetShieldColor()
  70. shield_color = Color( shield_color.x, shield_color.y, shield_color.z )
  71.  
  72. self.Trail_top = util.SpriteTrail( self, self:LookupAttachment( "top" ), shield_color, true, 2, 0, 0.25, 0.5, "effects/beam_generic01.vmt" )
  73. self.Trail_bottom = util.SpriteTrail( self, self:LookupAttachment( "bottom" ), shield_color, true, 2, 0, 0.25, 0.5, "effects/beam_generic01.vmt" )
  74.  
  75. self.TestCollisions = true
  76.  
  77. end
  78.  
  79. local target_ent = NULL
  80. local target_rank = 1
  81. local target_dist = 64
  82. local target_pos = vector_origin
  83.  
  84. function ENT:GetEntityPos_Static( ent, selfpos, HitPos, HitNormal )
  85.  
  86. if ( not IsValid( ent ) ) or ( ent.Hexshield_NoTarget ) or ( ent:IsWeapon() ) or ( ( ent:GetSolid() == SOLID_NONE ) and ( ent:GetMoveType() == MOVETYPE_NONE ) ) then return end
  87.  
  88. local min, max = ent:GetCollisionBounds()
  89.  
  90. if ( min == max ) then return end
  91.  
  92. local width = min:Distance( max )
  93.  
  94. if ( width > 128 ) then return end
  95.  
  96. min:Add( max )
  97. min:Mul( 0.5 )
  98.  
  99. local center = ent:LocalToWorld( min )
  100. local dist = center:Distance( selfpos )
  101.  
  102. if ( dist > 64 ) then return end
  103.  
  104. local normal = center - HitPos
  105. normal:Normalize()
  106.  
  107. if ( HitNormal:Dot( normal ) <= 0 ) then return end
  108.  
  109. local rank = 1
  110.  
  111. if ( ent:IsPlayer() ) then
  112. rank = 3
  113. elseif ( ent:IsNPC() ) then
  114. rank = 2
  115. elseif ( width < 16 ) then
  116. return
  117. end
  118.  
  119. if ( rank > target_rank ) or ( ( rank == target_rank ) and ( dist < target_dist ) ) then
  120.  
  121. target_ent = ent
  122. target_rank = rank
  123. target_dist = dist
  124. target_pos = center
  125.  
  126. end
  127.  
  128. end
  129.  
  130. function ENT:GetEntityPos_Dynamic( ent, selfpos )
  131.  
  132. if ( not IsValid( ent ) ) or ( ent.Hexshield_NoTarget ) or ( ent:IsWeapon() ) or ( ( ent:GetSolid() == SOLID_NONE ) and ( ent:GetMoveType() == MOVETYPE_NONE ) ) then return end
  133.  
  134. local min, max = ent:GetCollisionBounds()
  135.  
  136. if ( min == max ) then return end
  137.  
  138. local width = min:Distance( max )
  139.  
  140. if ( width > 128 ) then return end
  141.  
  142. min:Add( max )
  143. min:Mul( 0.5 )
  144.  
  145. local center = ent:LocalToWorld( min )
  146. local dist = center:Distance( selfpos )
  147.  
  148. if ( dist > 64 ) then return end
  149.  
  150. local rank = 1
  151.  
  152. if ( ent:IsPlayer() ) then
  153. rank = 3
  154. elseif ( ent:IsNPC() ) then
  155. rank = 2
  156. elseif ( width < 16 ) then
  157. return
  158. end
  159.  
  160. if ( rank > target_rank ) or ( ( rank == target_rank ) and ( dist < target_dist ) ) then
  161.  
  162. target_ent = ent
  163. target_rank = rank
  164. target_dist = dist
  165. target_pos = center
  166.  
  167. end
  168.  
  169. end
  170.  
  171. function ENT:FindEntityAndGetPos_Static( selfpos, selfang )
  172.  
  173. local HitPos, HitAng = LocalToWorld( self.HitPos, self.HitAng, selfpos, selfang )
  174. local HitNormal = HitAng:Forward()
  175.  
  176. target_ent = self
  177. target_rank = 1
  178. target_dist = 64
  179. target_pos = selfpos
  180.  
  181. for k, ent in pairs( ents.GetAll() ) do
  182.  
  183. self:GetEntityPos_Static( ent, selfpos, HitPos, HitNormal )
  184.  
  185. end
  186.  
  187. if ( target_ent == self ) then
  188.  
  189. HitNormal:Mul( 36.410477 )
  190. HitPos:Add( HitNormal )
  191.  
  192. return HitPos
  193.  
  194. end
  195.  
  196. return target_pos
  197.  
  198. end
  199.  
  200. function ENT:FindEntityAndGetPos_Dynamic( selfpos, selfang )
  201.  
  202. target_ent = self
  203. target_rank = 1
  204. target_dist = 64
  205. target_pos = selfpos
  206.  
  207. for k, ent in pairs( ents.GetAll() ) do
  208.  
  209. self:GetEntityPos_Dynamic( ent, selfpos )
  210.  
  211. end
  212.  
  213. if ( target_ent == self ) then
  214.  
  215. local HitPos, HitAng = LocalToWorld( self.HitPos, self.HitAng, selfpos, selfang )
  216. local HitNormal = HitAng:Forward()
  217.  
  218. HitNormal:Mul( 36.410477 )
  219. HitPos:Add( HitNormal )
  220.  
  221. return HitPos
  222.  
  223. end
  224.  
  225. return target_pos
  226.  
  227. end
  228.  
  229. function ENT:FindEntityAndGetPos( selfpos, selfang )
  230.  
  231. local ent = self:GetSurfaceEntity()
  232.  
  233. if ( IsValid( ent ) ) then
  234.  
  235. local min, max = ent:GetCollisionBounds()
  236.  
  237. if ( min ~= max ) and ( min:Distance( max ) <= 128 ) then
  238.  
  239. return self:FindEntityAndGetPos_Dynamic( selfpos, selfang )
  240.  
  241. end
  242.  
  243. end
  244.  
  245. return self:FindEntityAndGetPos_Static( selfpos, selfang )
  246.  
  247. end
  248.  
  249. local function GetPhysicsObjectIndex( self ) -- WHY DOES THIS FUNCTION NOT EXIST????
  250.  
  251. local ent = self:GetEntity()
  252.  
  253. if ( IsValid( ent ) ) then
  254.  
  255. for i = 0, ent:GetPhysicsObjectCount() - 1 do
  256.  
  257. if ( ent:GetPhysicsObjectNum( i ) == self ) then return i end
  258.  
  259. end
  260.  
  261. end
  262.  
  263. return 0
  264.  
  265. end
  266.  
  267. function ENT:PhysicsCollide( data, physobj )
  268.  
  269. if ( not self.TestCollisions ) then return end
  270.  
  271. if ( data.Speed < 64 ) then return end
  272.  
  273. if ( HEXSHIELD_MYCLASS( data.HitEntity ) ) then return end
  274.  
  275. if ( data.HitEntity:IsNPC() or data.HitEntity:IsPlayer() ) and ( data.HitEntity:GetSolid() ~= SOLID_VPHYSICS ) and ( data.HitEntity:GetMoveType() ~= MOVETYPE_VPHYSICS ) then return end
  276.  
  277. self.TestCollisions = false
  278.  
  279. data.HitBone = GetPhysicsObjectIndex( data.HitObject )
  280. self.CollisionData = data
  281. self.Events[ 1 ] = self.Collided
  282.  
  283. end
  284.  
  285. function ENT:Weld( ent, bone )
  286.  
  287. return constraint.Weld( self, ent, 0, bone, 4095, true, false )
  288.  
  289. end
  290.  
  291. local function hexshield_weld( self )
  292.  
  293. local ent = self.HexshieldGrenade
  294.  
  295. if ( IsValid( ent ) ) then ent:WeldRemoved() end
  296.  
  297. end
  298.  
  299. function ENT:WeldCreated( Constraint )
  300.  
  301. self:SetIsAttached( true )
  302.  
  303. Constraint.HexshieldGrenade = self
  304.  
  305. Constraint:CallOnRemove( "hexshield_weld", hexshield_weld )
  306.  
  307. end
  308.  
  309. local removeeffect = EffectData()
  310. removeeffect:SetMagnitude( 1 )
  311. removeeffect:SetScale( 1 )
  312. removeeffect:SetRadius( 1 )
  313.  
  314. function ENT:WeldRemoved()
  315.  
  316. self:SetIsAttached( false )
  317.  
  318. if ( self.DisableWeld ) then return end
  319.  
  320. local HitPos, HitAng = LocalToWorld( self.HitPos, self.HitAng, self:GetPos(), self:GetAngles() )
  321.  
  322. sound.Play( "ambient/machines/zap"..math.random( 1, 3 )..".wav", HitPos, 75, 125, 0.25 )
  323.  
  324. removeeffect:SetOrigin( HitPos )
  325. removeeffect:SetNormal( HitAng:Forward() )
  326. util.Effect( "ManhackSparks", removeeffect )
  327.  
  328. end
  329.  
  330. function ENT:AttachEntity( selfpos, selfang, data )
  331.  
  332. local ent = data.HitEntity
  333.  
  334. if ( IsValid( ent ) ) then
  335.  
  336. self:SetSurfaceEntity( ent )
  337.  
  338. if ( ent:GetMoveType() == MOVETYPE_VPHYSICS ) then
  339.  
  340. local Constraint = self:Weld( ent, data.HitBone )
  341.  
  342. if ( Constraint ) and ( Constraint:IsValid() ) then
  343.  
  344. self:WeldCreated( Constraint )
  345.  
  346. return
  347.  
  348. end
  349.  
  350. end
  351.  
  352. local follow = ents.Create( "hexshield_move_attach" ) -- I need to figure out a way to make an entity follow a specific physics object.
  353. follow:SetMoveType( MOVETYPE_NONE )
  354. follow:SetPos( selfpos )
  355. follow:SetAngles( selfang )
  356. follow:SetParent( ent )
  357. follow:Spawn()
  358.  
  359. local anchor = ents.Create( "hexshield_move_anchor" )
  360. anchor:SetPos( selfpos )
  361. anchor:SetAngles( selfang )
  362. anchor:Spawn()
  363.  
  364. follow:DeleteOnRemove( anchor )
  365. anchor:DeleteOnRemove( follow )
  366.  
  367. follow:SetTargetEntity( anchor )
  368.  
  369. local Constraint = self:Weld( anchor, 0 )
  370.  
  371. if ( Constraint ) and ( Constraint:IsValid() ) then
  372.  
  373. Constraint:DeleteOnRemove( anchor )
  374.  
  375. self:WeldCreated( Constraint )
  376.  
  377. else
  378.  
  379. anchor:Remove()
  380.  
  381. end
  382.  
  383. elseif ( ent:IsWorld() ) then
  384.  
  385. self:SetSurfaceEntity( ent )
  386.  
  387. local anchor = ents.Create( "hexshield_move_anchor" )
  388. anchor:SetPos( selfpos )
  389. anchor:SetAngles( selfang )
  390. anchor:Spawn()
  391.  
  392. local Constraint = self:Weld( anchor, 0 )
  393.  
  394. if ( Constraint ) and ( Constraint:IsValid() ) then
  395.  
  396. Constraint:DeleteOnRemove( anchor )
  397.  
  398. self:WeldCreated( Constraint )
  399.  
  400. else
  401.  
  402. anchor:Remove()
  403.  
  404. end
  405.  
  406. end
  407.  
  408. end
  409.  
  410. function ENT:Collided()
  411.  
  412. local data = self.CollisionData
  413.  
  414. self:SetCollisionGroup( COLLISION_GROUP_WORLD )
  415.  
  416. local physobj = self:GetPhysicsObject()
  417.  
  418. if ( IsValid( physobj ) ) then
  419.  
  420. physobj:SetDamping( 15, 15 )
  421.  
  422. end
  423.  
  424. local selfpos = self:GetPos()
  425. local selfang = self:GetAngles()
  426.  
  427. local detect = ents.Create( "hexshield_move_detect" )
  428. detect:SetMoveType( MOVETYPE_NONE )
  429. detect:SetPos( selfpos )
  430. detect:SetAngles( selfang )
  431. detect:SetParent( self )
  432. detect:Spawn()
  433. detect:DeleteOnRemove( self )
  434.  
  435. self:AttachEntity( selfpos, selfang, data )
  436.  
  437. self.DeployTime = CurTime() + 0.8
  438.  
  439. self.Events[ 1 ] = self.Event_Deploy
  440.  
  441. data.HitNormal:Mul( -1 )
  442.  
  443. self.HitPos, self.HitAng = WorldToLocal( data.HitPos, data.HitNormal:Angle(), selfpos, selfang )
  444.  
  445. if ( snd ) then
  446. sound.Play( "npc/ministrider/flechette_impact_stick"..math.random( 1, 5 )..".wav", data.HitPos, 75, 100, 1.0 )
  447. else
  448. sound.Play( "physics/metal/sawblade_stick"..math.random( 1, 3 )..".wav", data.HitPos, 75, 100, 1.0 )
  449. end
  450. sound.Play( "ambient/machines/zap"..math.random( 1, 3 )..".wav", data.HitPos, 75, 125, 0.25 )
  451.  
  452. end
  453.  
  454. util.AddNetworkString( "hexshield_grenade_drawfunc" )
  455.  
  456. function ENT:Event_Deploy()
  457.  
  458. if ( CurTime() < self.DeployTime ) then return end
  459.  
  460. self.ExpireTime = CurTime() + 32
  461.  
  462. self.Events[ 1 ] = self.Event_Expire
  463.  
  464. net.Start( "hexshield_grenade_drawfunc" )
  465. net.WriteEntity( self )
  466. net.WriteInt( 2, 3 )
  467. net.Broadcast()
  468.  
  469. local selfpos = self:GetPos()
  470. local selfang = self:GetAngles()
  471.  
  472. local pos = self:FindEntityAndGetPos( selfpos, selfang )
  473. local lpos, lang = WorldToLocal( pos, angle_zero, selfpos, selfang )
  474. self:SetShieldPos( lpos )
  475. self:SetShieldAng( lang )
  476.  
  477. local ent = ents.Create( "hexshield" )
  478. ent:SetPos( pos )
  479. ent:SetAngles( angle_zero )
  480. ent:SetShieldColor( self:GetShieldColor() )
  481. ent:Spawn()
  482.  
  483. ent:SetGenerator( self )
  484.  
  485. self:SetShield( ent )
  486.  
  487. ent:Deploy()
  488.  
  489. self.ShieldActive = true
  490.  
  491. end
  492.  
  493. function ENT:Expire()
  494.  
  495. self.PickupTime = CurTime() + 0.5
  496.  
  497. self.Events[ 1 ] = self.Event_Pickup
  498.  
  499. local physobj = self:GetPhysicsObject()
  500.  
  501. if ( IsValid( physobj ) ) then
  502.  
  503. physobj:SetDamping( 0, 0 )
  504.  
  505. end
  506.  
  507. if ( IsValid( self.Trail_top ) ) then self.Trail_top:Remove() end
  508. if ( IsValid( self.Trail_bottom ) ) then self.Trail_bottom:Remove() end
  509.  
  510. net.Start( "hexshield_grenade_drawfunc" )
  511. net.WriteEntity( self )
  512. net.WriteInt( 3, 3 )
  513. net.Broadcast()
  514.  
  515. end
  516.  
  517. function ENT:Event_Expire()
  518.  
  519. local ent = self:GetShield()
  520.  
  521. if ( IsValid( ent ) ) then
  522.  
  523. if ( CurTime() < self.ExpireTime ) then return end
  524.  
  525. self:Expire()
  526.  
  527. ent:Expire()
  528.  
  529. self.ShieldActive = false
  530.  
  531. else
  532.  
  533. self:Expire()
  534.  
  535. self.ShieldActive = false
  536.  
  537. end
  538.  
  539. end
  540.  
  541. function ENT:Event_Pickup()
  542.  
  543. if ( CurTime() < self.PickupTime ) then return end
  544.  
  545. self.Events[ 1 ] = nil
  546.  
  547. self.DisableWeld = true
  548.  
  549. local wep = ents.Create( "weapon_hexshield" )
  550. wep:SetPos( self:GetPos() )
  551. wep:SetAngles( self:GetAngles() )
  552. wep:Spawn()
  553. wep:Activate()
  554.  
  555. self:Remove()
  556.  
  557. end
  558.  
  559. function ENT:OnTick()
  560.  
  561. for k, Event in pairs( self.Events ) do Event( self ) end
  562.  
  563. end
  564.  
  565. hook.Add( "Tick", "hexshield_grenade", function()
  566.  
  567. for k, ent in pairs( ents.FindByClass( "hexshield_grenade" ) ) do ent:OnTick() end
  568.  
  569. end )
  570.  
  571. end
  572.  
  573. if ( CLIENT ) then
  574.  
  575. function ENT:Initialize()
  576.  
  577. self.DrawFuncs = {
  578. self.DrawNormal,
  579. self.DrawDeployed,
  580. self.DrawExpired
  581. }
  582.  
  583. self.DrawTranslucent = self.DrawNormal
  584.  
  585. end
  586.  
  587. net.Receive( "hexshield_grenade_drawfunc", function( l )
  588.  
  589. local ent = net.ReadEntity()
  590. local i = net.ReadInt( 3 )
  591.  
  592. if ( not IsValid( ent ) ) then return end
  593.  
  594. ent.DrawTranslucent = ent.DrawFuncs[ i ] or ent.DrawTranslucent
  595.  
  596. end )
  597.  
  598. local refract = Material( "effects/hexshield/hexshield_r1" )
  599. local spritemat = Material( "sprites/light_ignorez" )
  600.  
  601. function ENT:Draw()
  602.  
  603. self:DrawModel()
  604.  
  605. end
  606.  
  607. function ENT:DrawNormal()
  608.  
  609. local shield_color = self:GetShieldColor()
  610. shield_color = Color( shield_color.x, shield_color.y, shield_color.z )
  611.  
  612. self:Draw()
  613.  
  614. local posang = self:GetAttachment( self:LookupAttachment( "top" ) )
  615. local t_pos = posang.Pos
  616. posang = self:GetAttachment( self:LookupAttachment( "bottom" ) )
  617. local b_pos = posang.Pos
  618.  
  619. render.SetMaterial( spritemat )
  620. render.DrawSprite( t_pos, 4, 4, shield_color )
  621.  
  622. render.SetMaterial( spritemat )
  623. render.DrawSprite( b_pos, 4, 4, shield_color )
  624.  
  625. end
  626.  
  627. function ENT:DrawDeployed()
  628.  
  629. local shield_color = self:GetShieldColor()
  630. shield_color = Color( shield_color.x, shield_color.y, shield_color.z )
  631.  
  632. self:Draw()
  633.  
  634. local posang = self:GetAttachment( self:LookupAttachment( "top" ) )
  635. local t_pos = posang.Pos
  636. posang = self:GetAttachment( self:LookupAttachment( "bottom" ) )
  637. local b_pos = posang.Pos
  638.  
  639. local t = CurTime()
  640.  
  641. local i = ( math.sin( t * 8 ) + 1 ) + ( ( math.sin( t * 4 ) + 1 ) * 2 )
  642.  
  643. refract:SetFloat( "$refractamount", i * 0.003 )
  644.  
  645. local size = ( i + 32 ) * 0.25
  646.  
  647. render.UpdateRefractTexture()
  648.  
  649. render.SetMaterial( refract )
  650. render.DrawSprite( t_pos, size, size, color_white )
  651. render.DrawSprite( b_pos, size, size, color_white )
  652.  
  653. render.SetMaterial( spritemat )
  654. render.DrawSprite( t_pos, size, size, shield_color )
  655. render.DrawSprite( b_pos, size, size, shield_color )
  656.  
  657. end
  658.  
  659. function ENT:DrawExpired()
  660.  
  661. self:Draw()
  662.  
  663. end
  664.  
  665. end
  666.  
  667. function ENT:On_CalcAbsolutePosition( selfpos, selfang )
  668.  
  669. local ent = self:GetShield()
  670.  
  671. if ( not IsValid( ent ) ) then return end
  672.  
  673. local pos, ang = LocalToWorld( self:GetShieldPos(), self:GetShieldAng(), selfpos, selfang )
  674. ang.p, ang.r = 0, 0
  675.  
  676. ent:SetNetworkOrigin( pos )
  677. ent:SetAngles( ang )
  678. ent:SetAbsVelocity( self:GetVelocity() )
  679.  
  680. if ( SERVER ) then
  681.  
  682. local physobj = ent:GetPhysicsObject()
  683.  
  684. if ( IsValid( physobj ) ) then
  685.  
  686. physobj:SetPos( pos )
  687. physobj:SetAngles( ang )
  688. physobj:Wake()
  689.  
  690. end
  691.  
  692. end
  693.  
  694. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement