Guest User

Untitled

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