Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --// Objects
- local player = game.Players.LocalPlayer
- local char = player.Character or player.CharacterAdded:wait()
- local mouse = player:GetMouse()
- local cam = workspace.CurrentCamera
- local wfc = game.WaitForChild
- local ffc = game.FindFirstChild
- local ffcoc = game.FindFirstChildOfClass
- local getch = game.GetChildren
- --// Services
- local UserInput = game:GetService("UserInputService")
- local RunService = game:GetService("RunService")
- local TextService = game:GetService("TextService")
- local TweenService = game:GetService("TweenService")
- local RepStore = game:GetService("ReplicatedStorage")
- local events = wfc(RepStore,"Events")
- local models = wfc(RepStore,"Models")
- local modules = wfc(RepStore,"Modules")
- --// Variables
- local cf = CFrame.new
- local ang = CFrame.Angles
- local v3 = Vector3.new
- local lerpv3 = v3().lerp
- local lerpcf = cf().lerp
- local v2 = Vector2.new
- local c3 = Color3.new
- local rgb = Color3.fromRGB
- local brc = BrickColor.new
- local ud2 = UDim2.new
- local sin,cos,tan = math.sin,math.cos,math.sin
- local asin,acos,atan = math.asin,math.acos,math.atan
- local pi,tpi,hpi = math.pi,math.pi*2,math.pi/2
- local atan2 = math.atan2
- local sqrt = math.sqrt
- local abs = math.abs
- local random = math.random
- local floor,ceil,clamp = math.floor,math.ceil,math.clamp
- local rad,deg = math.rad,math.deg
- local rdm = math.random
- local ncf = cf()
- local nv3 = v3()
- local lerp = ncf.lerp
- --// Modules
- local spring = {}
- local camera = {}
- local character = {}
- local util = {}
- local ik = {}
- local loadout = {}
- local gun = {}
- local animate = {}
- local menu = {}
- local hud = {}
- do --// Spring
- local tick = tick
- local cos = math.cos
- local sin = math.sin
- local e = 2.718281828459045
- local function getposvel(s, d, p0, c1, c2, t0)
- local t = tick() - t0
- if d >= 1 then
- return (c1 + c2 * s * t) / e ^ (s * t) + p0, (c2 * s * (1 - t) - c1) / e ^ (s * t)
- else
- local h = (1 - d * d) ^ 0.5
- return (c1 * cos(s * h * t) + c2 * sin(s * h * t)) / e ^ (s * d * t) + p0, s * ((h * c2 - d * c1) * cos(s * h * t) - (h * c1 + d * c1) * sin(s * h * t)) / e ^ (s * d * t)
- end
- end
- function spring.new(initial, s, d)
- local self = {}
- local s = s or 15
- local d = d or 0.5
- local p0 = initial or 0
- local c1 = 0 * p0
- local c2 = 0 * p0
- local t0 = tick()
- function self:impulse(a)
- local p, v = getposvel(s, d, p0, c1, c2, t0)
- t0 = tick()
- c1 = p
- if d >= 1 then
- c2 = c1 + (v + a) / s
- else
- local h = (1 - d * d) ^ 0.5
- c2 = d / h * c1 + (v + a) / (s * h)
- end
- end
- local meta = {}
- function meta.__index(table, index)
- if index == "position" or index == "p" then
- local p, v = getposvel(s, d, p0, c1, c2, t0)
- return p
- elseif index == "velocity" or index == "v" then
- local p, v = getposvel(s, d, p0, c1, c2, t0)
- return v
- elseif index == "dampen" or index == "d" then
- return d
- elseif index == "speed" or index == "s" then
- return s
- end
- end
- function meta.__newindex(table, index, value)
- if index == "dampen" or index == "d" then
- d = value
- elseif index == "speed" or index == "s" then
- s = value
- elseif index == "target" or index == "t" then
- local p, v = getposvel(s, d, p0, c1, c2, t0)
- t0 = tick()
- p0 = value
- c1 = p - p0
- if d >= 1 then
- c2 = c1 + v / s
- else
- local h = (1 - d * d) ^ 0.5
- c2 = d / h * c1 + v / (s * h)
- end
- end
- end
- return setmetatable(self, meta)
- end
- end
- do --// Camera
- local self = camera
- self.recoil = spring.new(nv3)
- self.recoil.d = 0.8
- self.recoil.s = 20
- self.fov = spring.new(80)
- self.fov.d = 0.8
- self.fov.s = 20
- self.impulserecoil = function(self,vel)
- self.recoil:impulse(vel)
- end
- self.setfov = function(self,fov)
- self.fov.t = fov
- end
- end
- do --// Character
- local self = character
- self.running = false
- self.setsprint = function(self,state)
- self.running = not gun.aiming and state or false
- char.Humanoid.WalkSpeed = self.running and 26 or 16
- end
- self.grab = v3()
- end
- do --// Utility
- local self = util
- self.weldmodel = function(self,model)
- assert(model.PrimaryPart,"Model must have a PrimaryPart set in order to weld it")
- for i,v in pairs(model:GetDescendants()) do
- if v:IsA("BasePart") then
- v.CanCollide = false
- v.Anchored = false
- local weld = Instance.new("Weld")
- weld.Part0 = model.PrimaryPart
- weld.Part1 = v
- weld.C0 = model.PrimaryPart.CFrame:Inverse()
- weld.C1 = v.CFrame:Inverse()
- weld.Name = v.Name
- weld.Parent = model.PrimaryPart
- end
- end
- end
- self.randomvector = function(self,min,max)
- min = min or v3()
- max = max or v3()
- local minX,minY,minZ = min.X,min.Y,min.Z
- local maxX,maxY,maxZ = max.X,max.Y,max.Z
- return v3(rdm(minX,maxX),rdm(minY,maxY),rdm(minZ,maxZ))
- end
- end
- do --// Inverse Kinematics
- local self = ik
- local ptos = ncf.PointToObjectSpace
- self.new = function(self)
- local ret = {}
- function ret:solve(r0, r1, c, p)
- local t = ptos(c, p)
- local tx, ty, tz = t.x, t.y, t.z
- local d = (tx^2 + ty^2 + tz^2)^.5
- local nx, ny, nz = tx/d, ty/d, tz/d
- d = r0 + r1 < d and r0 + r1 or d
- local l = (r1^2 - r0^2 - d^2)/(2 * r0 * d)
- local h = (1 - l^2)^.5
- local a = atan2(-h, -l)
- local j0 = c * cf(nv3, t) * ang(a, 0, 0)
- return j0, j0 * cf(0, 0, -r0) * ang(-2 * a, 0, 0)
- end
- return ret
- end
- end
- do --// Loadout
- end
- do --// Gun
- local self = gun
- self.gunbob = function(self,s0,d0,d1,d2,d3)
- local t,s = tick(),s0/2
- local c = cf(not self.running and sin(t*s)/d0 or 0,cos(t*s0)/d1,self.running and sin(t*s)/d0 or 0)
- local a = not self.running and ang(sin(t*s0)/d2,0,sin(t*s)/d3) or ang(sin(t*s)/d1,0,0)
- return c*a
- end
- self.new = function(self,name)
- self.walk = cf()
- self.aimpos = cf()
- self.aimrot = cf()
- self.rarmc0 = cf()
- self.larmc0 = cf()
- local aimspring = spring.new(nv3)
- aimspring.d = 0.85
- aimspring.s = 20
- local aimrotspring = spring.new(nv3)
- aimrotspring.d = 0.85
- aimrotspring.s = 20
- local recoilspringp = spring.new(nv3)
- recoilspringp.d = 0.8
- recoilspringp.s = 30
- local recoilspringr = spring.new(nv3)
- recoilspringr.d = 0.8
- recoilspringr.s = 20
- self.lanimcf0p = spring.new(nv3)
- self.lanimcf0p.d = 1
- self.lanimcf0p.s = 20
- self.lanimcf0r = spring.new(nv3)
- self.lanimcf0r.d = 1
- self.lanimcf0r.s = 20
- self.janimcf0p = spring.new(nv3)
- self.janimcf0p.d = 1
- self.janimcf0p.s = 20
- self.janimcf0r = spring.new(nv3)
- self.janimcf0r.d = 1
- self.janimcf0r.s = 20
- recoil = {pos = recoilspringp,rot = recoilspringr,cf = cf()}
- self.model = models[name]:Clone()
- util:weldmodel(self.model)
- self.model.Parent = cam
- local data = require(modules[name])()
- self.getdata = function()
- return data
- end
- self.shooting = false
- self.aiming = false
- self.animoffset = cf()
- self.rootpart = Instance.new("Part")
- self.rootpart.Size = v3(1,1,1)
- self.rootpart.Transparency = 1
- self.rootpart.CanCollide = false
- self.rootpart.Name = "root"
- self.rootpart.CFrame = cam.CFrame
- self.rootpart.Parent = cam
- self.rarm = Instance.new("Part")
- self.rarm.Size = v3(0.5,0.5,3)
- self.rarm.TopSurface = Enum.SurfaceType.SmoothNoOutlines
- self.rarm.CanCollide = false
- self.rarm.Parent = cam
- self.rarm.Name = "rightarm"
- self.joint = Instance.new("Motor6D")
- self.joint.Part0 = self.rootpart
- self.joint.Part1 = self.rarm
- self.joint.C0 = cf(1,-1,-0.5)
- self.joint.Name = "mainweld"
- self.joint.Parent = self.rarm
- self.rjoint = Instance.new("Motor6D")
- self.rjoint.Part0 = self.rarm
- self.rjoint.Part1 = self.model.Right
- self.rjoint.C0 = cf(0,0.2,-1.5)
- self.rjoint.Name = "rightarmweld"
- self.rjoint.Parent = cam
- self.larm = Instance.new("Part")
- self.larm.Size = v3(0.5,0.5,3)
- self.larm.TopSurface = Enum.SurfaceType.SmoothNoOutlines
- self.larm.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
- self.larm.CanCollide = false
- self.larm.Parent = cam
- self.larm.Name = "leftarm"
- self.lc0 = cf(0,0,-1.5)
- self.ljoint = Instance.new("Motor6D")
- self.ljoint.Part0 = self.larm
- self.ljoint.Part1 = self.model.Left
- self.ljoint.C0 = self.lc0
- self.ljoint.Name = "leftarmweld"
- self.ljoint.Parent = cam
- self.lanimcf0 = cf()
- self.janimcf0 = cf()
- -- self.upperlarm = Instance.new("Part")
- -- self.upperlarm.Size = v3(0.5,0.5,1.6)
- -- self.upperlarm.TopSurface = Enum.SurfaceType.SmoothNoOutlines
- -- self.upperlarm.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
- -- self.upperlarm.CanCollide = false
- -- self.upperlarm.Parent = cam
- -- self.upperlarm.Name = "upperlarm"
- --
- -- self.lowerlarm = Instance.new("Part")
- -- self.lowerlarm.Size = v3(0.5,0.5,1.6)
- -- self.lowerlarm.TopSurface = Enum.SurfaceType.SmoothNoOutlines
- -- self.lowerlarm.BottomSurface = Enum.SurfaceType.SmoothNoOutlines
- -- self.lowerlarm.CanCollide = false
- -- self.lowerlarm.Parent = cam
- -- self.lowerlarm.Name = "lowerlarm"
- self.lshoulder = self.rootpart.CFrame * cf(-1,-1,-0.7)
- self.lhand = gun.model.Left
- character.grappart = self.lhand
- character.grab = character.grappart.Position
- self.larmik = ik.new()
- self.animdata = {
- walking = function()
- return 11,12,13,29,14
- end,
- running = function()
- return 18,5,8,20,10
- end,
- aiming = function()
- return 7,64,104,192,112
- end
- }
- self.aim = function(self,state)
- self.aiming = state
- local offset = (self.joint.Part1.CFrame:Inverse()*self.model.Aim.CFrame).p
- offset = self.joint.C0 * offset
- aimspring.t = state and offset or nv3
- local aimrotx = 0
- local aimroty = 1.6
- local aimrotz = 8
- local aimrot = v3(0,state and -aimroty or aimroty,state and -aimrotz or aimrotz)
- aimrotspring:impulse(aimrot)
- camera:setfov(state and 80-data.zoom or 80)
- character:setsprint(false)
- end
- local firedebounce = false
- self.fireround = function(self)
- if not firedebounce then
- firedebounce = true
- local s = gun.model.PrimaryPart.Fire:Clone()
- s.Parent = cam
- s:Play()
- local pos = not self.aiming and data.hiprecoilpos or data.aimrecoilpos
- local rot = not self.aiming and data.aimrecoilpos or data.aimrecoilpos
- local crot = not self.aiming and v3(data.hipmincamrot.X,rdm(data.hipmincamrot.Y,data.hipmaxcamrot.Y),0) or v3(data.aimmincamrot.X,rdm(data.aimmincamrot.Y,data.aimmaxcamrot.Y),0)
- recoil.pos:impulse(pos)
- recoil.rot:impulse(rot)
- camera.recoil:impulse(crot)
- wait(60/800)
- firedebounce = false
- end
- end
- local fakegrip = v3()
- local nah = cf()
- self.step = function(self,dt)
- for i,v in pairs(getch(self.model)) do v.Velocity = v3() end
- self.rarm.Velocity = v3()
- self.larm.Velocity = v3()
- local vel = char.HumanoidRootPart.Velocity
- local rvel = (char.HumanoidRootPart.CFrame:Inverse() - char.HumanoidRootPart.CFrame:Inverse().Position) * vel
- local walking = abs(sqrt(vel.X^2+vel.Z^2)) > 1
- local aimpos = aimspring.p
- local aimrot = aimrotspring.p
- local recoilpos = recoil.pos.p
- local recoilrot = recoil.rot.p
- local ax,ay,az = aimpos.X,aimpos.Y,aimpos.Z
- local arx,ary,arz = aimrot.X,aimrot.Y,aimrot.Z
- local rpx,rpy,rpz = recoilpos.X,recoilpos.Y,recoilpos.Z
- local rrx,rry,rrz = recoilrot.X,recoilrot.Y,recoilrot.Z
- local anims = {
- walking = data.anims.walking(),
- running = data.anims.running(),
- aiming = data.anims.aiming()
- }
- local anim = walking and not self.aiming and not character.running and lerp(self.walk,anims.walking(),0.2) or
- walking and not self.aiming and character.running and lerp(self.walk,anims.running(),0.2) or
- walking and self.aiming and lerp(self.walk,anims.aiming(),0.2) or lerp(self.walk,cf(),0.2)
- self.walk = anim
- aimpos = cf(ax,ay,az)
- aimrot = ang(arx,ary,arz)
- recoil.cf = cf(rpx,rpy,rpz)*ang(rad(1)*rrx,rad(1)*rry,rad(1)*rrz)
- self.janimcf0 = cf(self.janimcf0p.p)*ang(self.janimcf0r.p.X,self.janimcf0r.p.Y,self.janimcf0r.p.Z)
- self.lanimcf0 = cf(self.lanimcf0p.p)*ang(self.lanimcf0r.p.X,self.lanimcf0r.p.Y,self.lanimcf0r.p.Z)
- self.joint.C0 = cf(1,-1.2,-0.3)
- * recoil.cf
- * self.janimcf0
- self.joint.C1 = self.walk
- * aimpos
- * aimrot
- self.ljoint.C0 = self.lc0
- * self.lanimcf0
- self.larmc0 = lerp(self.larmc0,self.aiming and ang(0,rad(10),rad(-15)) or cf(),0.15)
- self.ljoint.C1 = self.larmc0
- if self.shooting then
- self:fireround()
- end
- end
- end
- end
- do --// Animation
- local self = animate
- self.inprogress = false
- self.play = function(self,animdata)
- local cache = {}
- self.inprogress = true
- for frame,framedata in pairs(animdata) do
- if gun[framedata[1]] then
- local m = framedata[1]
- local endp = framedata[2]
- local endr = framedata[3]
- local d = framedata[4]
- local start = gun[m]
- gun[m.."p"].t = endp
- gun[m.."r"].t = endr
- repeat wait() until gun[m.."p"].p.Magnitude >= endp.Magnitude*0.97 and gun[m.."r"].p.Magnitude >= endr.Magnitude*0.97
- if d then wait(d) end
- elseif framedata[1] == "weldmag" then
- local mw = gun.model.PrimaryPart.Mag
- cache.oldmagweld = mw
- mw.Parent = nil
- mw = Instance.new("Motor6D")
- mw.Part0 = gun.larm
- mw.Part1 = gun.model.Mag
- mw.Parent = cam
- mw.C0 = cf(0,0,-1.5)
- cache.newmagweld = mw
- elseif framedata[1] == "returnmag" then
- cache.oldmagweld.Parent = gun.model.PrimaryPart
- cache.newmagweld:Destroy()
- end
- end
- self.inprogress = true
- end
- end
- --// Main
- gun:new("M4A1")
- RunService.RenderStepped:Connect(function()
- gun.rootpart.CFrame = cam.CFrame
- local vel = char.HumanoidRootPart.Velocity
- local rvel = (char.HumanoidRootPart.CFrame:Inverse() - char.HumanoidRootPart.CFrame:Inverse().Position) * vel
- local walking = abs(sqrt(vel.X^2+vel.Z^2)) > 1
- local camrecoil = camera.recoil.p
- local crx,cry,crz = camrecoil.X,camrecoil.Y,camrecoil.Z
- camera.cf = ang(rad(1)*crx,rad(1)*cry,rad(1)*crz)
- cam.CFrame = cam.CFrame
- * camera.cf
- cam.FieldOfView = camera.fov.p
- gun:step()
- end)
- UserInput.InputBegan:Connect(function(obj)
- if obj.KeyCode == Enum.KeyCode.LeftShift then
- character:setsprint(true)
- elseif obj.KeyCode == Enum.KeyCode.R then
- local data = gun:getdata()
- animate:play(data.anims.reload())
- end
- if obj.UserInputType == Enum.UserInputType.MouseButton1 then
- gun.shooting = true
- --gun:fireround()
- elseif obj.UserInputType == Enum.UserInputType.MouseButton2 then
- gun:aim(true)
- end
- end)
- UserInput.InputEnded:Connect(function(obj)
- if obj.KeyCode == Enum.KeyCode.LeftShift then
- character:setsprint(false)
- end
- if obj.UserInputType == Enum.UserInputType.MouseButton1 then
- gun.shooting = false
- elseif obj.UserInputType == Enum.UserInputType.MouseButton2 then
- gun:aim(false)
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement