Guest User

Untitled

a guest
Aug 9th, 2015
213
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. AddCSLuaFile()
  3.  
  4. if ( SERVER ) then
  5. util.AddNetworkString( "rb655_holdtype" )
  6. resource.AddWorkshop( "111412589" )
  7. CreateConVar( "rb655_lightsaber_infinite", "0" )
  8. end
  9.  
  10. SWEP.PrintName = "Lightsaber"
  11. SWEP.Author = "Robotboy655"
  12. SWEP.Category = "Robotboy655's Weapons"
  13. SWEP.Contact = "robotboy655@gmail.com"
  14. SWEP.Purpose = "To slice off each others limbs and heads."
  15. SWEP.Instructions = "Use the force, Luke."
  16. SWEP.RenderGroup = RENDERGROUP_BOTH
  17.  
  18. SWEP.Slot = 0
  19. SWEP.SlotPos = 4
  20.  
  21. SWEP.Spawnable = true
  22. SWEP.DrawAmmo = false
  23. SWEP.DrawCrosshair = false
  24. SWEP.AutoSwitchTo = false
  25. SWEP.AutoSwitchFrom = false
  26. SWEP.DrawWeaponInfoBox = false
  27.  
  28. SWEP.ViewModel = "models/weapons/v_crowbar.mdl"
  29. SWEP.WorldModel = "models/sgg/starwars/weapons/w_anakin_ep2_saber_hilt.mdl"
  30. SWEP.ViewModelFOV = 55
  31.  
  32. SWEP.Primary.ClipSize = -1
  33. SWEP.Primary.DefaultClip = -1
  34. SWEP.Primary.Automatic = false
  35. SWEP.Primary.Ammo = "none"
  36.  
  37. SWEP.Secondary.ClipSize = -1
  38. SWEP.Secondary.DefaultClip = -1
  39. SWEP.Secondary.Automatic = true
  40. SWEP.Secondary.Ammo = "none"
  41.  
  42. // We have NPC support, but it SUCKS
  43. //list.Add( "NPCUsableWeapons", { class = "weapon_lightsaber", title = SWEP.PrintName } )
  44.  
  45. /* --------------------------------------------------------- Helper functions --------------------------------------------------------- */
  46.  
  47. function SWEP:PlayWeaponSound( snd )
  48. if ( CLIENT ) then return end
  49. self.Owner:EmitSound( snd )
  50. end
  51.  
  52. function SWEP:SelectTargets( num )
  53. local t = {}
  54. local dist = 512
  55.  
  56. local tr = util.TraceLine( {
  57. start = self.Owner:GetShootPos(),
  58. endpos = self.Owner:GetShootPos() + self.Owner:GetAimVector() * dist,
  59. filter = self.Owner
  60. } )
  61.  
  62. local p = {}
  63. for id, ply in pairs( ents.GetAll() ) do
  64. if ( !ply:GetModel() or ply:GetModel() == "" or ply == self.Owner or ply:Health() < 1 ) then continue end
  65. if ( string.StartWith( ply:GetModel() or "", "models/gibs/" ) ) then continue end
  66. if ( string.find( ply:GetModel() or "", "chunk" ) ) then continue end
  67. if ( string.find( ply:GetModel() or "", "_shard" ) ) then continue end
  68. if ( string.find( ply:GetModel() or "", "_splinters" ) ) then continue end
  69.  
  70. local tr = util.TraceLine( {
  71. start = self.Owner:GetShootPos(),
  72. endpos = (ply.GetShootPos && ply:GetShootPos() or ply:GetPos()),
  73. filter = self.Owner,
  74. } )
  75.  
  76. if ( tr.Entity != ply && IsValid( tr.Entity ) || tr.Entity == game.GetWorld() ) then continue end
  77.  
  78. local pos1 = self.Owner:GetPos() + self.Owner:GetAimVector() * dist
  79. local pos2 = ply:GetPos()
  80. local dot = self.Owner:GetAimVector():Dot( ( self.Owner:GetPos() - pos2 ):GetNormalized() )
  81.  
  82. if ( pos1:Distance( pos2 ) <= dist && ply:EntIndex() > 0 && ply:GetModel() && ply:GetModel() != "" ) then
  83. table.insert( p, { ply = ply, dist = tr.HitPos:Distance( pos2 ), dot = dot, score = -dot + ( ( dist - pos1:Distance( pos2 ) ) / dist ) * 50 } )
  84. end
  85. end
  86.  
  87. local d = {}
  88. for id, ply in SortedPairsByMemberValue( p, "dist" ) do
  89. table.insert( t, ply.ply )
  90. if ( #t >= num ) then return t end
  91. end
  92.  
  93. return t
  94. end
  95.  
  96. /* --------------------------------------------------------- Force Powers --------------------------------------------------------- */
  97.  
  98. if ( SERVER ) then
  99. concommand.Add( "rb655_select_force", function( ply, cmd, args )
  100. if ( !IsValid( ply ) || !IsValid( ply:GetActiveWeapon() ) || ply:GetActiveWeapon():GetClass() != "weapon_lightsaber" || !tonumber( args[ 1 ]) ) then return end
  101.  
  102. local wep = ply:GetActiveWeapon()
  103. local typ = math.Clamp( tonumber( args[ 1 ]), 1, #wep.ForcePowers )
  104. wep:SetForceType( typ )
  105. end )
  106. end
  107.  
  108. hook.Add( "GetFallDamage", "rb655_lightsaber_no_fall_damage", function( ply, speed )
  109. if ( IsValid( ply ) && IsValid( ply:GetActiveWeapon() ) && ply:GetActiveWeapon():GetClass() == "weapon_lightsaber" ) then
  110. local wep = ply:GetActiveWeapon()
  111.  
  112. if ( ply:KeyDown( IN_DUCK ) ) then
  113. ply:SetNWFloat( "SWL_FeatherFall", CurTime() ) -- Hate on me for NWVars!
  114. wep:SetNextAttack( 0.5 )
  115. ply:ViewPunch( Angle( speed / 32, 0, math.random( -speed, speed ) / 128 ) )
  116. return 0
  117. end
  118. end
  119. end )
  120.  
  121. function SWEP:OnRestore()
  122. self.Owner:SetNWFloat( "SWL_FeatherFall", 0 )
  123. end
  124.  
  125. hook.Add( "CreateMove", "rb655_lightsaber_no_fall_damage", function( cmd/* ply, mv, cmd*/ )
  126. if ( CurTime() - LocalPlayer():GetNWFloat( "SWL_FeatherFall", CurTime() - 2 ) < 1 ) then
  127. cmd:ClearButtons() -- No attacking, we are busy
  128. cmd:ClearMovement() -- No moving, we are busy
  129. cmd:SetButtons( IN_DUCK ) -- Force them to crouch
  130. end
  131. end )
  132.  
  133. hook.Add( "EntityTakeDamage", "rb655_sabers_armor", function( victim, dmg )
  134. local ply = victim
  135. if ( !ply.GetActiveWeapon || !ply:IsPlayer() ) then return end
  136. local wep = ply:GetActiveWeapon()
  137. if ( !IsValid( wep ) || wep:GetClass() != "weapon_lightsaber" || wep.ForcePowers[ wep:GetForceType() ].name != "Force Absorb" ) then return end
  138. if ( !ply:KeyDown( IN_ATTACK2 ) /*|| !ply:IsOnGround()*/ ) then return end
  139.  
  140. local damage = dmg:GetDamage() / 5
  141. local force = wep:GetForce()
  142. if ( force < damage ) then
  143. wep:SetForce( 0 )
  144. dmg:SetDamage( (damage - force) * 5 )
  145. return
  146. end
  147. wep:SetForce( force - damage )
  148. dmg:SetDamage( 0 )
  149. end )
  150.  
  151. function SWEP:SetNextAttack( delay )
  152. self:SetNextPrimaryFire( CurTime() + delay )
  153. self:SetNextSecondaryFire( CurTime() + delay )
  154. end
  155.  
  156. function SWEP:ForceJumpAnim()
  157. self.Owner.m_bJumping = true
  158.  
  159. self.Owner.m_bFirstJumpFrame = true
  160. self.Owner.m_flJumpStartTime = CurTime()
  161.  
  162. self.Owner:AnimRestartMainSequence()
  163. end
  164.  
  165. SWEP.ForcePowers = { {
  166. name = "Force Leap",
  167. icon = "L",
  168. description = "Jump longer and higher.\nAim higher to jump higher/further.\nHold CTRL to negate fall damage, but stop moving for 1 sec",
  169. action = function( self )
  170. if ( self:GetForce() < 10 || !self.Owner:IsOnGround() || CLIENT ) then return end
  171. self:SetForce( self:GetForce() - 10 )
  172.  
  173. self:SetNextAttack( 0.5 )
  174.  
  175. self.Owner:SetVelocity( self.Owner:GetAimVector() * 512 + Vector( 0, 0, 512 ) )
  176.  
  177. self:PlayWeaponSound( "lightsaber/ForceLeap.wav" )
  178.  
  179. // Trigger the jump animation, yay
  180. self:CallOnClient( "ForceJumpAnim", "" )
  181. end
  182. }, {
  183. name = "Force Absorb",
  184. icon = "A",
  185. description = "Hold Mouse 2 to protect yourself from harm",
  186. action = function( self )
  187. if ( self:GetForce() < 1/* || !self.Owner:IsOnGround()*/ || CLIENT ) then return end
  188. self:SetForce( self:GetForce() - 0.1 )
  189.  
  190. self:SetNextAttack( 0.3 )
  191. end
  192. }, {
  193. name = "Force Repulse",
  194. icon = "R",
  195. description = "Hold to charge for greater distance/damage.\nKill everybody close to you.\nPush back everybody who is a bit farther away but still close enough.",
  196. think = function( self )
  197. if ( self:GetNextSecondaryFire() > CurTime() ) then return end
  198. if ( self:GetForce() < 1 || CLIENT ) then return end
  199. if ( !self.Owner:KeyDown( IN_ATTACK2 ) && !self.Owner:KeyReleased( IN_ATTACK2 ) ) then return end
  200. if ( !self._ForceRepulse && self:GetForce() < 16 ) then return end
  201.  
  202. if ( !self.Owner:KeyReleased( IN_ATTACK2 ) ) then
  203. if ( !self._ForceRepulse ) then self:SetForce( self:GetForce() - 16 ) self._ForceRepulse = 1 end
  204.  
  205. if ( !self.NextForceEffect || self.NextForceEffect < CurTime() ) then
  206. local ed = EffectData()
  207. ed:SetOrigin( self.Owner:GetPos() + Vector( 0, 0, 36 ) )
  208. ed:SetRadius( 128 * self._ForceRepulse )
  209. util.Effect( "rb655_force_repulse_in", ed, true, true )
  210.  
  211. self.NextForceEffect = CurTime() + math.Clamp( self._ForceRepulse / 20, 0.1, 0.5 )
  212. end
  213.  
  214. self._ForceRepulse = self._ForceRepulse + 0.025
  215. self:SetForce( self:GetForce() - 0.5 )
  216. if ( self:GetForce() > 0.99 ) then return end
  217. else
  218. if ( !self._ForceRepulse ) then return end
  219. end
  220.  
  221. local maxdist = 128 * self._ForceRepulse
  222.  
  223. for i, e in pairs( ents.FindInSphere( self.Owner:GetPos(), maxdist ) ) do
  224. if ( e == self.Owner ) then continue end
  225.  
  226. local dist = self.Owner:GetPos():Distance( e:GetPos() )
  227. local mul = ( maxdist - dist ) / 256
  228.  
  229. local v = ( self.Owner:GetPos() - e:GetPos() ):GetNormalized()
  230. v.z = 0
  231.  
  232. if ( e:IsNPC() && util.IsValidRagdoll( e:GetModel() or "" ) ) then
  233.  
  234. local dmg = DamageInfo()
  235. dmg:SetDamagePosition( e:GetPos() + e:OBBCenter() )
  236. dmg:SetDamage( 48 * mul )
  237. dmg:SetDamageType( DMG_GENERIC )
  238. if ( ( 1 - dist / maxdist ) > 0.8 ) then
  239. dmg:SetDamageType( DMG_DISSOLVE )
  240. dmg:SetDamage( e:Health() * 3 )
  241. end
  242. dmg:SetDamageForce( -v * math.min( mul * 40000, 80000 ) )
  243. dmg:SetInflictor( self.Owner )
  244. dmg:SetAttacker( self.Owner )
  245. e:TakeDamageInfo( dmg )
  246.  
  247. if ( e:IsOnGround() ) then
  248. e:SetVelocity( v * mul * -2048 + Vector( 0, 0, 64 ) )
  249. elseif ( !e:IsOnGround() ) then
  250. e:SetVelocity( v * mul * -1024 + Vector( 0, 0, 64 ) )
  251. end
  252.  
  253. elseif ( e:IsPlayer() && e:IsOnGround() ) then
  254. e:SetVelocity( v * mul * -2048 + Vector( 0, 0, 64 ) )
  255. elseif ( e:IsPlayer() && !e:IsOnGround() ) then
  256. e:SetVelocity( v * mul * -384 + Vector( 0, 0, 64 ) )
  257. elseif ( e:GetPhysicsObjectCount() > 0 ) then
  258. for i=0, e:GetPhysicsObjectCount() - 1 do
  259. e:GetPhysicsObjectNum( i ):ApplyForceCenter( v * mul * -512 * math.min( e:GetPhysicsObject():GetMass(), 256 ) + Vector( 0, 0, 64 ) )
  260. end
  261. end
  262. end
  263.  
  264. local ed = EffectData()
  265. ed:SetOrigin( self.Owner:GetPos() + Vector( 0, 0, 36 ) )
  266. ed:SetRadius( maxdist )
  267. util.Effect( "rb655_force_repulse_out", ed, true, true )
  268.  
  269. self._ForceRepulse = nil
  270.  
  271. self:SetNextAttack( 1 )
  272.  
  273. self:PlayWeaponSound( "lightsaber/ForceRepulse.wav" )
  274. end
  275. }, {
  276. name = "Force Heal",
  277. icon = "H",
  278. description = "Hold Mouse 2 to slowly heal yourself",
  279. action = function( self )
  280. if ( self:GetForce() < 1 /*|| !self.Owner:IsOnGround()*/ || self.Owner:Health() >= 100 || CLIENT ) then return end
  281. self:SetForce( self:GetForce() - 1 )
  282.  
  283. self:SetNextAttack( 0.2 )
  284.  
  285. local ed = EffectData()
  286. ed:SetOrigin( self.Owner:GetPos() )
  287. util.Effect( "rb655_force_heal", ed, true, true )
  288.  
  289. self.Owner:SetHealth( self.Owner:Health() + 1 )
  290. end
  291. }, {
  292. name = "Force Combust",
  293. icon = "C",
  294. target = 1,
  295. description = "Ignite stuff infront of you.",
  296. action = function( self )
  297. if ( self:GetForce() < 30 || CLIENT ) then return end
  298.  
  299. local ent = self:SelectTargets( 1 )[ 1 ]
  300.  
  301. if ( IsValid( ent ) && !ent:IsOnFire() ) then
  302. ent:Ignite( 60, 0 )
  303. self:SetForce( self:GetForce() - 30 )
  304. end
  305.  
  306. self:SetNextAttack( 1 )
  307. end
  308. }, {
  309. name = "Force Lighting",
  310. icon = "L",
  311. target = 3,
  312. description = "Torture people ( and monsters ) at will.",
  313. action = function( self )
  314. if ( self:GetForce() < 3 || CLIENT ) then return end
  315.  
  316. local foundents = 0
  317. for id, ent in pairs( self:SelectTargets( 3 ) ) do
  318. if ( !IsValid( ent ) ) then continue end
  319.  
  320. foundents = foundents + 1
  321. local ed = EffectData()
  322. ed:SetOrigin( self:GetSaberPosAng() )
  323. ed:SetEntity( ent )
  324. util.Effect( "rb655_force_lighting", ed, true, true )
  325.  
  326. local dmg = DamageInfo()
  327. dmg:SetAttacker( self.Owner or self )
  328. dmg:SetInflictor( self.Owner or self )
  329.  
  330. dmg:SetDamage( math.Clamp( 512 / self.Owner:GetPos():Distance( ent:GetPos() ), 1, 10 ) )
  331. if ( ent:IsNPC() ) then dmg:SetDamage( 4 ) end
  332. ent:TakeDamageInfo( dmg )
  333.  
  334. end
  335.  
  336. if ( foundents > 0 ) then
  337. self:SetForce( self:GetForce() - foundents )
  338. if ( !self.SoundLightning ) then
  339. self.SoundLightning = CreateSound( self.Owner, "lightsaber/ForceLightning" .. math.random( 1, 2 ) .. ".wav" )
  340. self.SoundLightning:Play()
  341. else
  342. self.SoundLightning:Play()
  343. end
  344.  
  345. timer.Create( "test", 0.2, 1, function() if ( self.SoundLightning ) then self.SoundLightning:Stop() self.SoundLightning = nil end end )
  346. end
  347. self:SetNextAttack( 0.1 )
  348. end
  349. }
  350. }
  351.  
  352. /* --------------------------------------------------------- Initialize --------------------------------------------------------- */
  353.  
  354. function SWEP:SetupDataTables()
  355. self:NetworkVar( "Float", 0, "BladeLength" )
  356. self:NetworkVar( "Float", 1, "MaxLength" )
  357. self:NetworkVar( "Float", 2, "BladeWidth" )
  358. self:NetworkVar( "Float", 3, "Force" )
  359.  
  360. self:NetworkVar( "Bool", 0, "DarkInner" )
  361. self:NetworkVar( "Bool", 1, "Enabled" )
  362. self:NetworkVar( "Int", 0, "ForceType" )
  363.  
  364. self:NetworkVar( "Vector", 0, "CrystalColor" )
  365. self:NetworkVar( "String", 1, "WorldModel" )
  366. self:NetworkVar( "String", 2, "OnSound" )
  367. self:NetworkVar( "String", 3, "OffSound" )
  368.  
  369. if ( SERVER ) then
  370. self:SetBladeLength( 0 )
  371. self:SetBladeWidth( 2 )
  372. self:SetMaxLength( 42 )
  373. self:SetDarkInner( false )
  374. self:SetEnabled( true )
  375.  
  376. self:SetOnSound( "lightsaber/SaberOn" .. math.random( 1, 2 ) .. ".wav" )
  377. self:SetOffSound( "lightsaber/SaberOff" .. math.random( 1, 2 ) .. ".wav" )
  378. self:SetWorldModel( "models/sgg/starwars/weapons/w_anakin_ep2_saber_hilt.mdl" )
  379. self:SetCrystalColor( Vector( math.random( 0, 255 ), math.random( 0, 255 ), math.random( 0, 255 ) ) )
  380. self:SetForceType( 1 )
  381. self:SetForce( 100 )
  382.  
  383. self:NetworkVarNotify( "Force", self.OnForceChanged )
  384. end
  385. end
  386.  
  387. function SWEP:Initialize()
  388. self.LoopSound = self.LoopSound or "lightsaber/SaberLoop" .. math.random( 1, 8 ) .. ".wav"
  389. self.SwingSound = self.SwingSound or "lightsaber/SaberSwing" .. math.random( 1, 2 ) .. ".wav"
  390.  
  391. self:SetWeaponHoldType( self:GetTargetHoldType() )
  392.  
  393. if ( self.Owner && self.Owner:IsNPC() && SERVER ) then // NPC Weapons
  394. self.Owner:Fire( "GagEnable" )
  395.  
  396. if self.Owner:GetClass() == "npc_citizen" then
  397. self.Weapon.Owner:Fire( "DisableWeaponPickup" )
  398. end
  399.  
  400. self.Weapon.Owner:SetKeyValue( "spawnflags", "256" )
  401.  
  402. hook.Add( "Think", self, self.NPCThink )
  403.  
  404. timer.Simple( 0.5, function()
  405. if ( !IsValid( self ) or !IsValid( self.Owner ) ) then return end
  406. self.Owner:SetCurrentWeaponProficiency( 4 )
  407. self.Owner:CapabilitiesAdd( CAP_FRIENDLY_DMG_IMMUNE )
  408. self.Owner:CapabilitiesRemove( CAP_WEAPON_MELEE_ATTACK1 )
  409. self.Owner:CapabilitiesRemove( CAP_INNATE_MELEE_ATTACK1 )
  410. end )
  411. end
  412. end
  413.  
  414. /* --------------------------------------------------------- NPC Weapons --------------------------------------------------------- */
  415.  
  416. function SWEP:SetupWeaponHoldTypeForAI( t )
  417. if ( !self.Owner:IsNPC() ) then return end
  418. self.ActivityTranslateAI = {}
  419.  
  420. self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE
  421. self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_MELEE
  422. self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE
  423. self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_ANGRY_MELEE
  424. self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_MELEE
  425. self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_ANGRY_MELEE
  426. self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_ANGRY_MELEE
  427. self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_ANGRY_MELEE
  428.  
  429. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_THROW
  430. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_MELEE_ATTACK_SWING
  431. self.ActivityTranslateAI[ ACT_MELEE_ATTACK1 ] = ACT_MELEE_ATTACK_SWING
  432. self.ActivityTranslateAI[ ACT_MELEE_ATTACK2 ] = ACT_MELEE_ATTACK_SWING
  433. self.ActivityTranslateAI[ ACT_SPECIAL_ATTACK1 ] = ACT_RANGE_ATTACK_THROW
  434.  
  435. self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_IDLE_ANGRY_MELEE
  436. self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_IDLE_ANGRY_MELEE
  437.  
  438. self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK
  439. self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK
  440. self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK
  441. self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK
  442.  
  443. self.ActivityTranslateAI[ ACT_RUN_CROUCH ] = ACT_RUN
  444. self.ActivityTranslateAI[ ACT_RUN_CROUCH_AIM ] = ACT_RUN
  445. self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN
  446. self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN
  447. self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN
  448. self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN
  449. self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN
  450. self.ActivityTranslateAI[ ACT_SMALL_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  451. self.ActivityTranslateAI[ ACT_BIG_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  452.  
  453. if ( self.Owner:GetClass() == "npc_metropolice" ) then
  454.  
  455. self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE
  456. self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_MELEE
  457. self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE
  458. self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE
  459. self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_MELEE
  460.  
  461. self.ActivityTranslateAI[ ACT_MP_RUN ] = ACT_HL2MP_RUN_SUITCASE
  462. self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_SUITCASE
  463. self.ActivityTranslateAI[ ACT_MELEE_ATTACK1 ] = ACT_MELEE_ATTACK_SWING
  464. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_MELEE_ATTACK_SWING
  465. self.ActivityTranslateAI[ ACT_SPECIAL_ATTACK1 ] = ACT_RANGE_ATTACK_THROW
  466. self.ActivityTranslateAI[ ACT_SMALL_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  467. self.ActivityTranslateAI[ ACT_BIG_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  468.  
  469. return end
  470.  
  471. if ( self.Owner:GetClass() == "npc_combine_s2" ) then
  472.  
  473. self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE
  474. self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_ANGRY_MELEE
  475. self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE
  476. self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_ANGRY_MELEE
  477. self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_ANGRY_MELEE
  478. self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_ANGRY_MELEE
  479. self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_ANGRY_MELEE
  480. self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_ANGRY_MELEE
  481.  
  482. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_RANGE_ATTACK_THROW
  483. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_MELEE_ATTACK_SWING
  484. self.ActivityTranslateAI[ ACT_MELEE_ATTACK1 ] = ACT_MELEE_ATTACK_SWING
  485. self.ActivityTranslateAI[ ACT_MELEE_ATTACK2 ] = ACT_MELEE_ATTACK_SWING
  486. self.ActivityTranslateAI[ ACT_SPECIAL_ATTACK1 ] = ACT_RANGE_ATTACK_THROW
  487.  
  488.  
  489. self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_IDLE_ANGRY_MELEE
  490. self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_IDLE_ANGRY_MELEE
  491.  
  492. self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK
  493. self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK
  494. self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK
  495. self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK
  496.  
  497. self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN
  498. self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN
  499. self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN
  500. self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN
  501. self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN
  502. self.ActivityTranslateAI[ ACT_SMALL_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  503. self.ActivityTranslateAI[ ACT_BIG_FLINCH ] = ACT_RANGE_ATTACK_PISTOL
  504.  
  505. return end
  506.  
  507. if ( self.Owner:GetClass() == "npc_combine_s" ) then
  508.  
  509. self.ActivityTranslateAI[ ACT_IDLE ] = ACT_IDLE_UNARMED
  510. self.ActivityTranslateAI[ ACT_IDLE_ANGRY ] = ACT_IDLE_SHOTGUN
  511. self.ActivityTranslateAI[ ACT_IDLE_RELAXED ] = ACT_IDLE_SHOTGUN
  512. self.ActivityTranslateAI[ ACT_IDLE_STIMULATED ] = ACT_IDLE_SHOTGUN
  513. self.ActivityTranslateAI[ ACT_IDLE_AGITATED ] = ACT_IDLE_SHOTGUN
  514. self.ActivityTranslateAI[ ACT_IDLE_AIM_RELAXED ] = ACT_IDLE_SHOTGUN
  515. self.ActivityTranslateAI[ ACT_IDLE_AIM_STIMULATED ] = ACT_IDLE_SHOTGUN
  516. self.ActivityTranslateAI[ ACT_IDLE_AIM_AGITATED ] = ACT_IDLE_SHOTGUN
  517.  
  518. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1 ] = ACT_MELEE_ATTACK1
  519. self.ActivityTranslateAI[ ACT_RANGE_ATTACK1_LOW ] = ACT_MELEE_ATTACK1
  520. self.ActivityTranslateAI[ ACT_MELEE_ATTACK1 ] = ACT_MELEE_ATTACK1
  521. self.ActivityTranslateAI[ ACT_MELEE_ATTACK2 ] = ACT_MELEE_ATTACK1
  522. self.ActivityTranslateAI[ ACT_SPECIAL_ATTACK1 ] = ACT_MELEE_ATTACK1
  523.  
  524. self.ActivityTranslateAI[ ACT_RANGE_AIM_LOW ] = ACT_IDLE_SHOTGUN
  525. self.ActivityTranslateAI[ ACT_COVER_LOW ] = ACT_IDLE_SHOTGUN
  526.  
  527. self.ActivityTranslateAI[ ACT_WALK ] = ACT_WALK_UNARMED
  528. self.ActivityTranslateAI[ ACT_WALK_RELAXED ] = ACT_WALK_UNARMED
  529. self.ActivityTranslateAI[ ACT_WALK_STIMULATED ] = ACT_WALK_UNARMED
  530. self.ActivityTranslateAI[ ACT_WALK_AGITATED ] = ACT_WALK_UNARMED
  531.  
  532. self.ActivityTranslateAI[ ACT_RUN ] = ACT_RUN_AIM_SHOTGUN
  533. self.ActivityTranslateAI[ ACT_RUN_AIM_RELAXED ] = ACT_RUN_AIM_SHOTGUN
  534. self.ActivityTranslateAI[ ACT_RUN_AIM_STIMULATED ] = ACT_RUN_AIM_SHOTGUN
  535. self.ActivityTranslateAI[ ACT_RUN_AIM_AGITATED ] = ACT_RUN_AIM_SHOTGUN
  536. self.ActivityTranslateAI[ ACT_RUN_AIM ] = ACT_RUN_AIM_SHOTGUN
  537.  
  538. return end
  539. end
  540.  
  541. function SWEP:GetCapabilities()
  542. return bit.bor( CAP_WEAPON_MELEE_ATTACK1 )
  543. end
  544.  
  545. function SWEP:NextFire()
  546. if ( !IsValid( self ) or !IsValid( self.Owner ) ) then return end
  547. if ( self.Owner:IsCurrentSchedule( SCHED_CHASE_ENEMY ) ) then return end
  548. self.NextFireTimer = true
  549. self:Chase_Enemy()
  550. timer.Simple( math.Rand( 0.6, 1 ), function()
  551. self.NextFireTimer = false
  552. end )
  553. end
  554.  
  555. function SWEP:Chase_Enemy()
  556. if ( !IsValid( self ) or !IsValid( self.Owner ) ) then return end
  557. if ( self.Owner:GetEnemy():GetPos():Distance( self:GetPos() ) > 70 ) then
  558. self.Owner:SetSchedule( SCHED_CHASE_ENEMY )
  559. end
  560.  
  561. if ( self.Owner:GetEnemy() == self.Owner ) then self.Owner:SetEnemy( NULL ) return end
  562. if ( !self.CooldownTimer && self.Owner:GetEnemy():GetPos():Distance( self:GetPos() ) <= 70 ) then
  563. self.Owner:SetSchedule( SCHED_MELEE_ATTACK1 )
  564. self:NPCShoot_Primary( ShootPos, ShootDir )
  565. end
  566. end
  567.  
  568. function SWEP:NPCThink()
  569. if ( !IsValid( self.Owner ) || !IsValid( self ) || !self.Owner:IsNPC() ) then return end
  570.  
  571. //self.Owner:RemoveAllDecals()
  572. self.Owner:ClearCondition( 13 )
  573. self.Owner:ClearCondition( 17 )
  574. self.Owner:ClearCondition( 18 )
  575. self.Owner:ClearCondition( 20 )
  576. self.Owner:ClearCondition( 48 )
  577. self.Owner:ClearCondition( 42 )
  578. self.Owner:ClearCondition( 45 )
  579.  
  580. if ( !self.NextFireTimer && IsValid( self.Owner:GetEnemy() ) ) then
  581. self:NextFire()
  582. end
  583.  
  584. self:Think()
  585. end
  586.  
  587. function SWEP:NPCShoot_Primary( ShootPos, ShootDir )
  588. if ( !IsValid( self ) or !IsValid( self.Owner ) ) then return end
  589. if ( !self.Owner:GetEnemy() ) then return end
  590.  
  591. self.CooldownTimer = true
  592. local seqtimer = 0.4
  593. if self.Owner:GetClass() == "npc_alyx" then
  594. seqtimer = 0.8
  595. end
  596.  
  597. timer.Simple( seqtimer, function()
  598. if ( !IsValid( self ) or !IsValid( self.Owner ) ) then return end
  599. if ( self.Owner:IsCurrentSchedule( SCHED_MELEE_ATTACK1 ) ) then
  600. //self:PrimaryAttack()
  601. end
  602. self.CooldownTimer = false
  603. end )
  604. end
  605.  
  606. /* --------------------------------------------------------- Attacks --------------------------------------------------------- */
  607.  
  608. function SWEP:PrimaryAttack()
  609. if ( !IsValid( self.Owner ) ) then return end
  610.  
  611. self:SetNextAttack( 0.5 )
  612.  
  613. if ( !self.Owner:IsNPC() ) then
  614. self.Owner:AnimResetGestureSlot( GESTURE_SLOT_CUSTOM )
  615. self.Owner:SetAnimation( PLAYER_ATTACK1 )
  616. end
  617. end
  618.  
  619. function SWEP:SecondaryAttack()
  620. if ( !IsValid( self.Owner ) ) then return end
  621.  
  622. if ( game.SinglePlayer() ) then self:CallOnClient( "SecondaryAttack", "" ) end
  623. if ( self.ForcePowers[ self:GetForceType() ]&& self.ForcePowers[ self:GetForceType() ].action ) then
  624. self.ForcePowers[ self:GetForceType() ].action( self )
  625. if ( GetConVarNumber( "rb655_lightsaber_infinite" ) != 0 ) then self:SetForce( 100 ) end
  626. end
  627. end
  628.  
  629. function SWEP:Reload()
  630. if ( !self.Owner:KeyPressed( IN_RELOAD ) ) then return end
  631.  
  632. if ( self:GetEnabled() ) then
  633. self:PlayWeaponSound( self:GetOffSound() )
  634.  
  635. -- Fancy extinguish animations?
  636. if ( self.Owner:WaterLevel() > 1 ) then self:SetHoldType( "knife" ) end
  637. timer.Create( "rb655_ls_ht", 0.4, 1, function() if ( IsValid( self ) ) then self:SetHoldType( "normal" ) end end )
  638.  
  639. if ( CLIENT ) then return end
  640.  
  641. if ( self.SoundLoop ) then self.SoundLoop:Stop() self.SoundLoop = nil end
  642. if ( self.SoundSwing ) then self.SoundSwing:Stop() self.SoundSwing = nil end
  643. if ( self.SoundHit ) then self.SoundHit:Stop() self.SoundHit = nil end
  644. else
  645. self:PlayWeaponSound( self:GetOnSound() )
  646. self:SetHoldType( self:GetTargetHoldType() )
  647. timer.Destroy( "rb655_ls_ht" )
  648.  
  649. if ( CLIENT ) then return end
  650.  
  651. self.SoundLoop = CreateSound( self.Owner, Sound( self.LoopSound ) )
  652. if ( self.SoundLoop ) then self.SoundLoop:Play() end
  653.  
  654. self.SoundSwing = CreateSound( self.Owner, Sound( self.SwingSound ) )
  655. if ( self.SoundSwing ) then self.SoundSwing:Play() self.SoundSwing:ChangeVolume( 0, 0 ) end
  656.  
  657. self.SoundHit = CreateSound( self.Owner, Sound( "lightsaber/SaberHit.wav" ) )
  658. if ( self.SoundHit ) then self.SoundHit:Play() self.SoundHit:ChangeVolume( 0, 0 ) end
  659. end
  660.  
  661. self:SetEnabled( !self:GetEnabled() )
  662. end
  663.  
  664. /* --------------------------------------------------------- Hold Types --------------------------------------------------------- */
  665.  
  666. function SWEP:GetTargetHoldType()
  667. //print( self:LookupAttachment( "blade2" ), self:GetAttachment( 1 ), self:GetModel() )
  668. //PrintTable( self:GetAttachments() )
  669.  
  670. //if ( !self:GetEnabled() ) then return "normal" end
  671. //if ( self:GetWorldModel() == "models/sgg/starwars/weapons/w_maul_saber_hilt.mdl" ) then return "knife" end
  672. if ( self:GetWorldModel() == "models/sgg/starwars/weapons/w_maul_saber_staff_hilt.mdl" ) then return "knife" end
  673. if ( self:LookupAttachment( "blade2" ) && self:LookupAttachment( "blade2" ) > 0 ) then return "knife" end
  674.  
  675. return "melee2"
  676. end
  677.  
  678. /* --------------------------------------------------------- Deploy / Holster --------------------------------------------------------- */
  679.  
  680. function SWEP:OnRemove()
  681. if ( CLIENT ) then rb655_SaberClean( self:EntIndex() ) return end
  682.  
  683. if ( self.SoundLoop ) then self.SoundLoop:Stop() self.SoundLoop = nil end
  684. if ( self.SoundSwing ) then self.SoundSwing:Stop() self.SoundSwing = nil end
  685. if ( self.SoundHit ) then self.SoundHit:Stop() self.SoundHit = nil end
  686. end
  687.  
  688. function SWEP:Deploy()
  689.  
  690. local ply = self.Owner
  691.  
  692. if ( ply:IsPlayer() && !ply:IsBot() && !self.WeaponSynched && SERVER ) then
  693. self:SetMaxLength( math.Clamp( ply:GetInfoNum( "rb655_lightsaber_bladel", 42 ), 32, 64 ) )
  694. self:SetCrystalColor( Vector( ply:GetInfo( "rb655_lightsaber_red" ), ply:GetInfo( "rb655_lightsaber_green" ), ply:GetInfo( "rb655_lightsaber_blue" ) ) )
  695. self:SetDarkInner( ply:GetInfo( "rb655_lightsaber_dark" ) == "1" )
  696. self:SetWorldModel( ply:GetInfo( "rb655_lightsaber_model" ) )
  697. self:SetBladeWidth( math.Clamp( ply:GetInfoNum( "rb655_lightsaber_bladew", 2 ), 2, 4 ) )
  698.  
  699. self.LoopSound = ply:GetInfo( "rb655_lightsaber_humsound" )
  700. self.SwingSound = ply:GetInfo( "rb655_lightsaber_swingsound" )
  701. self:SetOnSound( ply:GetInfo( "rb655_lightsaber_onsound" ) )
  702. self:SetOffSound( ply:GetInfo( "rb655_lightsaber_offsound" ) )
  703.  
  704. self.WeaponSynched = true
  705. end
  706.  
  707. if ( self:GetEnabled() ) then self:PlayWeaponSound( self:GetOnSound() ) end
  708.  
  709. if ( CLIENT ) then return end
  710.  
  711. if ( ply:FlashlightIsOn() ) then ply:Flashlight( false ) end
  712.  
  713. self:SetBladeLength( 0 )
  714.  
  715. if ( self:GetEnabled() ) then
  716. self.SoundLoop = CreateSound( ply, Sound( self.LoopSound ) )
  717. if ( self.SoundLoop ) then self.SoundLoop:Play() end
  718.  
  719. self.SoundSwing = CreateSound( ply, Sound( self.SwingSound ) )
  720. if ( self.SoundSwing ) then self.SoundSwing:Play() self.SoundSwing:ChangeVolume( 0, 0 ) end
  721.  
  722. self.SoundHit = CreateSound( ply, Sound( "lightsaber/SaberHit.wav" ) )
  723. if ( self.SoundHit ) then self.SoundHit:Play() self.SoundHit:ChangeVolume( 0, 0 ) end
  724. end
  725.  
  726. if ( !self:GetEnabled() ) then
  727. self:SetHoldType( "normal" )
  728. else
  729. self:SetHoldType( self:GetTargetHoldType() )
  730. end
  731.  
  732. return true
  733. end
  734.  
  735. function SWEP:Holster()
  736. if ( self:GetEnabled() ) then self:PlayWeaponSound( self:GetOffSound() ) end
  737.  
  738. if ( CLIENT ) then rb655_SaberClean( self:EntIndex() ) return true end
  739.  
  740. if ( self.SoundLoop ) then self.SoundLoop:Stop() self.SoundLoop = nil end
  741. if ( self.SoundSwing ) then self.SoundSwing:Stop() self.SoundSwing = nil end
  742. if ( self.SoundHit ) then self.SoundHit:Stop() self.SoundHit = nil end
  743.  
  744. return true
  745. end
  746.  
  747. /* --------------------------------------------------------- Think --------------------------------------------------------- */
  748.  
  749. function SWEP:GetSaberPosAng( num )
  750. num = num or 1
  751.  
  752. local c = Color( 255, 128, 0 )
  753. if ( SERVER ) then c = Color( 0, 128, 255 ) end
  754.  
  755. if ( IsValid( self.Owner ) ) then
  756.  
  757. local attachment = self:LookupAttachment( "blade" .. num )
  758. if ( attachment && attachment > 0 ) then
  759. local PosAng = self:GetAttachment( attachment )
  760.  
  761. /*if ( SERVER ) then
  762. debugoverlay.Line( PosAng.Pos, PosAng.Pos + PosAng.Ang:Forward() * 50, .1, c, false )
  763. end*/
  764.  
  765. return PosAng.Pos, PosAng.Ang:Forward()
  766. end
  767.  
  768. local attachment = self.Owner:LookupBone( "ValveBiped.Bip01_R_Hand" )
  769. if ( attachment ) then
  770. local pos, ang = self.Owner:GetBonePosition( attachment )
  771. if ( pos == self.Owner:GetPos() ) then
  772. local matrix = self.Owner:GetBoneMatrix( attachment )
  773. pos = matrix:GetTranslation()
  774. ang = matrix:GetAngles()
  775. end
  776.  
  777. ang:RotateAroundAxis( ang:Forward(), 180 )
  778. ang:RotateAroundAxis( ang:Up(), 30 )
  779. ang:RotateAroundAxis( ang:Forward(), -5.7 )
  780. ang:RotateAroundAxis( ang:Right(), 92 )
  781.  
  782. pos = pos + ang:Up() * -3.3 + ang:Right() * 0.8 + ang:Forward() * 5.6
  783.  
  784. /*if ( SERVER ) then
  785. debugoverlay.Line( pos, pos + ang:Forward() * 50, .1, c, false )
  786. end*/
  787.  
  788. return pos, ang:Forward()
  789. end
  790. end
  791.  
  792. local defAng = self:GetAngles()
  793. defAng:RotateAroundAxis( defAng:Right(), 90 )
  794.  
  795. ErrorNoHalt( "LIGHTSABERS: THIS SHOULD NEVER HAPPEN!")
  796.  
  797. return self:GetPos() + defAng:Right() * 0.6 - defAng:Up() * 1 - defAng:Forward() * 0.25, defAng:Forward()
  798. end
  799.  
  800. function SWEP:OnForceChanged( name, old, new )
  801. if ( old > new ) then
  802. self.NextForce = CurTime() + 4
  803. end
  804. end
  805.  
  806. function SWEP:Think()
  807. self.WorldModel = self:GetWorldModel()
  808. self:SetModel( self:GetWorldModel() )
  809.  
  810. if ( self.ForcePowers[ self:GetForceType() ]&& self.ForcePowers[ self:GetForceType() ].think && !self.Owner:KeyDown( IN_USE ) ) then
  811. self.ForcePowers[ self:GetForceType() ].think( self )
  812. end
  813.  
  814. if ( CLIENT ) then return true end
  815.  
  816. if ( ( self.NextForce or 0 ) < CurTime() ) then
  817. self:SetForce( math.min( self:GetForce() + 0.5, 100 ) )
  818. end
  819.  
  820. if ( !self:GetEnabled() && self:GetBladeLength() != 0 ) then
  821. self:SetBladeLength( math.Approach( self:GetBladeLength(), 0, 2 ) )
  822. elseif ( self:GetEnabled() && self:GetBladeLength() != self:GetMaxLength() ) then
  823. self:SetBladeLength( math.Approach( self:GetBladeLength(), self:GetMaxLength(), 8 ) )
  824. end
  825.  
  826. if ( self:GetBladeLength() <= 0 ) then return end
  827.  
  828. -- Up
  829. local pos, ang = self:GetSaberPosAng()
  830. local trace = util.TraceLine( {
  831. start = pos,
  832. endpos = pos + ang * self:GetBladeLength(),
  833. filter = { self, self.Owner },
  834. mins = Vector( -1, -1, -1 ) * self:GetBladeWidth() / 8,
  835. maxs = Vector( 1, 1, 1 ) * self:GetBladeWidth() / 8
  836. } )
  837.  
  838. if ( trace.HitSky or !util.IsInWorld( trace.HitPos ) ) then trace.Hit = false end
  839.  
  840. self:DrawHitEffects( trace )
  841.  
  842. if ( trace.Hit ) then
  843. rb655_LS_DoDamage( trace, self )
  844. end
  845.  
  846. -- Down
  847. local isTrace2Hit = false
  848. if ( self:LookupAttachment( "blade2" ) > 0 ) then -- TEST ME
  849. local pos2, dir2 = self:GetSaberPosAng( 2 )
  850. local trace2 = util.TraceHull( {
  851. start = pos2,
  852. endpos = pos2 + dir2 * self:GetBladeLength(),
  853. filter = { self, self.Owner },
  854. mins = Vector( -1, -1, -1 ) * self:GetBladeWidth() / 8,
  855. maxs = Vector( 1, 1, 1 ) * self:GetBladeWidth() / 8
  856. } )
  857.  
  858. if ( trace2.HitSky or !util.IsInWorld( trace2.HitPos ) ) then trace2.Hit = false end
  859.  
  860. self:DrawHitEffects( trace2 )
  861.  
  862. if ( trace2.Hit ) then
  863. rb655_LS_DoDamage( trace2, self )
  864. end
  865.  
  866. isTrace2Hit = trace2.Hit
  867. end
  868.  
  869. if ( ( trace.Hit || isTrace2Hit ) && self.SoundHit ) then
  870. self.SoundHit:ChangeVolume( math.Rand( 0.1, 0.5 ), 0 )
  871. elseif ( self.SoundHit ) then
  872. self.SoundHit:ChangeVolume( 0, 0 )
  873. end
  874.  
  875. if ( self.SoundSwing ) then
  876.  
  877. if ( self.LastAng != ang ) then
  878. self.LastAng = self.LastAng or ang
  879. self.SoundSwing:ChangeVolume( math.Clamp( ang:Distance( self.LastAng ) / 2, 0, 1 ), 0 )
  880. end
  881.  
  882. self.LastAng = ang
  883. end
  884.  
  885. if ( self.SoundLoop ) then
  886. pos = pos + ang * self:GetBladeLength()
  887.  
  888. if ( self.LastPos != pos ) then
  889. self.LastPos = self.LastPos or pos
  890. self.SoundLoop:ChangeVolume( 0.1 + math.Clamp( pos:Distance( self.LastPos ) / 128, 0, 0.2 ), 0 )
  891. end
  892. self.LastPos = pos
  893. end
  894. end
  895.  
  896. function SWEP:DrawHitEffects( trace )
  897. if ( self:GetBladeLength() <= 0 ) then return end
  898.  
  899. if ( trace.HitSky ) then trace.Hit = false end
  900.  
  901. if ( trace.Hit ) then
  902. rb655_DrawHit( trace.HitPos, trace.HitNormal )
  903. end
  904. end
  905.  
  906. local index = ACT_HL2MP_IDLE_KNIFE
  907. local KnifeHoldType = {}
  908. KnifeHoldType[ ACT_MP_STAND_IDLE ]= index
  909. KnifeHoldType[ ACT_MP_WALK ]= index + 1
  910. KnifeHoldType[ ACT_MP_RUN ]= index + 2
  911. KnifeHoldType[ ACT_MP_CROUCH_IDLE ]= index + 3
  912. KnifeHoldType[ ACT_MP_CROUCHWALK ]= index + 4
  913. KnifeHoldType[ ACT_MP_ATTACK_STAND_PRIMARYFIRE ]= index + 5
  914. KnifeHoldType[ ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ]= index + 5
  915. KnifeHoldType[ ACT_MP_RELOAD_STAND ]= index + 6
  916. KnifeHoldType[ ACT_MP_RELOAD_CROUCH ]= index + 6
  917. KnifeHoldType[ ACT_MP_JUMP ]= index + 7
  918. KnifeHoldType[ ACT_RANGE_ATTACK1 ]= index + 8
  919. KnifeHoldType[ ACT_MP_SWIM ]= index + 9
  920.  
  921. function SWEP:TranslateActivity( act )
  922.  
  923. if ( self.Owner:IsNPC() ) then
  924. if ( self.ActivityTranslateAI[ act ]) then return self.ActivityTranslateAI[ act ]end
  925. return -1
  926. end
  927.  
  928. if ( self.Owner:Crouching() ) then
  929. local tr = util.TraceHull( {
  930. start = self.Owner:GetShootPos(),
  931. endpos = self.Owner:GetShootPos() + Vector( 0, 0, 20 ),
  932. mins = self.Owner:OBBMins(),
  933. maxs = self.Owner:OBBMaxs(),
  934. filter = self.Owner
  935. } )
  936.  
  937. if ( self:GetEnabled() && tr.Hit && act == ACT_MP_ATTACK_CROUCH_PRIMARYFIRE ) then return ACT_HL2MP_IDLE_KNIFE + 5 end
  938.  
  939. if ( ( !self:GetEnabled() && self:GetHoldType() == "normal" ) && self.Owner:Crouching() && act == ACT_MP_CROUCH_IDLE ) then return ACT_HL2MP_IDLE_KNIFE + 3 end
  940. if ( ( ( !self:GetEnabled() && self:GetHoldType() == "normal" ) || ( self:GetEnabled() && tr.Hit ) ) && act == ACT_MP_CROUCH_IDLE ) then return ACT_HL2MP_IDLE_KNIFE + 3 end
  941. if ( ( ( !self:GetEnabled() && self:GetHoldType() == "normal" ) || ( self:GetEnabled() && tr.Hit ) ) && act == ACT_MP_CROUCHWALK ) then return ACT_HL2MP_IDLE_KNIFE + 4 end
  942.  
  943. end
  944.  
  945. if ( self.Owner:WaterLevel() > 1 && self:GetEnabled() ) then
  946. return KnifeHoldType[ act ]
  947. end
  948.  
  949. if ( self.ActivityTranslate[ act ]!= nil ) then return self.ActivityTranslate[ act ]end
  950. return -1
  951. end
  952.  
  953. /* ------------------------------------------------------------- Clientside stuff ----------------------------------------------------------------- */
  954.  
  955. if ( SERVER ) then return end
  956.  
  957. killicon.Add( "weapon_lightsaber", "lightsaber/lightsaber_killicon", color_white )
  958.  
  959. local WepSelectIcon = Material( "lightsaber/selection.png" )
  960. local Size = 96
  961.  
  962. function SWEP:DrawWeaponSelection( x, y, w, h, a )
  963. surface.SetDrawColor( 255, 255, 255, a )
  964. surface.SetMaterial( WepSelectIcon )
  965.  
  966. render.PushFilterMag( TEXFILTER.ANISOTROPIC )
  967. render.PushFilterMin( TEXFILTER.ANISOTROPIC )
  968.  
  969. surface.DrawTexturedRect( x + ( ( w - Size ) / 2 ), y + ( ( h - Size ) / 2.5 ), Size, Size )
  970.  
  971. render.PopFilterMag()
  972. render.PopFilterMin()
  973. end
  974.  
  975. function SWEP:DrawWorldModel()
  976. self:DrawWorldModelTranslucent()
  977. end
  978.  
  979. function SWEP:DrawWorldModelTranslucent()
  980. self.WorldModel = self:GetWorldModel()
  981. self:SetModel( self:GetWorldModel() )
  982.  
  983. self:DrawModel()
  984.  
  985. if ( !IsValid( self:GetOwner() ) ) then return end
  986.  
  987. local clr = self:GetCrystalColor()
  988. clr = Color( clr.x, clr.y, clr.z )
  989.  
  990. local pos, dir = self:GetSaberPosAng()
  991. rb655_RenderBlade( pos, dir, self:GetBladeLength(), self:GetMaxLength(), self:GetBladeWidth(), clr, self:GetDarkInner(), self:EntIndex(), self:GetOwner():WaterLevel() > 2 )-- Doesn't work for non local players
  992.  
  993. if ( self:LookupAttachment( "blade2" ) > 0 ) then
  994. local pos, dir = self:GetSaberPosAng( 2 )
  995. rb655_RenderBlade( pos, dir, self:GetBladeLength(), self:GetMaxLength(), self:GetBladeWidth(), clr, self:GetDarkInner(), self:EntIndex() + 655, self:GetOwner():WaterLevel() > 2 )
  996. end
  997. end
  998.  
  999. /* --------------------------------------------------------- 3rd Person Camera --------------------------------------------------------- */
  1000.  
  1001. hook.Add( "ShouldDrawLocalPlayer", "rb655_lightsaber_weapon_draw", function()
  1002. if ( IsValid( LocalPlayer() ) && LocalPlayer().GetActiveWeapon && IsValid( LocalPlayer():GetActiveWeapon() ) && LocalPlayer():GetActiveWeapon():GetClass() == "weapon_lightsaber" && !LocalPlayer():InVehicle() && LocalPlayer():Alive() && LocalPlayer():GetViewEntity() == LocalPlayer() ) then return true end
  1003. end )
  1004.  
  1005. function SWEP:CalcView( ply, pos, ang, fov )
  1006. if ( !IsValid( ply ) || !ply:Alive() || ply:InVehicle() || ply:GetViewEntity() != ply ) then return end
  1007.  
  1008. local trace = util.TraceHull( {
  1009. start = pos,
  1010. endpos = pos - ang:Forward() * 100,
  1011. filter = { ply:GetActiveWeapon(), ply },
  1012. mins = Vector( -4, -4, -4 ),
  1013. maxs = Vector( 4, 4, 4 ),
  1014. } )
  1015.  
  1016. if ( trace.Hit ) then pos = trace.HitPos else pos = pos - ang:Forward() * 100 end
  1017.  
  1018. return pos, ang, fov
  1019. end
  1020.  
  1021. /* --------------------------------------------------------- HUD --------------------------------------------------------- */
  1022.  
  1023. surface.CreateFont( "SelectedForceType", {
  1024. font = "Roboto Cn",
  1025. size = ScreenScale( 16 ),
  1026. weight = 600
  1027. } )
  1028.  
  1029. surface.CreateFont( "SelectedForceHUD", {
  1030. font = "Roboto Cn",
  1031. size = ScreenScale( 6 )
  1032. } )
  1033.  
  1034. local ForceSelectEnabled = false
  1035. hook.Add( "PlayerBindPress", "rb655_sabers_force", function( ply, bind, pressed )
  1036. if ( LocalPlayer():InVehicle() || ply != LocalPlayer() || !LocalPlayer():Alive() || !IsValid( LocalPlayer():GetActiveWeapon() ) || LocalPlayer():GetActiveWeapon():GetClass() != "weapon_lightsaber" ) then ForceSelectEnabled = false return end
  1037.  
  1038. if ( bind == "impulse 100" && pressed ) then
  1039. ForceSelectEnabled = !ForceSelectEnabled
  1040. return true
  1041. end
  1042.  
  1043. if ( !ForceSelectEnabled ) then return end
  1044.  
  1045. if ( bind:StartWith( "slot" ) ) then
  1046. RunConsoleCommand( "rb655_select_force", bind:sub( 5 ) )
  1047. return true
  1048. end
  1049. end )
  1050.  
  1051. local grad = Material( "gui/gradient_up" )
  1052. local matBlurScreen = Material( "pp/blurscreen" )
  1053. matBlurScreen:SetFloat( "$blur", 3 )
  1054. matBlurScreen:Recompute()
  1055. local function DrawHUDBox( x, y, w, h, b )
  1056.  
  1057. surface.SetMaterial( matBlurScreen )
  1058. surface.SetDrawColor( 255, 255, 255, 255 )
  1059.  
  1060. render.SetScissorRect( x, y, w + x, h + y, true )
  1061. for i = 0.33, 1, 0.33 do
  1062. matBlurScreen:SetFloat( "$blur", 5 * i )
  1063. matBlurScreen:Recompute()
  1064. render.UpdateScreenEffectTexture()
  1065. surface.DrawTexturedRect( 0, 0, ScrW(), ScrH() )
  1066. end
  1067. render.SetScissorRect( 0, 0, 0, 0, false )
  1068.  
  1069. surface.SetDrawColor( Color( 0, 0, 0, 128 ) )
  1070. surface.DrawRect( x, y, w, h )
  1071.  
  1072. if ( b ) then
  1073. surface.SetMaterial( grad )
  1074. surface.SetDrawColor( Color( 0, 128, 255, 4 ) )
  1075. surface.DrawTexturedRect( x, y, w, h )
  1076. end
  1077.  
  1078. end
  1079.  
  1080. local ForceBar = 100
  1081. function SWEP:DrawHUD()
  1082.  
  1083. if ( !IsValid( self.Owner ) || self.Owner:GetViewEntity() != self.Owner || self.Owner:InVehicle() ) then return end
  1084.  
  1085. -----------------------------------
  1086.  
  1087. local icon = 52
  1088. local gap = 5
  1089.  
  1090. local bar = 4
  1091. local bar2 = 16
  1092.  
  1093. if ( ForceSelectEnabled ) then
  1094. icon = 128
  1095. bar = 8
  1096. bar2 = 24
  1097. end
  1098.  
  1099. ----------------------------------- Force Bar -----------------------------------
  1100.  
  1101. ForceBar = math.min( 100, Lerp( 0.1, ForceBar, self:GetForce() ) )
  1102.  
  1103. local w = #self.ForcePowers * icon + ( #self.ForcePowers - 1 ) * gap
  1104. local h = bar2
  1105. local x = ScrW() / 2 - w / 2
  1106. local y = ScrH() - gap - bar2
  1107.  
  1108. DrawHUDBox( x, y, w, h )
  1109. draw.RoundedBox( 0, x, y, w * ( ForceBar / 100 ), h, Color( 0, 128, 255, 255 ) )
  1110.  
  1111. draw.SimpleText( math.floor( self:GetForce() ) .. "%", "SelectedForceHUD", x + w / 2, y + h / 2, Color( 255, 255, 255 ), 1, 1 )
  1112.  
  1113. ----------------------------------- Force Icons -----------------------------------
  1114.  
  1115. local y = y - icon - gap
  1116. local h = icon
  1117.  
  1118. for id, t in pairs( self.ForcePowers ) do
  1119. local x = x + ( id - 1 ) * ( h + gap )
  1120.  
  1121. DrawHUDBox( x, y, h, h, self:GetForceType() == id )
  1122. draw.SimpleText( self.ForcePowers[ id ].icon or "", "SelectedForceType", x + icon / 2, y + icon / 2, Color( 255, 255, 255 ), 1, 1 )
  1123. if ( ForceSelectEnabled ) then draw.SimpleText( id, "SelectedForceHUD", x + gap, y + gap, Color( 255, 255, 255 ) ) end
  1124. if ( self:GetForceType() == id ) then
  1125. local y = y + ( icon - bar )
  1126. surface.SetDrawColor( 0, 128, 255, 255 )
  1127. draw.NoTexture()
  1128. surface.DrawPoly( {
  1129. { x = x + icon / 2 - bar, y = y },
  1130. { x = x + icon / 2, y = y - bar },
  1131. { x = x + icon / 2 + bar, y = y }
  1132. } )
  1133. draw.RoundedBox( 0, x, y, h, bar, Color( 0, 128, 255, 255 ) )
  1134. end
  1135. end
  1136.  
  1137. ----------------------------------- Force Description -----------------------------------
  1138.  
  1139. if ( ForceSelectEnabled ) then
  1140.  
  1141. surface.SetFont( "SelectedForceHUD" )
  1142. local tW, tH = surface.GetTextSize( self.ForcePowers[ self:GetForceType() ].description or "" )
  1143.  
  1144. /*local x = x + w + gap
  1145. local y = y*/
  1146. local x = ScrW() / 2 + gap// - tW / 2
  1147. local y = y - tH - gap * 3
  1148.  
  1149. DrawHUDBox( x, y, tW + gap * 2, tH + gap * 2 )
  1150.  
  1151. for id, txt in pairs( string.Explode( "\n", self.ForcePowers[ self:GetForceType() ].description or "" ) ) do
  1152. draw.SimpleText( txt, "SelectedForceHUD", x + gap, y + ( id - 1 ) * ScreenScale( 6 ) + gap, Color( 255, 255, 255 ) )
  1153. end
  1154.  
  1155. end
  1156.  
  1157. ----------------------------------- Force Label -----------------------------------
  1158.  
  1159. if ( !ForceSelectEnabled ) then
  1160. surface.SetFont( "SelectedForceHUD" )
  1161. local txt = "Press F to toggle Force selection"
  1162. local tW, tH = surface.GetTextSize( txt )
  1163.  
  1164. local x = x + w / 2
  1165. local y = y - tH - gap
  1166.  
  1167. DrawHUDBox( x - tW / 2 - 5, y, tW + 10, tH )
  1168. draw.SimpleText( txt, "SelectedForceHUD", x, y, Color( 255, 255, 255 ), 1 )
  1169. end
  1170.  
  1171. if ( ForceSelectEnabled ) then
  1172. surface.SetFont( "SelectedForceType" )
  1173. local txt = self.ForcePowers[ self:GetForceType() ].name or ""
  1174. local tW2, tH2 = surface.GetTextSize( txt )
  1175.  
  1176. local x = x + w / 2 - tW2 - gap * 2//+ w / 2
  1177. local y = y + gap - tH2 - gap * 2
  1178.  
  1179. DrawHUDBox( x, y, tW2 + 10, tH2 )
  1180. draw.SimpleText( txt, "SelectedForceType", x + gap, y, Color( 255, 255, 255 ) )
  1181. end
  1182.  
  1183. ----------------------------------- Force Target -----------------------------------
  1184.  
  1185. local isTarget = self.ForcePowers[ self:GetForceType() ].target
  1186.  
  1187. if ( isTarget ) then
  1188. for id, ent in pairs( self:SelectTargets( isTarget ) ) do
  1189. if ( !IsValid( ent ) ) then continue end
  1190. local maxs = ent:OBBMaxs()
  1191. local p = ent:GetPos()
  1192. p.z = p.z + maxs.z
  1193.  
  1194. local pos = p:ToScreen()
  1195. local x, y = pos.x, pos.y
  1196. local size = 16
  1197.  
  1198. surface.SetDrawColor( 255, 0, 0, 255 )
  1199. draw.NoTexture()
  1200. surface.DrawPoly( {
  1201. { x = x - size, y = y - size },
  1202. { x = x + size, y = y - size },
  1203. { x = x, y = y }
  1204. } )
  1205. end
  1206. end
  1207.  
  1208. -----------------------------------
  1209.  
  1210. /*local ang = Angle( 0, self.Owner:GetAngles().y, 0 )
  1211. ang:RotateAroundAxis( ang:Up(), -90 )
  1212. ang:RotateAroundAxis( ang:Forward(), 90 )
  1213. local pos = self.Owner:GetPos() + Vector( 0, 0, 48 ) + ang:Forward() * 16 + ang:Up() * 16
  1214.  
  1215. cam.Start3D( EyePos(), EyeAngles() )
  1216. cam.Start3D2D( pos, ang, 0.2 )
  1217.  
  1218. local x = 0//ScrW() - ScrW() / 3
  1219. local y = 0//ScrH() / 2 - 8
  1220.  
  1221. draw.RoundedBox( 0, x, y, 180, 18, Color( 0, 0, 0, 200 ) )
  1222. draw.SimpleText( self.ForcePowers[ self:GetForceType() ].name or "", "Default", x + 5, y + 3, Color( 255, 255, 255 ) )
  1223. draw.SimpleText( math.floor( self:GetForce() ) .. "%", "Default", x + 175, y + 3, Color( 255, 255, 255 ), 2 )
  1224.  
  1225. draw.RoundedBox( 0, x, y + 18, 180 * ( self:GetForce() / 100 ), 3, Color( 0, 128, 255 ) )
  1226.  
  1227. for id, txt in pairs( string.Explode( "\n", self.ForcePowers[ self:GetForceType() ].description or "" ) ) do
  1228. draw.SimpleText( txt, "Default", x + 4, y + 13 + id * 12, Color( 100, 255, 100 ) )
  1229. end
  1230.  
  1231. cam.End3D2D()
  1232. cam.End3D()*/
  1233.  
  1234. end
RAW Paste Data