Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Here is a copy of my weapon client script.
- This script is in charge of any animations for the weapon, and rendering other characters .
- I went through and commented out some functions to explain what they do
- GAME LINK: https://www.roblox.com/games/496469360/Gun-Framework?refPageId=5db09d5f-b7e1-4629-889c-c561f25bd29c
- ]]
- math.randomseed(tick())
- local wfc = game.WaitForChild
- local ffc = game.FindFirstChild
- local cf = CFrame.new
- local fea = CFrame.fromEulerAnglesXYZ
- local v3 = Vector3.new
- local ffa = CFrame.fromAxisAngle
- local ca = CFrame.Angles
- local v2 = Vector2.new
- local atan = math.atan
- local abs = math.abs
- local atan2 = math.atan2
- local asin = math.asin
- local tan = math.tan
- local pi = math.pi
- local huge = math.huge
- local rad = math.rad
- local sqrt = math.sqrt
- local deg = math.deg
- local sin = math.sin
- local new = Instance.new
- local random = math.random
- local cos = math.cos
- local acos = math.acos
- local function isNaN(v) if tostring(v):find("NAN") or tostring(v):find("INF") then return true end return false end
- local sign = function(x) if x > 0 then return 1 elseif x < 0 then return -1 else return 0 end end
- local clamp = function(v, l, h) if v > h then return h elseif v < l then return l end return v end
- local biasedRandom = function() return random(900, 1100)/1000 end -- I'll do this later
- local srandom = function() return (random() - .5) * 2 end
- local draw = function(v) local p = Instance.new("Part", game.Workspace) p.Anchored = true p.Size = v3() p.CFrame = cf(v) end
- local ease = function(x, y, a) return x + (y - x) * a end
- local function sw(x) local s = x % 2 local x = s % 1 if s < 1 then return (x*x*(3 - 2*x) - .5)*2 end return (1 - x*x*(3 - 2*x) - .5)*2 end
- --public class Probability
- --{
- -- public static float InRangeOfExponentialPDF(float x, float min, float max)
- -- {
- -- /**
- -- * Use a linearly distributed random number (x) to get a
- -- * random number in the range of an exponential PDF.
- -- *
- -- * Parameters:
- -- * x - random number from a linearly distributed range in [0,1]
- -- * min/max - range of values in pdf
- -- */
- --
- -- float range = max - min;
- -- float density = range - (range * Mathf.Exp(-range * x)); // pdf
- -- return density + min;
- -- }
- --}
- local gs = function(s) return game:GetService(s.."Service") end
- local rs = gs("Run")
- local uis = gs("UserInput")
- local cam = game.Workspace.CurrentCamera
- local player = game.Players.LocalPlayer
- local modules = wfc(game.ReplicatedStorage, "Modules")
- local events = wfc(game.ReplicatedStorage, "Events")
- local particles = wfc(game.ReplicatedStorage, "Particles")
- local spring = require(wfc(modules, "Spring"))
- local util = require(wfc(modules, "Util"))
- local Ragdoll = require(script.Ragdoll)
- local Indicator = require(script.Indicator)
- local BulletHole = require(script.BulletHole)
- local spring = {}
- local animate = {}
- local physics = {}
- local vector = {}
- local cframe = {}
- local network = {}
- local weapon = {}
- local camera = {}
- local ui = {}
- local input = {}
- local character = {}
- local robo = {}
- -- Custom tick
- -- can control time ;D
- local tick = {
- tick = tick;
- last = 0;
- lastReal = tick();
- speed = 1;
- }
- setmetatable(tick, {
- __call = function()
- return tick:Get()
- end
- })
- function tick:Get()
- local t = self.tick()
- local time = self.speed * (t - self.lastReal) + self.last
- self.last = time
- self.lastReal = t
- return time
- end
- function tick:SetSpeed(speed)
- tick.speed = speed
- tick:Get()
- end
- do -- Spring Scope
- function spring.new(start, d, s)
- start = start or 0
- local t0 = tick()
- local p0 = start
- local v0 = 0 * start
- local t = start
- local d = d or 1
- local s = s or 1
- local function update(tick)
- local x = tick - t0
- local c0 = p0 - t
- if s == 0 then
- return p0, 0
- elseif d < 1 then
- local c = (1 - d*d)^.5
- local c1 = (v0/s + d*c0)/c
- local co = cos(c * s*x)
- local si = sin(c * s*x)
- local e = 2.718^(d*s*x)
- return t + (c0*co + c1*si)/e,
- s*((c*c1 - d*c0)*co - (c*c0 + d*c1)*si)/e
- else
- local c1 = v0/s + c0
- local e = 2.718^(s*x)
- return t + (c0 + c1*s*x)/e,
- s * (c1 - c0 - c1*s*x)/e
- end
- end
- return setmetatable({
- accelerate = function(_, a)
- local time = tick()
- local p, v = update(time)
- p0 = p
- v0 = v + a
- t0 = time
- end;
- }, {
- __newindex = function(_, index, value)
- local time = tick()
- if index == "p" then
- local p, v = update(time)
- p0, v0 = value, v
- elseif index == "v" then
- local p, v = update(time)
- p0, v0 = p, value
- elseif index == "a" then
- local p, v = update(time)
- p0, v0 = p, v + value
- elseif index == "t" then
- p0, v0 = update(time)
- t = value
- elseif index == "d" then
- p0, v0 = update(time)
- d = value < 0 and 0 or value < 1 and value or 1
- elseif index == "s" then
- p0, v0 = update(time)
- s = value < 0 and 0 or value
- end
- t0 = time
- end;
- __index = function(_, index)
- if index == "p" then -- Position
- local p, v = update(tick())
- return p
- elseif index == "v" then -- Velocity
- local p, v = update(tick())
- return v
- elseif index == "a" then -- Acceleration
- local x = tick() - t0
- local c0 = p0 - t
- if s == 0 then
- return 0
- elseif d < 1 then
- local c =(1-d*d)^0.5
- local c1 =(v0/s+d*c0)/c
- return s * s *((d*d*c0 - 2*c*d*c1 - c*c*c0)*cos(c*s*x)
- +(d*d*c1 + 2*c*d*c0 - c*c*c1)*sin(c*s*x))
- /2.718^(d*s*x)
- else
- local c1 =v0/s + c0
- return s*s*(c0 - 2*c1 + c1*s*x)
- /2.718^(s*x)
- end
- elseif index == "t" then -- Target
- return t
- elseif index == "d" then -- Damp
- return d
- elseif index == "s" then -- Speed
- return s
- elseif index == "m" then -- Magnitude
- local p, v = update(tick())
- return p.magnitude
- end
- end;
- })
- end
- end
- --
- local veloSpring = spring.new(v2(), .5, 13)
- local bounceSpring = spring.new(0, .4, 18)
- local aimSpring = spring.new(1, 1, 15)
- local magnitudeSpring = spring.new(0, 1, 12)
- --
- do -- Animation Scope
- setmetatable(animate, {
- __call = function(...)
- return animate.loadAnim(...)
- end;
- })
- animate.running = {}
- animate.tweens = {
- linear = function(x) return x end;
- inQuad = function(x) return x*x end;
- inCubic = function(x) return x*x*x end;
- inQuart = function(x) return x*x*x*x end;
- inQuint = function(x) return x*x*x*x*x end;
- inSextic = function(x) return x*x*x*x*x*x end;
- inSeptic = function(x) return x*x*x*x*x*x*x end;
- inOctic = function(x) return x*x*x*x*x*x*x*x end;
- outQuad = function(x) local m = x-1 return 1 - m*m end;
- outCubic = function(x) local m = x-1 return 1 + m*m*m end;
- outQuart = function(x) local m = x-1 return 1 - m*m*m*m end;
- outQuint = function(x) local m = x-1 return 1 + m*m*m*m*m end;
- outSextic = function(x) local m = x-1 return 1 - m*m*m*m*m*m end;
- outSeptic = function(x) local m = x-1 return 1 + m*m*m*m*m*m*m end;
- outOctic = function(x) local m = x-1 return 1 - m*m*m*m*m*m*m*m end;
- inOutQuad = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t else return 1 - m*m * 2 end end;
- inOutCubic = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t else return 1 + m*m*m * 4 end end;
- inOutQuart = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t*t else return 1 - m*m*m*m * 8 end end;
- inOutQuint = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t*t*t else return 1 + m*m*m*m*m * 16 end end;
- inOutSextic = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t*t*t*t else return 1 - m*m*m*m*m*m * 3 end end;
- inOutSeptic = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t*t*t*t*t else return 1 + m*m*m*m*m*m*m * 64 end end;
- inOutOctic = function(x) local m = x-1 local t = x*2 if t < 1 then return x*t*t*t*t*t*t*t else return 1 - m*m*m*m*m*m*m*m * 128 end end;
- smooth = function(x) return x*x*(3 - 2*x) end;
- smoother = function(x) x = x*x*(3 - 2*x) return x*x*(3 - 2*x) end;
- spring = function(x) return 1 + (-2.72^(-6.9*x) * cos(2*pi*x*-3.2)) end;
- softSpring = function(x) return 1 + (-2.72^(-7.5*x) * cos(2*pi*x*-1.6)) end;
- inBack = function(x) local k = 1.70158 return x*x*(x*(k+1) - k) end;
- inOutBack = function(x) local m = x-1 local t = x*2 local k = 1.70158 * 1.525 if(x < 0.5) then return x*t*(t*(k+1) - k) else return 1 + 2*m*m*(2*m*(k+1) + k) end end;
- outBack = function(x) local m = x-1 local k = 1.70158 return 1 + m*m*(m*(k+1) + k) end;
- inCirc = function(x) return 1 - sqrt(1 - x*x) end;
- inOutCirc = function(x) local m = x-1 local t = x*2 if(t < 1) then return (1 - sqrt(1 - t*t))*0.5 else return (sqrt( 1 - 4*m*m) + 1) * 0.5 end end;
- outCirc = function(x) local m = x-1 return sqrt( 1 - m*m) end;
- outBounce = function(x)
- local r = 1 / 2.75
- local k1 = 1 * r
- local k2 = 2 * r
- local k3 = 1.5 * r
- local k4 = 2.5 * r
- local k5 = 2.25 * r
- local k6 = 2.625 * r
- local k0 = 7.5625
- local t = k0
- if x < k1 then return k0 * x*x
- elseif x < k2 then t = x - k3 return k0 * t*t + 0.75
- elseif x < k4 then t = x - k5 return k0 * t*t + 0.9375
- else t = x - k6 return k0 * t*t + 0.984375 end
- end;
- inBounce = function(x)
- x = 1 - x
- local r = 1 / 2.75
- local k1 = 1 * r
- local k2 = 2 * r
- local k3 = 1.5 * r
- local k4 = 2.5 * r
- local k5 = 2.25 * r
- local k6 = 2.625 * r
- local k0 = 7.5625
- local t = k0
- if x < k1 then return 1 - (k0 * x*x)
- elseif x < k2 then t = x - k3 return 1 - (k0 * t*t + 0.75)
- elseif x < k4 then t = x - k5 return 1 - (k0 * t*t + 0.9375)
- else t = x - k6 return 1 - (k0 * t*t + 0.984375) end
- end;
- }
- animate.loadAnim = function(_, k)
- local this = {}
- this.data = k
- this.start = 0
- function this:Run()
- local t = tick()
- this.start = t
- this.starts = {}
- for i, o in pairs(this.data) do
- this.starts[i] = o.object[o.prop]
- end
- table.insert(animate.running, this)
- end;
- function this:Cancel()
- end
- function this:Stop()
- for i, anim in pairs(animate.running) do
- if anim == this then
- animate.running[i] = nil
- end
- end
- local data = this.data
- for i, o in pairs(data) do
- o.object[o.prop] = o.keys[#o.keys].cf
- end
- end
- return this
- end
- local function update()
- for _, anim in pairs(animate.running) do
- local t = tick()
- local elapsed = t - anim.start
- local data = anim.data
- for i, o in pairs(data) do
- local key, it = o.keys[1], 1
- for iit, k in pairs(o.keys) do
- if elapsed < k.time and elapsed > key.time then
- key = k
- it = iit
- end
- end
- local prev = o.keys[it - 1]
- local prevTime = prev and prev.time or 0
- local next = o.keys[it + 1]
- if not next then
- anim:Stop()
- break
- end
- local a = (elapsed - prevTime)/(key.time - prevTime)
- o.object[o.prop] = next.cf:lerp(key.cf, 1 - animate.tweens[key.style](a))
- end
- end
- end
- rs:BindToRenderStep("Animation Update", 200, update)
- end
- do -- Physics Scope
- local Meta = {__index = physics}
- local PhysicObjects = {}
- physics.Gravity = -9.86
- physics.Position = v3()
- physics.Rotation = v3()
- physics.Velocity = v3()
- physics.RotVelocity = v3()
- physics.LastUpdate = 0
- physics.Attached = nil
- physics.Enabled = true
- function physics.new(part, timeout)
- local self = setmetatable({}, Meta)
- self.LastUpdate = tick()
- self.TimeOut = tick() + timeout
- if part then
- self:SetAttached(part, true)
- end
- table.insert(PhysicObjects, self)
- return self
- end
- function physics:Update(time)
- if not self.Enabled or not self.Attached then return end
- if self.TimeOut and tick() >= self.TimeOut then
- self:Destroy()
- return
- end
- local dt = (time - self.LastUpdate) * tick.speed
- self.LastUpdate = time
- local v = self.Velocity
- local p = self.Position
- local r = self.Rotation
- local rV = self.RotVelocity
- local g = self.Gravity
- local cV = v + v3(0, g * dt, 0)
- local cP = p + cV
- local cR = r + rV * dt
- self.Velocity = cV
- self.Position = cP
- self.Rotation = cR
- self.Attached.CFrame = self:GetCFrame()
- end
- function physics:GetCFrame()
- local r = self.Rotation
- return cf(self.Position) * fea(r.X, r.Y, r.Z)
- end
- function physics:Toggle(enabled)
- self.Enabled = enabled
- end
- function physics:SetAttached(part, currentCFrame)
- self.Attached = part
- if currentCFrame then
- local cframe = part.CFrame
- self.Position = cframe.p
- self.Rotation = v3(cframe:toEulerAnglesXYZ())
- end
- end
- function physics:Destroy()
- for index, obj in ipairs(PhysicObjects)do
- if obj == self then
- table.remove(PhysicObjects, index)
- if self.Attached then
- self.Attached:Destroy()
- end
- break
- end
- end
- end
- game:GetService("RunService").Heartbeat:connect(function()
- local time = tick()
- for _, obj in next, PhysicObjects do
- obj:Update(time)
- end
- end)
- end
- -- old
- --do -- Phyiscs Scope
- -- local gravity = -9.86
- -- physics.objects = {}
- --
- --
- -- function physics.new(attached)
- -- local this = {
- -- velocity = v3();
- -- position = v3();
- -- rotation = v3();
- -- rotVelocity = v3();
- -- gravity = gravity;
- --
- -- attached = nil;
- -- enabled = true;
- -- }
- --
- --
- -- function this.step(dt)
- -- if not this.enabled then return end
- --
- -- local v = this.velocity
- -- local p = this.position
- -- local r = this.rotation
- -- local rV = this.rotVelocity
- -- local g = this.gravity
- --
- -- local cV = v + v3(0, g * dt, 0)
- -- local cP = p + cV
- -- local cR = r + rV * dt
- --
- -- this.velocity = cV
- -- this.position = cP
- -- this.rotation = cR
- -- end
- --
- --
- -- function this:toCFrame()
- -- local r = this.rotation
- -- return cf(this.position) * ca(r.x, r.y, r.z)
- -- end
- --
- --
- -- function this:Toggle(bool)
- -- this.enabled = bool
- -- end
- --
- --
- -- function this:SetAttached(part, useCurrent)
- -- this.attached = part
- --
- -- if useCurrent then
- -- this.position = part.CFrame.p
- -- this.rotation = v3(part.CFrame:toEulerAnglesXYZ()) -- im cheating
- -- end
- -- end
- --
- --
- -- if attached then
- -- this:SetAttached(attached, true)
- -- end
- --
- -- table.insert(physics.objects, this)
- --
- -- return this
- -- end
- --
- --
- -- local function physicsStep(dt)
- -- for i = 1, #physics.objects do
- -- local po = physics.objects[i]
- -- po.step(dt)
- --
- -- if po.attached then
- -- po.attached.CFrame = po:toCFrame()
- -- end
- -- end
- -- end
- --
- --
- -- rs.Heartbeat:connect(physicsStep)
- --end
- do -- Vector Scope
- function vector.clamp(v, h, l)
- return v3(
- clamp(v.x, h, l),
- clamp(v.y, h, l),
- clamp(v.z, h, l)
- )
- end
- end
- do -- cfame scope
- function cframe.squashRotMatrix(c, scale)
- local matrix = {c:components()}
- for i = 4, 12 do
- matrix[i] = matrix[i] * scale
- end
- return cf(unpack(matrix))
- end
- end
- do -- Network module
- local this = network;
- local updateStep = 1/60 -- 1/5
- -- player.Chatted:connect(function(msg)
- -- if msg:sub(1, 4) == "/rep" then
- -- if tonumber(msg:sub(6, string.len(msg)))then
- -- updateStep = tonumber(msg:sub(6, string.len(msg)))
- -- end
- -- end
- -- end)
- local bounceEvent = events.Bounce
- local requests = {}
- local players = {}
- local update = false
- local updateTick = tick()
- local dataPack = {
- [1] = {Name = "position"; Default = v3()};
- [2] = {Name = "rotation"; Default = v2()};
- [3] = {Name = "joints"; Default = {cf(0, 1.5, 0); cf(-.5, -2, 0); cf(.5, -2, 0); cf(-1.5, 0, 0); cf(1.5, 0, 0)}};
- }
- local bounceOut, bounceIn, bounceDataLength = {}, {}, 0
- for i, data in pairs(dataPack) do
- bounceIn[i] = data.Name
- bounceOut[data.Name] = i;
- bounceDataLength = bounceDataLength + 1
- end
- function network:bounce(name, data)
- requests[bounceOut[name]] = data
- if not update then update = true end -- noticed setting value to same is more cpu than checking a value
- end
- function network:send(name, data)
- events[name]:FireServer(data)
- end
- function network:fastbounce(name, data)
- events.FastBounce[name]:FireServer(data)
- end
- function network:connect(event, func)
- events.FastBounce[event].OnClientEvent:connect(func)
- end
- bounceEvent.OnClientEvent:connect(function(player, data)
- local p = players[player.Name]
- if not p then
- players[player.Name] = {}
- p = players[player.Name]
- end
- for i = 1, bounceDataLength do
- if data[i] then
- p[bounceIn[i]] = data[i]
- end
- end
- end)
- rs:BindToRenderStep("bounce", Enum.RenderPriority.Last.Value, function()
- if update and tick() - updateTick > updateStep then
- bounceEvent:FireServer(requests)
- requests = {}
- update = false
- updateTick = tick()
- end
- end)
- local function addPlayer(player)
- local data = {}
- data.player = player
- for _, x in pairs(dataPack)do
- data[x.Name] = x.Default
- end
- players[player.Name] = data
- end
- game.Players.PlayerAdded:connect(addPlayer)
- game.Players.PlayerRemoving:connect(function(player) players[player.Name] = nil end)
- for _, plr in ipairs(game.Players:GetPlayers()) do addPlayer(plr) end
- network.players = players
- end
- do -- Character Scope
- character.char = player.Character or player.CharacterAdded:wait()
- character.distance = 0
- character.lastPosition = wfc(character.char, "HumanoidRootPart").CFrame.p
- character.speedSpring = spring.new(16, 1, 12)
- character.heightSpring = spring.new(0, 1, 17)
- character.state = "idle"
- character.stance = "stand"
- character.alive = false
- character.lastJump = 0
- character.jumpTime = .7
- character.lastSlide = 0
- character.slideTime = .7
- character.speeds = {
- idle = 17;
- sprint = 24;
- aim = 12; }
- character.stanceMult = {
- stand = 1;
- crouch = .6;
- prone = .2; }
- character.stances = {
- stand = 0;
- crouch = -1.2;
- prone = -2.2; }
- function character:SetStance(stance)
- if not character.char then return end
- local hrp = ffc(character.char, "HumanoidRootPart")
- if not hrp then return end
- if not weapon.equipped then return end
- local t = tick()
- if stance == character.stance then
- stance = "stand"
- end
- local ground = character:CheckGround()
- if stance == "crouch" and input.keysDown.leftshift and not(t - character.lastSlide < character.slideTime) and ground then
- weapon:SetState("idle", true)
- character.lastSlide = t
- character.pushForce.Force = hrp.CFrame.lookVector * v3(1, 0, 1) * 3200
- weapon:Push(v3(0, -1, -.7).unit, 3.4343563425)
- spawn(function()
- wait(.13)
- character.pushForce.Force = v3()
- end)
- end
- if character.stance == "crouch" and stance ~= "crouch" then
- weapon:SetState("idle")
- end
- character.stance = stance
- character.heightSpring.t = character.stances[stance]
- weapon:SetStance(stance)
- end
- function character:CheckGround()
- local hrp = ffc(character.char, "HumanoidRootPart")
- if not hrp then return end
- local dRay = Ray.new(hrp.CFrame.p, v3(0, -3.2, 0))
- local dHit, dPos = game.Workspace:FindPartOnRayWithIgnoreList(dRay, {game.Workspace.Ignore; character.char; cam; weapon.model;})
- return dHit, dPos
- end
- function character:Jump()
- local t = tick()
- local hrp = ffc(character.char, "HumanoidRootPart")
- if not hrp then return end
- if t - character.lastJump < character.jumpTime then return else character.lastJump = t end
- local ignore = {game.Workspace.Ignore; character.char; cam; weapon.model;}
- local bp = hrp.CFrame.p - v3(0, .1, 0)
- local lv = hrp.CFrame.lookVector
- local bv = hrp.Velocity
- local speed = character.speedSpring.p
- local ground = character:CheckGround()
- if ground then
- local mRay = Ray.new(bp - v3(0, .7, 0), lv * 3.9)
- local mHit, mPos = game.Workspace:FindPartOnRayWithIgnoreList(mRay, ignore)
- local uRay = Ray.new(bp + v3(0, 2.718/1.8, 0), lv * 7 + v3(0, 6, 0))
- local uHit, uPos = game.Workspace:FindPartOnRayWithIgnoreList(uRay, ignore)
- -- util.drawRay(mRay.Origin, mPos)
- -- util.drawRay(uRay.Origin, uPos)
- if mHit and not uHit then
- weapon.vaultSpring:accelerate(18)
- hrp.Velocity = bv + v3(0, 30, 0) + lv * v3(0, 0, 40)
- spawn(function()
- wait(.1)
- hrp.Velocity = bv + v3(0, 5, 0)
- end)
- else
- hrp.Velocity = bv + v3(0, (400 * 3)^.5, 0)
- end
- end
- end
- local function stateChange(state, lastState)
- state = state.Name:lower()
- if state == "landed" then
- weapon:Push(v3(0, -1, 0), .7)
- end
- end
- local function filterChild(child)
- if child:IsA("BasePart") then
- child.Transparency = 1
- elseif child:IsA("Clothing") or child:IsA("Hat") then
- child:Destroy()
- end
- end
- local function characterAdded(char)
- character.char = char
- spawn(function()
- wfc(char, "Left Arm"):Destroy()
- wfc(char, "Right Arm"):Destroy()
- local head = wfc(char, "Head")
- local humanoid = wfc(char, "Humanoid")
- local hrp = wfc(char, "HumanoidRootPart")
- humanoid.AutoRotate = false
- humanoid.JumpPower = 0
- repeat wait()
- if ffc(head, "face") then
- head.face:Destroy()
- end
- until not ffc(head, "face")
- for _, child in ipairs(char:GetChildren()) do
- filterChild(child)
- end
- --character.controlForce = new("BodyThrust", hrp)
- --character.controlForce.MaxForce = v3(1, 0, 1) * 1000
- character.pushForce = new("BodyForce", hrp)
- character.pushForce.Force = v3()
- weapon:Toggle(true)
- char.DescendantAdded:connect(filterChild)
- humanoid.StateChanged:connect(stateChange)
- humanoid.Died:connect(function() weapon:Toggle(false) end)
- end)
- end
- local function update()
- if not ffc(character.char, "HumanoidRootPart") then return end
- if not ffc(character.char, "Humanoid") then return end
- local hrp = character.char.HumanoidRootPart
- local humanoid = character.char.Humanoid
- local speed = character.speedSpring.p
- local position = hrp.CFrame.p * v3(1, 0, 1)
- character.distance = character.distance + (position - character.lastPosition).magnitude * .9
- character.lastPosition = position
- local velocity = hrp.Velocity * v3(1, 0, 1)
- magnitudeSpring.t = velocity.magnitude > 0 and velocity.magnitude or 0
- local w, a, s, d = input.keysDown.w, input.keysDown.a, input.keysDown.s, input.keysDown.d
- local dir = v2()
- if w and not s then
- dir = v2(dir.x, 1)
- elseif s and not w then
- dir = v2(dir.x, -1)
- else
- dir = v2(dir.x, 0)
- end
- if a and not d then
- dir = v2(-1, dir.y)
- elseif d and not a then
- dir = v2(1, dir.y)
- else
- dir = v2(0, dir.y)
- end
- if dir == v2() then
- character.speedSpring.t = 0
- else
- character.speedSpring.t = character.speeds[character.state] * character.stanceMult[character.stance]
- end
- -- Buggy custom movement
- -- local direction = v3(dir.x, 0, -dir.y)
- -- local velocity = hrp.Velocity * v3(1, 0, 1)
- --
- -- character.controlForce.Force = (direction.magnitude > 1 and direction.unit or direction) * 1900)
- -- hrp.Velocity = v3(0, hrp.Velocity.y, 0) + (velocity.magnitude > 0 and velocity.unit * clamp(velocity.magnitude, 0, speed) or velocity)
- humanoid.WalkSpeed = speed * tick.speed
- end
- characterAdded(character.char)
- player.CharacterAdded:connect(characterAdded)
- rs:BindToRenderStep("CharacterUpdate", 150, update)
- end
- do -- Weapon Scope
- local base = new("Part", game.Workspace)
- base.Size = v3(.2, .2, .2)
- base.Anchored = true
- base.CanCollide = false
- base.Transparency = 1
- weapon.base = base
- weapon.weapons = {
- require(game.ReplicatedStorage.Weapons["Anaconda"]);
- require(game.ReplicatedStorage.Weapons["G36"]);
- require(game.ReplicatedStorage.Weapons["G17"]);
- require(game.ReplicatedStorage.Weapons["AK-74B"]);
- }
- weapon.equipSpring = spring.new(1, 1, 9)
- weapon.positionSpring = spring.new(v3(), .7, aimSpring.s)
- weapon.rotationSpring = spring.new(cf().lookVector, weapon.positionSpring.d, weapon.positionSpring.s)
- weapon.swaySpring = spring.new(v2(), .6, 13)
- weapon.sprintSpring = spring.new(0, weapon.positionSpring.d, weapon.positionSpring.s+1)
- weapon.tiltSpring = spring.new(v2(), 1, 12)
- weapon.pushSpring = spring.new(v3(), 1, 7)
- weapon.vaultSpring = spring.new(0, 1, weapon.positionSpring.s)
- weapon.rRotSpring = spring.new(v3(), .7, 13)
- weapon.rKickSpring = spring.new(v2(), 1, 25)
- weapon.rCamRotSpring = spring.new(v3(), 1, 10)
- weapon.rCamKickSpring = spring.new(v2(), 1, 23)
- weapon.firing = false
- weapon.lastfire = tick()
- weapon.shown = true
- function weapon:SetStance(stance)
- end
- function weapon:EjectShell()
- local shell = weapon.model.Eject:Clone()
- shell.Parent = game.Workspace.Ignore
- shell.Transparency = 0
- local dir = shell.CFrame.lookVector
- local po = physics.new(shell, .7)
- po.Velocity = dir * .7 + v3(0, .1, 0) + v3(1, 0, 1) * srandom()/6
- po.RotVelocity = v3(pi * srandom(), pi * srandom())
- po.Gravity = -3
- -- po:Update(0)
- end
- function weapon:Push(d, m)
- weapon.pushSpring:accelerate(d * m)
- end
- function weapon:SetState(state, override)
- if not weapon.shown then return end
- if not input.keysDown then return end
- if state == "idle" then
- if input.right then
- state = "aim"
- elseif input.keysDown.leftshift and not override then
- state = "sprint"
- end
- end
- if state == "idle" and input.left then
- weapon.firing = true
- end
- if state == "aim" then
- aimSpring.t = 0
- else
- aimSpring.t = 1
- end
- if state == "sprint" then
- weapon.sprintSpring.t = 1
- weapon.firing = false
- else
- weapon.sprintSpring.t = 0
- end
- local stateCf = weapon.equipped[state]
- if stateCf then
- stateCf = stateCf[1]
- else
- stateCf = weapon:GetAimSpot()
- end
- character.speedSpring.t = character.speeds[state]
- ui.crossSpring.t = ui.crossAmounts[state]
- weapon.positionSpring.t = stateCf.p
- weapon.rotationSpring.t = stateCf.lookVector
- character.state = state
- weapon.lastFire = tick()
- end
- function weapon:SetMode(v)
- -- Fire Mode
- -- Three round burst
- -- Single shot
- -- Automatic
- end
- function weapon.makeArms()
- if weapon.left then weapon.left:Destroy() end
- if weapon.right then weapon.right:Destroy() end
- weapon.left = game.ReplicatedStorage.Arm:Clone()
- weapon.left.Parent = game.Workspace.Ignore
- util.weldModel(weapon.left, weapon.left.PrimaryPart)
- weapon.right = weapon.left:Clone()
- weapon.right.Parent = game.Workspace.Ignore
- end
- function weapon:Toggle(bool)
- weapon.shown = bool
- if not weapon.shown then
- weapon.firing = false
- end
- end
- function weapon:Load(slot)
- if slot == weapon.loaded then return end
- if weapon.model then weapon.model:Destroy() end
- weapon.loaded = slot
- weapon.equipped = weapon.weapons[slot]
- if not weapon.equipped then return end
- weapon.model = weapon.equipped.model:Clone()
- weapon.model.Parent = game.Workspace
- local flash = ffc(weapon.model.Barrel, "Flash")
- if not flash then
- flash = particles.Flash:Clone()
- flash.Parent = weapon.model.Barrel
- end
- flash.Texture = weapon.equipped.FlashImg
- BulletHole.SetDecal(weapon.equipped.BulletHole.Texture)
- BulletHole.SetSize(weapon.equipped.BulletHole.Size)
- local wep = weapon.equipped
- if ffc(weapon.model, "slide") then
- util.weldModel(weapon.model, weapon.model.PrimaryPart, ffc(weapon.model, "sights"))
- util.weld(weapon.model.sights, weapon.model.slide)
- else
- util.weldModel(weapon.model, weapon.model.PrimaryPart)
- end
- for i, v in pairs(weapon.model:GetChildren()) do
- if v:IsA("BasePart") then
- v.Anchored = false
- v.CanCollide = false
- end
- end
- local weld = new("Motor6D", base)
- weld.Part0 = base
- weld.Part1 = weapon.model.PrimaryPart
- weapon:SetState("idle")
- weapon.firing = false
- if ffc(weapon.model, "slide") and weapon.equipped.slideAnimation then
- weapon.slideAnim = animate({{
- object = wfc(weapon.model.PrimaryPart, "slide");
- prop = "C1";
- keys = {
- {
- time = 0;
- style = "linear";
- cf = cf(0, 0, 0);
- };
- {
- time = .1;
- style = "linear";
- cf = cf(0, 0, .3);
- };
- {
- time = .2;
- style = "linear";
- cf = cf();
- };
- };
- };})
- end
- weapon.rRotSpring.d = wep.recoilRotDamp or weapon.rRotSpring.d
- weapon.rRotSpring.s = wep.recoilRotSpeed or weapon.rRotSpring.s
- weapon.rKickSpring.d = wep.recoilKickDamp or weapon.rKickSpring.d
- weapon.rKickSpring.s = wep.recoilKickSpeed or weapon.rKickSpring.s
- weapon.rCamRotSpring.d = wep.camRecoilRotDamp or weapon.rCamRotSpring.d
- weapon.rCamRotSpring.s = wep.camRecoilRotSpeed or weapon.rCamRotSpring.s
- weapon.rCamKickSpring.d = wep.camRecoilKickDamp or weapon.rCamKickSpring.d
- weapon.rCamKickSpring.s = wep.camRecoilKickSpeed or weapon.rCamKickSpring.s
- end
- function weapon:Scroll(v)
- local slot = weapon.loaded + v
- if slot > #weapon.weapons then
- slot = slot - #weapon.weapons
- elseif slot == 0 then
- slot = #weapon.weapons
- end
- weapon.equipSpring.t = 1
- weapon.equipSpring.p = 0
- weapon:Load(slot)
- end
- function weapon:GetAimSpot()
- if not weapon.equipped then return end
- if not weapon.model then return end
- if not ffc(weapon.model, "Sight") then return end
- if not weapon.model.PrimaryPart then return end
- return weapon.model.Sight.CFrame:inverse() * weapon.model.PrimaryPart.CFrame
- end
- local function BulletRayCast()
- local rays = 0
- local hit, pos, normal
- local start = weapon.model.Barrel.CFrame.p
- local last = start
- local xaxis = (weapon.model.Barrel.CFrame * ca(srandom() * rad(.1), srandom() * rad(.1), 0)).lookVector * 100
- local yaxis = weapon.model.Barrel.CFrame:vectorToWorldSpace(v3(1, 0, 0)):Cross(xaxis).unit
- local grav = -.2
- local v0 = 0 -- initial velocity
- local x0 = 0 -- initial position
- local t = 0
- repeat -- EgoMoose
- local yvalue = (grav/2) * t^2 + t * v0 + x0
- local nextPos = start + xaxis * t + yaxis * yvalue
- local ray = Ray.new(last, (nextPos - last))
- hit, pos, normal = game.Workspace:FindPartOnRayWithIgnoreList(ray, {game.Workspace.Ignore; character.char; cam; weapon.model;})
- rays = rays + 1
- last = nextPos
- t = t + 0.5
- -- util.drawRay(ray.Origin, pos)
- -- draw(pos)
- until hit or rays > 10
- return hit, pos , normal
- end
- function weapon:LateFire()
- if weapon.equipped.eject then
- weapon:EjectShell()
- end
- end
- function weapon.fire()
- if not weapon.shown then return end
- if not weapon.equipped then return end
- if not weapon.firing then return end
- if character.state == "sprint" then weapon:SetState("idle", true) end
- if tick() - weapon.lastfire < weapon.equipped.rof then return end
- local wepRecoil = weapon.equipped.recoil
- local camRecoil = weapon.equipped.camRecoil
- weapon.rRotSpring.a = (v3(biasedRandom() * wepRecoil.y, biasedRandom() * wepRecoil.z * srandom(), biasedRandom() * wepRecoil.z * srandom()))
- weapon.rKickSpring.a = (v2(biasedRandom() * wepRecoil.x, biasedRandom() * wepRecoil.x))
- weapon.rCamRotSpring.a = (v3(biasedRandom() * camRecoil.y, biasedRandom() * camRecoil.z * srandom(), biasedRandom() * camRecoil.z * srandom()))
- weapon.rCamKickSpring.a = (v2(biasedRandom() * camRecoil.x, biasedRandom() * camRecoil.x))
- weapon.lastfire = tick()
- if weapon.slideAnim then
- weapon.slideAnim:Run()
- end
- local fireSound = new("Sound", weapon.model.PrimaryPart)
- fireSound.Name = "Fire"
- fireSound.SoundId = "rbxassetid://"..weapon.equipped.shoot
- fireSound:Play()
- fireSound.Volume = .7
- fireSound.Pitch = .95
- delay(fireSound.TimeLength, function()
- fireSound:Destroy()
- end)
- local flash = ffc(weapon.model.Barrel, "Flash")
- if flash then
- flash:Emit(1)
- end
- local hit, pos, normal = BulletRayCast()
- if hit then
- -- local particleBase = game.ReplicatedStorage.Particles.Centered:Clone()
- -- particleBase.Parent = game.Workspace.Ignore
- -- particleBase.CFrame = cf(pos)
- -- local particle = game.ReplicatedStorage.Particles.Ground:Clone()
- -- particle.Acceleration = -cam.CFrame.lookVector * 5 + v3(0, -40, 0)
- -- particle.Parent = particleBase
- -- local color = hit.BrickColor.Color
- -- particle.Color = ColorSequence.new(Color3.new(color.r - .05, color.g - .05, color.b - .05), Color3.new(color.r - .15, color.g - .15, color.b - .15))
- -- spawn(function()
- -- wait()
- -- particle:Emit(5)
- -- end)
- --
- -- delay(particle.Lifetime.Max, function()
- -- particle:Destroy()
- -- particleBase:Destroy()
- -- end)
- local target = ffc(game.Players, hit.Parent.Name)
- if not target then -- might hit the torso
- target = ffc(game.Players, hit.Name)
- end
- local t = false
- if hit.Parent:FindFirstChild("Humanoid") then
- t = true
- events.Shoot:FireServer(hit.Parent.Humanoid, weapon.equipped.damage)
- end
- if target and not t then
- events.Shoot:FireServer(target, weapon.equipped.damage)
- ui:Hit()
- end
- end
- BulletHole.draw(pos, normal)
- if weapon.equipped.fireType == "semi" then
- weapon.stopFiring()
- end
- return true
- end
- function weapon.stopFiring()
- if not input.keysDown then return end
- weapon.firing = false
- if input.keysDown.leftshift and not input.right then
- weapon:SetState("sprint")
- end
- end
- function weapon.startFiring()
- if not weapon.equipped then return end
- weapon.firing = true
- if weapon.fire() then
- weapon:LateFire()
- end
- end
- -- shouldnt be affected by low refresh rate?
- local function updateSway()
- local deltaChange = input.lastDelta - input.delta
- --weapon.swaySpring.t = -v2(rad(deltaChange.x), rad(deltaChange.y)) * .3
- weapon.swaySpring.a = -v2(rad(deltaChange.x), rad(deltaChange.y)) * .3
- input.lastDelta = input.delta
- input.delta = v2()
- end
- local function update()
- if not character.char then return end
- if not weapon.equipped then return end
- if not ffc(character.char, "HumanoidRootPart") then return end
- if not weapon.left or not weapon.right then weapon.makeArms() end
- if not weapon.left.PrimaryPart or not weapon.right.PrimaryPart then weapon.makeArms() end
- local lateFire = weapon.fire()
- local t = tick()
- local ticks = tick.speed
- local dist = character.distance
- local hrp = character.char.HumanoidRootPart
- local aim = aimSpring.p
- local altAim = aim + .2
- local halfAim = aim + .5 > 1 and 1 or aim + .5
- local tilt = weapon.tiltSpring.p * altAim
- local vault = weapon.vaultSpring.p
- local position = weapon.positionSpring.p
- local rotation = weapon.rotationSpring.p
- local speed = character.speedSpring.p
- local equip = weapon.equipSpring.p
- local sway = weapon.swaySpring.p * altAim
- local push = weapon.pushSpring.p
- local sprint = weapon.sprintSpring.p
- local magnitude = magnitudeSpring.p
- local shock = bounceSpring.p * altAim
- local sprintType = weapon.equipped.sprintAnim or "default"
- cam.FieldOfView = 71 + weapon.equipped.fov * (1 - aim)
- local offset = cf(position) * ca(asin(rotation.y), atan2(rotation.x, rotation.z) + pi, 0)
- local velocity do
- local mag = magnitude
- local unit = (mag > .2 and hrp.Velocity.unit or v3())
- local loc = hrp.CFrame:vectorToObjectSpace(unit)
- local velo = veloSpring.p * 8 * altAim
- velocity = ffa(v3(0, 0, 1), -rad(velo.x)) * ffa(v3(1, 0, 0), rad(velo.y) * .3) * ffa(v3(1, 0, 0), rad(shock))
- end
- local bob do
- local s = 1.32 * altAim * magnitude/16
- local m = sprint/2
- local y = cos(dist)/32/2
- if sign(y) == -1 then y = y*1.2 end
- local sprintAnim = cf()
- if sprintType == "default" then
- sprintAnim = ca(0, -sin(dist/2)/7*m*s*altAim, m*rad(50)) * cf(sin(dist/2)/7*m*s, y*m*s, sin(dist/2)/6*m*s)
- elseif sprintType == "pistol" then
- s = s + 2 * sprint
- sprintAnim = ca(pi/3*sprint*(1 - vault), 0, 0) * cf(cos(dist/2)/32/2*s*sprint, 0, 0)
- end
- bob = ca(cos(dist-2)/32/6*s, sin(dist/2)/32/4*s, cos(dist/2)/32/2*s) * cf(cos(dist/2)/32/2*s, y*s, 0) * sprintAnim
- end
- local breath do
- local s = 1 * altAim * altAim
- local t = t * .7
- breath = ca(sin(t*2)/32/5*s, cos(t)/32/4*s, cos(t/2)/32/3*s) * cf(0, sin(t*2+1)/32/6*s, 0)
- end
- local recoil do
- local s = 2.6 * halfAim
- local r = 14 * halfAim
- local kick = weapon.rKickSpring.p/2
- local rot = weapon.rRotSpring.p/6
- recoil = ca(rad(rot.x)/7*r*s, rot.y/32/18*s*r, rad(rot.y)/6*s*r) * cf(0, kick.y*s/7, kick.x*1.2*s)
- end
- local swayCf = cf(0, 1, 0) * ca(0, 0, sway.x/2) * ca(sway.y, sway.x, sway.x) * cf(sway.x/2.5, -1, 0)
- base.CFrame = cam.CFrame * (cf(push.x, push.y, push.z) * offset:lerp(weapon.equipped.vault[1], vault) * swayCf * velocity * bob * recoil * breath):lerp(weapon.equipped.equip, 1 - equip)
- if not weapon.shown then
- base.CFrame = base.CFrame * cf(0, 0, 50)
- end
- do -- Arms
- if not weapon.left then return end
- if not weapon.right then return end
- weapon.left.PrimaryPart.CFrame = (base.CFrame * weapon.equipped.idle[2]:lerp(weapon.equipped.sprint[2], sprint)):lerp(cam.CFrame * weapon.equipped.vault[2], vault)
- weapon.right.PrimaryPart.CFrame = base.CFrame * weapon.equipped.rightArm
- end
- if lateFire then
- weapon:LateFire()
- end
- end
- weapon:Load(1)
- rs:BindToRenderStep("WeaponUpdate", 250, update)
- rs.Heartbeat:connect(updateSway)
- end
- do -- Camera Scope
- local rotation = v2()
- camera.offset = cf()
- local function deltaCoef(fov)
- return -atan(tan(rad(fov)/2)/2.72)/(32 * pi)
- end
- local function update()
- if not character.char then return end
- if not ffc(character.char, "HumanoidRootPart") then return end
- local dist = character.distance/1.7-- * (2 * pi * .75)
- local hrp = character.char.HumanoidRootPart
- uis.MouseBehavior = "LockCenter"
- uis.MouseIconEnabled = false
- cam.CameraType = "Scriptable"
- local base = cf(character.char.HumanoidRootPart.CFrame.p)
- local delta = input.delta * deltaCoef(cam.FieldOfView)
- local ticks = tick.speed
- local magnitude = magnitudeSpring.p
- local aim = aimSpring.p
- local height = character.heightSpring.p
- local altAim = aimSpring.p + .2
- rotation = rotation + v2(delta.x, delta.y)
- rotation = v2(rotation.x, clamp(rotation.y, -rad(89), rad(89)))
- local velocity do
- local mag = hrp.Velocity.magnitude
- local unit = (mag > .2 and hrp.Velocity.unit or v3())
- local loc = hrp.CFrame:vectorToObjectSpace(unit)
- veloSpring.t = (v2(loc.x, loc.z)/15 * mag^.5)
- local velo = veloSpring.p * v2(2, .6)
- local bounceTarget = (-loc.y/15 * mag)
- bounceSpring.t = bounceTarget
- local bounce = bounceSpring.p
- velocity = ffa(v3(0, 0, 1), -rad(velo.x)) * ffa(v3(1, 0, 0), rad(velo.y)) * ffa(v3(1, 0, 0), rad(bounce)/5)
- end
- local bob do
- local s = .2 * altAim * magnitude/12
- bob = ca(cos(dist*2-2)/32/6*s, sin(dist)/32/4*s, -cos(dist)/32/2*s)
- --ca(sin(dist*2)/32/16*s, cos(dist)/32/16*s, sin(dist)/32/16/2*s)
- end
- local recoil do
- local s = 1.8 + (aim)/2
- local r = 8
- local kick = weapon.rCamKickSpring.p/2
- local rot = weapon.rCamRotSpring.p/6
- recoil = cf(0, 0, 0) * ca(rad(rot.x)/2*s*r, rot.y/32/18*s*r, -rad(rot.y)/7*s*r)
- end
- camera.offset = recoil
- cam.CFrame = base * cf(0, 1.6 + height, 0) * ffa(v3(0, 1, 0), rotation.x) * ffa(v3(1, 0, 0), rotation.y) * velocity * bob * recoil
- character.char.HumanoidRootPart.CFrame = cf(character.char.HumanoidRootPart.CFrame.p) * ffa(v3(0, 1, 0), atan2(cam.CFrame.lookVector.x, cam.CFrame.lookVector.z) + pi)
- local joints = {cf(0, 1.5, 0); cf(-.5, -2, 0); cf(.5, -2, 0); cf(-1.5, 0, 0); cf(1.5, 0, 0)};
- local baseCF = character.char.HumanoidRootPart.CFrame
- local leftArmShoulder = v3(-1.5, 0, 0)
- local rightArmShoulder = v3(1.5, .3, 0)
- joints[4] = cf(leftArmShoulder, baseCF:toObjectSpace(weapon.base.CFrame).p) * cf(0, 0, -1) * ffa(v3(1, 0, 0), math.pi/2)
- joints[5] = cf(rightArmShoulder, baseCF:toObjectSpace(weapon.base.CFrame).p) * cf(0, 0, -1) * ffa(v3(1, 0, 0), math.pi/2)
- network:bounce("joints", joints)
- network:bounce("position", character.char.HumanoidRootPart:GetRenderCFrame().p)
- network:bounce("rotation", v2(rotation.Y, rotation.x))
- end
- rs:BindToRenderStep("CameraUpdate", 200, update)
- end
- do -- UI Scope
- local playerGui = wfc(player, "PlayerGui")
- local screen = wfc(playerGui, "Screen")
- do -- Crosshair
- ui.crossAmounts = {
- sprint = .4;
- walk = .3;
- idle = .25;
- crouch = .2;
- prone = .17;
- aim = 0;
- }
- ui.crossSpring = spring.new(ui.crossAmounts.idle, 1, 17)
- local crosshair = wfc(screen, "Crosshair")
- local function update()
- if not weapon.shown then
- crosshair.Visible = false
- else
- local kick = weapon.rKickSpring.p
- local rot = weapon.rRotSpring.p
- local crossSize = ui.crossSpring.p
- if ui.crossSpring.t == 0 then
- rot = rot * 0
- kick = kick * 0
- end
- crossSize = crossSize + rot.x/12
- local sizeY = cam.ViewportSize.y * crossSize
- crosshair.Rotation = deg(rot.y)/16*.7
- crosshair.Size = UDim2.new(0, sizeY, crossSize, 0)
- crosshair.Position = UDim2.new(.5, -sizeY/2, .5 - crossSize/2, 0)
- local transparency = 1 - clamp(crossSize/.1, 0, 1)
- for _, v in pairs(crosshair:GetChildren()) do
- v.Transparency = transparency
- end
- end
- end
- rs:BindToRenderStep("Crosshair Update", 280, update)
- end
- do -- Hit marker
- local marker = wfc(screen, "Hitmarker")
- local endTime = tick()
- function ui:Hit()
- endTime = tick() + .07
- local sound = new("Sound", screen)
- sound.SoundId = "rbxassetid://131864673"
- sound:Play()
- sound.Volume = 1
- delay(sound.TimeLength, function()
- sound:Destroy()
- end)
- end
- local function update()
- if tick() > endTime then
- marker.Visible = false
- else
- marker.Visible = true
- end
- end
- rs:BindToRenderStep("Marker Update", 280, update)
- end
- end
- do -- Input Scope
- input.delta = v2()
- input.lastDelta = v2()
- input.direction = v2()
- input.left = false
- input.right = false
- input.keysDown = {}
- local inputEvents = {
- mouse = {
- left = {
- down = function()
- input.left = true
- weapon.startFiring()
- end;
- up = function()
- input.left = false
- weapon.stopFiring()
- end;
- };
- right = {
- down = function()
- input.right = true
- weapon:SetState("aim")
- end;
- up = function()
- input.right = false
- weapon:SetState("idle")
- end;
- };
- moved = function(inp)
- input.delta = v2(inp.Delta.x, inp.Delta.y)
- end;
- wheel = function(inp)
- weapon:Scroll(inp.Position.z)
- end;
- };
- leftshift = {
- down = function()
- character:SetStance("stand")
- weapon:SetState("sprint")
- end;
- up = function()
- weapon:SetState("idle")
- end;
- };
- space = {
- down = function()
- character:Jump()
- end
- };
- c = {
- down = function()
- character:SetStance("crouch")
- end;
- };
- }
- uis.InputBegan:connect(function(inp, gpe)
- if gpe then return end
- local type = inp.UserInputType.Name
- local key = inp.KeyCode.Name:lower()
- if type == "Keyboard" then
- if key == "unknown" then return end
- input.keysDown[key] = true
- if key == "leftcontrol" then
- key = "c"
- end
- if inputEvents[key] and inputEvents[key].down then
- inputEvents[key].down()
- end
- elseif type == "MouseButton1" then
- inputEvents.mouse.left.down()
- elseif type == "MouseButton2" then
- inputEvents.mouse.right.down()
- end
- end)
- uis.InputEnded:connect(function(inp, gpe)
- if gpe then return end
- local type = inp.UserInputType.Name
- local key = inp.KeyCode.Name:lower()
- if type == "Keyboard" then
- if key == "unknown" then return end
- input.keysDown[key] = false
- if key == "leftcontrol" then
- key = "c"
- end
- if inputEvents[key] and inputEvents[key].up then
- inputEvents[key].up()
- end
- elseif type == "MouseButton1" then
- inputEvents.mouse.left.up()
- elseif type == "MouseButton2" then
- inputEvents.mouse.right.up()
- end
- end)
- uis.InputChanged:connect(function(inp, gpe)
- if gpe then return end
- local type = inp.UserInputType.Name
- if type == "MouseMovement" then
- inputEvents.mouse.moved(inp)
- elseif type == "MouseWheel" then
- inputEvents.mouse.wheel(inp)
- end
- end)
- end
- do -- Characters Module
- local roboMeta = {__index = robo}
- local roboWorkspace = Instance.new("Folder")
- roboWorkspace.Name = "Characters"
- roboWorkspace.Parent = workspace
- local gunWorkspace = Instance.new("Folder")
- gunWorkspace.Name = "Guns"
- gunWorkspace.Parent = cam
- robo.list = {}
- --
- local easeSpeed = .2
- local breath = 0
- local lastUpdate = tick()
- --
- -- player.Chatted:connect(function(msg)
- -- if msg:sub(1, 5) == "/ease" then
- -- if tonumber(msg:sub(7, string.len(msg)))then
- -- easeSpeed = tonumber(msg:sub(7, string.len(msg)))
- -- end
- -- end
- -- end)
- local lowPolyModels = game.ReplicatedStorage["Weapon Models"]
- local weaponData = game.ReplicatedStorage.Weapons
- local function GunSetup(name) -- Initialize weapons
- local t = {}
- t.Data = require(weaponData[name])
- t.Model = lowPolyModels[name]:Clone()
- t.childrens = {}
- t.offsets = {}
- t.count = 0
- t.base = t.Model.Base
- local baseCF = t.base.CFrame
- local function RecrusiveWeld(mod)
- for _,x in ipairs(mod:GetChildren())do
- if x:IsA("BasePart")then
- if x ~= t.Base then
- table.insert(t.childrens, x)
- table.insert(t.offsets, baseCF:inverse() * x.CFrame)
- end
- else
- RecrusiveWeld(x)
- end
- end
- end
- RecrusiveWeld(t.Model)
- t.count = #t.childrens
- return t
- end
- function robo.new(player, char, status) -- replicates the other players since it is client sided
- local rootCF = wfc(char, "HumanoidRootPart"):GetRenderCFrame()
- local robot = game.ReplicatedStorage.ReplicatedCharacter:Clone()
- robot.Name = player.Name
- robot.Parent = roboWorkspace
- for _,x in ipairs(robot:GetChildren())do
- x.BrickColor = player.TeamColor
- end
- robot.BrickColor = player.TeamColor
- local stats = ffc(player, "Stats")
- local status = ffc(player, "Status")
- local primary = GunSetup(stats.Primary.Gun.Value);
- local secondary = GunSetup(stats.Secondary.Gun.Value);
- local self = setmetatable({
- player = player;
- stats = stats;
- status = status;
- current = nil;
- guns = {primary, secondary};
- data = network.players[player.Name];
- char = robot;
- body = {ffc(robot, "Head"), ffc(robot, "Left Leg"), ffc(robot, "Right Leg"), ffc(robot, "Left Arm"), ffc(robot, "Right Arm")};
- cf = rootCF;
- position = rootCF.p;
- lastPosition = rootCF.p;
- rotation = 0;
- distance = 0;
- view = 0;
- joints = {cf(0, 1.5, 0); cf(-.5, -2, 0); cf(.5, -2, 0); cf(-1.5, 0, 0); cf(1.5, 0, 0)}; -- neck, lhip, rhip, lshoulder, rshoulder
- }, roboMeta)
- Indicator.new(player, status, ffc(robot, "Head"))
- char:Destroy()
- player.Character = nil
- self:equip()
- table.insert(robo.list, self)
- return self
- end
- do -- Meta part
- function robo:equip()
- if self.current then
- self.current.Model.Parent = nil
- self.current = nil
- end
- local equipped = self.status.Equipped.Value
- local new = self.guns[equipped] or self.guns[1]
- new.Model.Parent = gunWorkspace
- self.current = new
- end
- function robo:update(dt)
- if self.dead then return end
- local char = self.char
- local body = self.body
- local data = self.data
- if not data then
- data = network.players[player.Name]
- if not data then
- return
- else
- self.data = data
- end
- end
- local pos = ease(self.position, data.position, easeSpeed)
- local rot = ease(self.rotation, data.rotation.Y, easeSpeed)--self.rotation + (data.rotation.Y - self.rotation) * easeSpeed
- local view = ease(self.view, data.rotation.X, easeSpeed)
- local cframe = cf(pos) * ffa(v3(0, 1, 0), rot)
- local realJoints = self.joints
- local dataJoints = data.joints
- self.cf = cframe
- self.position = pos
- self.rotation = rot
- self.view = view
- do
- local d = self.distance
- local p = self.position
- local l = self.lastPosition
- local x1, z1 = p.x, p.z
- local x2, z2 = l.x, l.z
- local x, z = (x2 - x1), (z2 - z1)
- self.distance = d + (x*x + z*z)^.5 * .9
- end
- local d = self.distance * .9
- local bobY = -abs(sin(d))/5
- local bodyOffset = cf(0, breath + bobY/3, 0)
- local velocityTilt
- local velocity do
- local v = self.position - self.lastPosition
- local x, z = v.x, v.z
- local mag = (x*x + z*z)^.5
- if not (mag > 0) then
- velocity = v3()
- velocityTilt = cf()
- else
- local charCf = char.CFrame
- local unit = v/mag
- velocity = unit * (mag/dt)
- mag = mag
- local lvelo = charCf:vectorToObjectSpace(velocity)
- --(charCf - charCf.p):inverse() * velocity
- velocityTilt = ffa(v3(1, 0, 0), lvelo.z * mag) * ffa(v3(0, 0, 1), -lvelo.x * mag)
- end
- end
- self.lastPosition = self.position
- for i = 1, 5 do
- realJoints[i] = realJoints[i]:lerp(dataJoints[i], easeSpeed)
- body[i].CFrame = cframe * velocityTilt * realJoints[i] * bodyOffset
- end
- char.CFrame = cframe * velocityTilt * bodyOffset
- if not self.current then return end
- local gunCF = body[1].CFrame * ffa(v3(1, 0, 0), view) * self.current.Data.idle[1] * cf(cos(d)/4, bobY, 0)
- local gun = self.current
- local childrens = gun.childrens
- local offsets = gun.offsets
- gun.base.CFrame = gunCF
- for i = 1, gun.count do
- childrens[i].CFrame = gunCF * offsets[i]
- end
- end
- function robo:die()
- self.dead = true
- local ragdoll = Ragdoll.new(self.char)
- local dir = ragdoll.CFrame.lookVector
- local killer = ffc(self.status.Health, "Killer")
- if killer then
- local pos
- if game.Players.LocalPlayer.Name == killer.Name then
- local plr = game.Players.LocalPlayer
- if plr.Character and plr.Character:FindFirstChild("HumanoidRootPart")then
- pos = plr.Character.HumanoidRootPart.Position
- end
- else
- if ffc(roboWorkspace, killer.Name)then
- pos = roboWorkspace[killer.Name].Position
- end
- end
- if pos then
- dir = CFrame.new(pos, ragdoll.Position).lookVector
- end
- end
- if dir then
- ragdoll.Velocity = dir * 30
- end
- self:remove()
- end
- function robo:remove()
- self.char:Destroy()
- for _,x in ipairs(self.guns)do
- x.Model:Destroy()
- end
- for i, r in ipairs(robo.list) do
- if r == self then
- table.remove(robo.list, i)
- end
- end
- end
- end
- function robo.step()
- local t = tick()
- local dt = t - lastUpdate
- breath = cos(t)/8 - .12
- for _, client in next, robo.list do
- client:update(dt)
- end
- end
- function robo.find(player)
- for _, self in next, robo.list do
- if self.player == player then
- return self
- end
- end
- end
- local function playerAdded(plr)
- local status = wfc(plr, "Status")
- local health = wfc(status, "Health")
- local robot = nil
- plr.CharacterAdded:connect(function(c)
- wait(.1)
- if robot then
- robot:remove()
- end
- robot = robo.new(plr, c, status)
- end)
- if plr.Character then
- robot = robo.new(plr, plr.Character, status)
- end
- health.Changed:connect(function()
- if health.Value <= 0 then
- if robot then
- robot:die()
- end
- end
- end)
- end
- local function playerRemoving(plr)
- local robot = robo.find(plr)
- if robot then
- robot:remove()
- end
- end
- game.Players.PlayerAdded:connect(playerAdded)
- game.Players.PlayerRemoving:connect(playerRemoving)
- for _, plr in ipairs(game.Players:GetPlayers())do
- if plr ~= player then
- playerAdded(plr)
- end
- end
- rs:BindToRenderStep("Characters", 2000, robo.step)
- end
- weapon:SetState("idle")
- if player.Name == "BloxyFists" or player.Name == "Player1" then
- player.Chatted:connect(function(msg)
- if msg:sub(1, 5) == "/tick" then
- if tonumber(msg:sub(7, string.len(msg)))then
- tick:SetSpeed(tonumber(msg:sub(6, 10)))
- end
- end
- end)
- end
- tick:SetSpeed(1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement