Guest User

Untitled

a guest
Oct 9th, 2016
488
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.32 KB | None | 0 0
  1. --------------------- TEMPLATE ASSAULT RIFLE WEAPON ---------------------------
  2. -- Waits for the child of the specified parent
  3. local function WaitForChild(parent, childName)
  4.     while not parent:FindFirstChild(childName) do parent.ChildAdded:wait() end
  5.     return parent[childName]
  6. end
  7.  
  8. ----- MAGIC NUMBERS ABOUT THE TOOL -----
  9. -- How much damage a bullet does
  10. local Damage = 30
  11. -- How many times per second the gun can fire
  12. local FireRate = 1 / 10
  13. -- The maximum distance the can can shoot, this value should never go above 1000
  14. local Range = 800
  15. -- In radians the minimum accuracy penalty
  16. local MinSpread = 0
  17. -- In radian the maximum accuracy penalty
  18. local MaxSpread = 0.05
  19. -- Number of bullets in a clip
  20. local ClipSize = 10000000000
  21. -- DefaultValue for spare ammo
  22. local SpareAmmo = 100000000000000000
  23. -- The amount the aim will increase or decrease by
  24. -- decreases this number reduces the speed that recoil takes effect
  25. local AimInaccuracyStepAmount = 0.02
  26. -- Time it takes to reload weapon
  27. local ReloadTime = 3
  28. ----------------------------------------
  29.  
  30. -- Colors
  31. local FriendlyReticleColor = Color3.new(0, 1, 0)
  32. local EnemyReticleColor = Color3.new(1, 0, 0)
  33. local NeutralReticleColor   = Color3.new(1, 1, 1)
  34.  
  35. local Spread = MinSpread
  36. local AmmoInClip = ClipSize
  37.  
  38. local Tool = script.Parent
  39. local Handle = WaitForChild(Tool, 'Handle')
  40. local WeaponGui = nil
  41.  
  42. local LeftButtonDown
  43. local Reloading = false
  44. local IsShooting = false
  45.  
  46. -- Player specific convenience variables
  47. local MyPlayer = nil
  48. local MyCharacter = nil
  49. local MyHumanoid = nil
  50. local MyTorso = nil
  51. local MyMouse = nil
  52.  
  53. local RecoilAnim
  54. local RecoilTrack = nil
  55.  
  56. local ReloaddAnim
  57. local ReloaddTrack = nil
  58.  
  59. local IconURL = Tool.TextureId  -- URL to the weapon icon asset
  60.  
  61. local DebrisService = game:GetService('Debris')
  62. local PlayersService = game:GetService('Players')
  63.  
  64.  
  65. local FireSound
  66.  
  67. local OnFireConnection = nil
  68. local OnReloadConnection = nil
  69.  
  70. local DecreasedAimLastShot = false
  71. local LastSpreadUpdate = time()
  72.  
  73. -- this is a dummy object that holds the flash made when the gun is fired
  74. local FlashHolder = nil
  75.  
  76.  
  77. local WorldToCellFunction = Workspace.Terrain.WorldToCellPreferSolid
  78. local GetCellFunction = Workspace.Terrain.GetCell
  79.  
  80. function RayIgnoreCheck(hit, pos)
  81.     if hit then
  82.         if hit.Transparency >= 1 or string.lower(hit.Name) == "water" or
  83.                 hit.Name == "Effect" or hit.Name == "Rocket" or hit.Name == "Bullet" or
  84.                 hit.Name == "Handle" or hit:IsDescendantOf(MyCharacter) then
  85.             return true
  86.         elseif hit:IsA('Terrain') and pos then
  87.             local cellPos = WorldToCellFunction(Workspace.Terrain, pos)
  88.             if cellPos then
  89.                 local cellMat = GetCellFunction(Workspace.Terrain, cellPos.x, cellPos.y, cellPos.z)
  90.                 if cellMat and cellMat == Enum.CellMaterial.Water then
  91.                     return true
  92.                 end
  93.             end
  94.         end
  95.     end
  96.     return false
  97. end
  98.  
  99. -- @preconditions: vec should be a unit vector, and 0 < rayLength <= 1000
  100. function RayCast(startPos, vec, rayLength)
  101.     local hitObject, hitPos = game.Workspace:FindPartOnRay(Ray.new(startPos + (vec * .01), vec * rayLength), Handle)
  102.     if hitObject and hitPos then
  103.         local distance = rayLength - (hitPos - startPos).magnitude
  104.         if RayIgnoreCheck(hitObject, hitPos) and distance > 0 then
  105.             -- there is a chance here for potential infinite recursion
  106.             return RayCast(hitPos, vec, distance)
  107.         end
  108.     end
  109.     return hitObject, hitPos
  110. end
  111.  
  112.  
  113.  
  114. function TagHumanoid(humanoid, player)
  115.     -- Add more tags here to customize what tags are available.
  116.     while humanoid:FindFirstChild('creator') do
  117.         humanoid:FindFirstChild('creator'):Destroy()
  118.     end
  119.     local creatorTag = Instance.new("ObjectValue")
  120.     creatorTag.Value = player
  121.     creatorTag.Name = "creator"
  122.     creatorTag.Parent = humanoid
  123.     DebrisService:AddItem(creatorTag, 1.5)
  124.  
  125.     local weaponIconTag = Instance.new("StringValue")
  126.     weaponIconTag.Value = IconURL
  127.     weaponIconTag.Name = "icon"
  128.     weaponIconTag.Parent = creatorTag
  129. end
  130.  
  131.  
  132. local function CreateBullet(bulletPos)
  133.     local bullet = Instance.new('Part', Workspace)
  134.     bullet.FormFactor = Enum.FormFactor.Custom
  135.     bullet.Size = Vector3.new(0.1, 0.1, 0.1)
  136.     bullet.BrickColor = BrickColor.new("Black")
  137.     bullet.Shape = Enum.PartType.Block
  138.     bullet.CanCollide = false
  139.     bullet.CFrame = CFrame.new(bulletPos)
  140.     bullet.Anchored = true
  141.     bullet.TopSurface = Enum.SurfaceType.Smooth
  142.     bullet.BottomSurface = Enum.SurfaceType.Smooth
  143.     bullet.Name = 'Bullet'
  144.     DebrisService:AddItem(bullet, 2.5)
  145.     return bullet
  146. end
  147.  
  148. local function Reload()
  149.     if not Reloading then
  150.         Reloading = true
  151.         -- Don't reload if you are already full or have no extra ammo
  152.         if AmmoInClip ~= ClipSize and SpareAmmo > 0 then
  153.             if RecoilTrack then
  154.                 RecoilTrack:Stop()
  155.                
  156.             end
  157.             if WeaponGui and WeaponGui:FindFirstChild('Crosshair') then
  158.                 if WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
  159.                     WeaponGui.Crosshair.ReloadingLabel.Visible = true
  160.                 end
  161.             end
  162.             script.Parent.Handle.Reload:Play() 
  163.             wait(ReloadTime)
  164.             -- Only use as much ammo as you have
  165.             local ammoToUse = math.min(ClipSize - AmmoInClip, SpareAmmo)
  166.             AmmoInClip = AmmoInClip + ammoToUse
  167.             SpareAmmo = SpareAmmo - ammoToUse
  168.             UpdateAmmo(AmmoInClip)
  169.             WeaponGui.Reload.Visible = false
  170.         end
  171.         Reloading = false
  172.     end
  173. end
  174.  
  175. function OnFire()
  176.     if IsShooting then return end
  177.     if MyHumanoid and MyHumanoid.Health > 0 then
  178.         if RecoilTrack and AmmoInClip > 0 then
  179.             RecoilTrack:Play()
  180.         end
  181.         IsShooting = true
  182.         while LeftButtonDown and AmmoInClip > 0 and not Reloading do
  183.             if Spread and not DecreasedAimLastShot then
  184.                 Spread = math.min(MaxSpread, Spread + AimInaccuracyStepAmount)
  185.                 UpdateCrosshair(Spread)
  186.             end
  187.             DecreasedAimLastShot = not DecreasedAimLastShot
  188.             if script.Parent.Handle.FireSound.Playing then
  189.                 Handle.Flash.Enabled = true
  190.             elseif
  191.                 FireSound:Play()
  192.                 then
  193.                 script.Parent.Flash.ParticleEmitter.Enabled = true
  194.             end
  195.             if MyMouse then
  196.                 local targetPoint = MyMouse.Hit.p
  197.                 local shootDirection = (targetPoint - Handle.Position).unit
  198.                 -- Adjust the shoot direction randomly off by a little bit to account for recoil
  199.                 shootDirection = CFrame.Angles((0.5 - math.random()) * 2 * Spread,
  200.                                                                 (0.5 - math.random()) * 2 * Spread,
  201.                                                                 (0.5 - math.random()) * 2 * Spread) * shootDirection
  202.                 local hitObject, bulletPos = RayCast(Handle.Position, shootDirection, Range)
  203.                 local bullet
  204.                 -- Create a bullet here
  205.                 if hitObject then
  206.                     bullet = CreateBullet(bulletPos)
  207.                 end
  208.                 if hitObject and hitObject.Parent then
  209.                     local hitHumanoid = hitObject.Parent:FindFirstChild("Humanoid")
  210.                     if hitHumanoid then
  211.                         local hitPlayer = game.Players:GetPlayerFromCharacter(hitHumanoid.Parent)
  212.                         if MyPlayer.Neutral or (hitPlayer and hitPlayer.TeamColor ~= MyPlayer.TeamColor) then
  213.                             TagHumanoid(hitHumanoid, MyPlayer)
  214.                             hitHumanoid:TakeDamage(Damage)
  215.                             if bullet then
  216.                                 bullet:Destroy()
  217.                                 bullet = nil
  218.                                 --bullet.Transparency = 1
  219.                             end
  220.                             Spawn(UpdateTargetHit)
  221.                         end
  222.                     end
  223.                 end
  224.    
  225.                 AmmoInClip = AmmoInClip - 1
  226.                 UpdateAmmo(AmmoInClip)
  227.             end
  228.             wait(FireRate)
  229.         end
  230.         Handle.Flash.Enabled = false
  231.         IsShooting = false
  232.         if AmmoInClip == 0 then
  233.             Handle.Tick:Play()
  234.             WeaponGui.Reload.Visible = true
  235.         end
  236.         if RecoilTrack then
  237.             RecoilTrack:Stop()
  238.             FireSound:Stop()
  239.             script.Parent.Flash.ParticleEmitter.Enabled = false
  240.         end
  241.     end
  242. end
  243.  
  244. local TargetHits = 0
  245. function UpdateTargetHit()
  246.     TargetHits = TargetHits + 1
  247.     if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
  248.         WeaponGui.Crosshair.TargetHitImage.Visible = true
  249.     end
  250.     wait(0.5)
  251.     TargetHits = TargetHits - 1
  252.     if TargetHits == 0 and WeaponGui and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('TargetHitImage') then
  253.         WeaponGui.Crosshair.TargetHitImage.Visible = false
  254.     end
  255. end
  256.  
  257. function UpdateCrosshair(value, mouse)
  258.     if WeaponGui then
  259.         local absoluteY = 650
  260.         WeaponGui.Crosshair:TweenSize(
  261.             UDim2.new(0, value * absoluteY * 2 + 23, 0, value * absoluteY * 2 + 23),
  262.             Enum.EasingDirection.Out,
  263.             Enum.EasingStyle.Linear,
  264.             0.33)
  265.     end
  266. end
  267.  
  268. function UpdateAmmo(value)
  269.     if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('ClipAmmo') then
  270.         WeaponGui.AmmoHud.ClipAmmo.Text = AmmoInClip
  271.         if value > 0 and WeaponGui:FindFirstChild('Crosshair') and WeaponGui.Crosshair:FindFirstChild('ReloadingLabel') then
  272.             WeaponGui.Crosshair.ReloadingLabel.Visible = false
  273.         end
  274.     end
  275.     if WeaponGui and WeaponGui:FindFirstChild('AmmoHud') and WeaponGui.AmmoHud:FindFirstChild('TotalAmmo') then
  276.         WeaponGui.AmmoHud.TotalAmmo.Text = SpareAmmo
  277.     end
  278. end
  279.  
  280.  
  281. function OnMouseDown()
  282.     LeftButtonDown = true
  283.     OnFire()
  284. end
  285.  
  286. function OnMouseUp()
  287.     LeftButtonDown = false
  288. end
  289.  
  290. function OnKeyDown(key)
  291.     if string.lower(key) == 'r' then
  292.         Reload()
  293.     end
  294. end
  295.  
  296.  
  297. function OnEquipped(mouse)
  298.     Handle.EquipSound:Play()
  299.     RecoilAnim = WaitForChild(Tool, 'Recoil')
  300.     FireSound  = WaitForChild(Handle, 'FireSound')
  301.  
  302.     MyCharacter = Tool.Parent
  303.     MyPlayer = game:GetService('Players'):GetPlayerFromCharacter(MyCharacter)
  304.     MyHumanoid = MyCharacter:FindFirstChild('Humanoid')
  305.     MyTorso = MyCharacter:FindFirstChild('Torso')
  306.     MyMouse = mouse
  307.     WeaponGui = WaitForChild(Tool, 'WeaponHud'):Clone()
  308.     if WeaponGui and MyPlayer then
  309.         WeaponGui.Parent = MyPlayer.PlayerGui
  310.         UpdateAmmo(AmmoInClip)
  311.     end
  312.     if RecoilAnim then
  313.         RecoilTrack = MyHumanoid:LoadAnimation(RecoilAnim)
  314.     end
  315.  
  316.     if MyMouse then
  317.         -- Disable mouse icon
  318.         MyMouse.Icon = "http://www.roblox.com/asset/?id=18662154"
  319.         MyMouse.Button1Down:connect(OnMouseDown)
  320.         MyMouse.Button1Up:connect(OnMouseUp)
  321.         MyMouse.KeyDown:connect(OnKeyDown)
  322.     end
  323. end
  324.  
  325.  
  326. -- Unequip logic here
  327. function OnUnequipped()
  328.     LeftButtonDown = false
  329.     Reloading = false
  330.     MyCharacter = nil
  331.     MyHumanoid = nil
  332.     MyTorso = nil
  333.     MyPlayer = nil
  334.     MyMouse = nil
  335.     if OnFireConnection then
  336.         OnFireConnection:disconnect()
  337.     end
  338.     if OnReloadConnection then
  339.         OnReloadConnection:disconnect()
  340.     end
  341.     if FlashHolder then
  342.         FlashHolder = nil
  343.     end
  344.     if WeaponGui then
  345.         WeaponGui.Parent = nil
  346.         WeaponGui = nil
  347.     end
  348.     if RecoilTrack then
  349.         RecoilTrack:Stop()
  350.     end
  351. end
  352.  
  353. local function SetReticleColor(color)
  354.     if WeaponGui and WeaponGui:FindFirstChild('Crosshair') then
  355.         for _, line in pairs(WeaponGui.Crosshair:GetChildren()) do
  356.             if line:IsA('Frame') then
  357.                 line.BorderColor3 = color
  358.             end
  359.         end
  360.     end
  361. end
  362.  
  363.  
  364. Tool.Equipped:connect(OnEquipped)
  365. Tool.Unequipped:connect(OnUnequipped)
  366.  
  367. while true do
  368.     wait(0.033)
  369.     if WeaponGui and WeaponGui:FindFirstChild('Crosshair') and MyMouse then
  370.         WeaponGui.Crosshair.Position = UDim2.new(0, MyMouse.X, 0, MyMouse.Y)
  371.         SetReticleColor(NeutralReticleColor)
  372.  
  373.         local target = MyMouse.Target
  374.         if target and target.Parent then
  375.             local player = PlayersService:GetPlayerFromCharacter(target.Parent)
  376.             if player then
  377.                 if MyPlayer.Neutral or player.TeamColor ~= MyPlayer.TeamColor then
  378.                     SetReticleColor(EnemyReticleColor)
  379.                 else
  380.                     SetReticleColor(FriendlyReticleColor)
  381.                 end
  382.             end
  383.         end
  384.     end
  385.     if Spread and not IsShooting then
  386.         local currTime = time()
  387.         if currTime - LastSpreadUpdate > FireRate * 2 then
  388.             LastSpreadUpdate = currTime
  389.             Spread = math.max(MinSpread, Spread - AimInaccuracyStepAmount)
  390.             UpdateCrosshair(Spread, MyMouse)
  391.         end
  392.     end
  393. end
Advertisement
Add Comment
Please, Sign In to add comment