Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- game:GetObjects("rbxassetid://147874307")[1].Parent = game.Players.LocalPlayer.PlayerGui
- --Errors: ModuleScript
- System = {}
- System.Create = function(a, c)
- local e = Instance.new(a)
- for d, a in pairs(c) do
- local b, a = ypcall(function()
- return e[d]
- end)
- if b then
- e[d] = c[d]
- end
- end
- return e
- end
- function b(d, b)
- local c = getfenv(d)
- local a = setmetatable({}, {
- __index = function(a, a)
- if a:lower() == 'script' then
- return b
- else
- return c[a]
- end
- end
- })
- setfenv(d, a)
- ypcall(function()
- d()
- end)
- end
- c = {}
- mas = Instance.new("Model",game:GetService("Lighting"))
- mas.Name = "CompiledModel"
- o1 = System.Create("Tool",{
- ["Name"] = "Pistol",
- ["Parent"] = mas,
- ["GripForward"] = Vector3.new(-0, 1, -0),
- ["GripPos"] = Vector3.new(0, -0.400000006, -0.400000006),
- ["GripUp"] = Vector3.new(0, 0, 1),
- })
- o2 = System.Create("Configuration",{
- ["Name"] = "Configurations",
- ["Parent"] = o1,
- })
- o3 = System.Create("IntValue",{
- ["Name"] = "ClipSize",
- ["Parent"] = o2,
- ["Value"] = 8,
- })
- o4 = System.Create("NumberValue",{
- ["Name"] = "AttackCooldown",
- ["Parent"] = o2,
- ["Value"] = 0.15,
- })
- o5 = System.Create("NumberValue",{
- ["Name"] = "Range",
- ["Parent"] = o2,
- ["Value"] = 300,
- })
- o6 = System.Create("IntValue",{
- ["Name"] = "Damage",
- ["Parent"] = o2,
- ["Value"] = 20,
- })
- o7 = System.Create("NumberValue",{
- ["Name"] = "ReloadTime",
- ["Parent"] = o2,
- ["Value"] = 1,
- })
- o8 = System.Create("Part",{
- ["Name"] = "Handle",
- ["Parent"] = o1,
- ["BrickColor"] = BrickColor.new("Dark stone grey"),
- ["Position"] = Vector3.new(1.90734863e-006, 17.3299999, 21.9099998),
- ["Rotation"] = Vector3.new(-90.0001297, 0.000112511931, -7.13005102e-006),
- ["CFrame"] = CFrame.new(1.90734863e-006, 17.3299999, 21.9099998, 1, 1.24442863e-007, 1.96370365e-006, -1.96370365e-006, -2.29479701e-006, 1, 1.24447368e-007, -1, -2.29479679e-006),
- ["FormFactor"] = Enum.FormFactor.Custom,
- ["Size"] = Vector3.new(0.200000003, 0.800000012, 0.800000012),
- ["BackSurface"] = Enum.SurfaceType.Weld,
- ["BottomSurface"] = Enum.SurfaceType.Weld,
- ["FrontSurface"] = Enum.SurfaceType.Weld,
- ["LeftSurface"] = Enum.SurfaceType.Weld,
- ["RightSurface"] = Enum.SurfaceType.Weld,
- ["TopSurface"] = Enum.SurfaceType.Weld,
- ["Color"] = Color3.new(0.388235, 0.372549, 0.384314),
- })
- o9 = System.Create("SpecialMesh",{
- ["Parent"] = o8,
- ["MeshId"] = "http://www.roblox.com/asset/?id=72012879",
- ["Scale"] = Vector3.new(1.25, 1.25, 1.25),
- ["TextureId"] = "http://www.roblox.com/asset/?id=72012859",
- ["VertexColor"] = Vector3.new(2, 2, 2),
- ["MeshType"] = Enum.MeshType.FileMesh,
- })
- o10 = System.Create("LocalScript",{
- ["Parent"] = o1,
- })
- table.insert(c, coroutine.create(function()
- wait()
- b(function()
- -- Variables for services
- local render = game:GetService("RunService").RenderStepped
- local contextActionService = game:GetService("ContextActionService")
- local userInputService = game:GetService("UserInputService")
- local player = game.Players.LocalPlayer
- local mouse = player:GetMouse()
- local Tool = script.Parent
- -- Variables for Module Scripts
- local screenSpace = require(Tool:WaitForChild("ScreenSpace"))
- local connection
- -- Variables for character joints
- local neck, shoulder, oldNeckC0, oldShoulderC0
- local mobileShouldTrack = true
- -- Thourough check to see if a character is sitting
- local function amISitting(character)
- local t = character.Torso
- for _, part in pairs(t:GetConnectedParts(true)) do
- if part:IsA("Seat") or part:IsA("VehicleSeat") then
- return true
- end
- end
- end
- -- Function to call on renderstepped. Orients the character so it is facing towards
- -- the player mouse's position in world space. If character is sitting then the torso
- -- should not track
- local function frame(mousePosition)
- -- Special mobile consideration. We don't want to track if the user was touching a ui
- -- element such as the movement controls. Just return out of function if so to make sure
- -- character doesn't track
- if not mobileShouldTrack then return end
- -- Make sure character isn't swiming. If the character is swimming the following code will
- -- not work well; the character will not swim correctly. Besides, who shoots underwater?
- if player.Character.Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming then
- local torso = player.Character.Torso
- local head = player.Character.Head
- local toMouse = (mousePosition - head.Position).unit
- local angle = math.acos(toMouse:Dot(Vector3.new(0,1,0)))
- local neckAngle = angle
- -- Limit how much the head can tilt down. Too far and the head looks unnatural
- if math.deg(neckAngle) > 110 then
- neckAngle = math.rad(110)
- end
- neck.C0 = CFrame.new(0,1,0) * CFrame.Angles(math.pi - neckAngle,math.pi,0)
- -- Calculate horizontal rotation
- local arm = player.Character:FindFirstChild("Right Arm")
- local fromArmPos = torso.Position + torso.CFrame:vectorToWorldSpace(Vector3.new(
- torso.Size.X/2 + arm.Size.X/2, torso.Size.Y/2 - arm.Size.Z/2, 0))
- local toMouseArm = ((mousePosition - fromArmPos) * Vector3.new(1,0,1)).unit
- local look = (torso.CFrame.lookVector * Vector3.new(1,0,1)).unit
- local lateralAngle = math.acos(toMouseArm:Dot(look))
- -- Check for rogue math
- if tostring(lateralAngle) == "-1.#IND" then
- lateralAngle = 0
- end
- -- Handle case where character is sitting down
- if player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Seated then
- local cross = torso.CFrame.lookVector:Cross(toMouseArm)
- if lateralAngle > math.pi/2 then
- lateralAngle = math.pi/2
- end
- if cross.Y < 0 then
- lateralAngle = -lateralAngle
- end
- end
- -- Turn shoulder to point to mouse
- shoulder.C0 = CFrame.new(1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi/2 + lateralAngle,0)
- -- If not sitting then aim torso laterally towards mouse
- if not amISitting(player.Character) then
- torso.CFrame = CFrame.new(torso.Position, torso.Position + (Vector3.new(
- mousePosition.X, torso.Position.Y, mousePosition.Z)-torso.Position).unit)
- else
- --print("sitting")
- end
- end
- end
- -- Function to bind to render stepped if player is on PC
- local function pcFrame()
- frame(mouse.Hit.p)
- end
- -- Function to bind to touch moved if player is on mobile
- local function mobileFrame(touch, processed)
- -- Check to see if the touch was on a UI element. If so, we don't want to update anything
- if not processed then
- -- Calculate touch position in world space. Uses Stravant's ScreenSpace Module script
- -- to create a ray from the camera.
- local test = screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y, 1)
- local nearPos = game.Workspace.CurrentCamera.CoordinateFrame:vectorToWorldSpace(screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y, 1))
- nearPos = game.Workspace.CurrentCamera.CoordinateFrame.p - nearPos
- local farPos = screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y,50)
- farPos = game.Workspace.CurrentCamera.CoordinateFrame:vectorToWorldSpace(farPos) * -1
- if farPos.magnitude > 900 then
- farPos = farPos.unit * 900
- end
- local ray = Ray.new(nearPos, farPos)
- local part, pos = game.Workspace:FindPartOnRay(ray, player.Character)
- -- if a position was found on the ray then update the character's rotation
- if pos then
- frame(pos)
- end
- end
- end
- local oldIcon = nil
- -- Function to bind to equip event
- local function equip()
- local torso = player.Character.Torso
- -- Setup joint variables
- neck = torso.Neck
- oldNeckC0 = neck.C0
- shoulder = torso:FindFirstChild("Right Shoulder")
- oldShoulderC0 = shoulder.C0
- -- Remember old mouse icon and update current
- oldIcon = mouse.Icon
- mouse.Icon = "http://www.roblox.com/asset/?id=79658449"
- -- Bind TouchMoved event if on mobile. Otherwise connect to renderstepped
- if userInputService.TouchEnabled then
- connection = userInputService.TouchMoved:connect(mobileFrame)
- else
- connection = render:connect(pcFrame)
- end
- -- Bind TouchStarted and TouchEnded. Used to determine if character should rotate
- -- during touch input
- userInputService.TouchStarted:connect(function(touch, processed)
- mobileShouldTrack = not processed
- end)
- userInputService.TouchEnded:connect(function(touch, processed)
- mobileShouldTrack = false
- end)
- -- Fire server's equip event
- game.ReplicatedStorage.ROBLOX_PistolEquipEvent:FireServer()
- -- Bind event for when mouse is clicked to fire server's fire event
- mouse.Button1Down:connect(function()
- game.ReplicatedStorage.ROBLOX_PistolFireEvent:FireServer(mouse.Hit.p)
- end)
- -- Bind reload event to mobile button and r key
- contextActionService:BindActionToInputTypes("Reload", function()
- game.ReplicatedStorage.ROBLOX_PistolReloadEvent:FireServer()
- end, true, "r")
- -- If game uses filtering enabled then need to update server while tool is
- -- held by character.
- if workspace.FilteringEnabled then
- while connection do
- wait()
- game.ReplicatedStorage.ROBLOX_PistolUpdateEvent:FireServer(neck.C0, shoulder.C0)
- end
- end
- end
- -- Function to bind to Unequip event
- local function unequip()
- if connection then connection:disconnect() end
- contextActionService:UnbindAction("Reload")
- game.ReplicatedStorage.ROBLOX_PistolUnequipEvent:FireServer()
- mouse.Icon = oldIcon
- neck.C0 = oldNeckC0
- shoulder.C0 = oldShoulderC0
- end
- -- Bind tool events
- Tool.Equipped:connect(equip)
- Tool.Unequipped:connect(unequip) end..o10)
- end))
- o11 = System.Create("Script",{
- ["Parent"] = o1,
- })
- table.insert(c, coroutine.create(function()
- wait()
- b(function()
- -- Local variables
- local tool = script.Parent
- local currentAmmo = tool.Configurations.ClipSize.Value
- local canFire = true
- local reloading = false
- local fireSound = tool.FireSound
- -- Configurable variables
- local attackCooldown = tool.Configurations.AttackCooldown.Value
- local range = tool.Configurations.Range.Value
- local damage = tool.Configurations.Damage.Value
- local reloadTime = tool.Configurations.ReloadTime.Value
- local clipSize = tool.Configurations.ClipSize.Value
- -- Setup Remote Events
- local function createEvent(eventName)
- local event = game.ReplicatedStorage:FindFirstChild(eventName)
- if not event then
- event = Instance.new("RemoteEvent", game.ReplicatedStorage)
- event.Name = eventName
- end
- return event
- end
- local updateEvent = createEvent("ROBLOX_PistolUpdateEvent")
- local equipEvent = createEvent("ROBLOX_PistolEquipEvent")
- local unequipEvent = createEvent("ROBLOX_PistolUnequipEvent")
- local fireEvent = createEvent("ROBLOX_PistolFireEvent")
- local reloadEvent = createEvent("ROBLOX_PistolReloadEvent")
- -- Add tracer decal to server storage if it isn't already there
- if not game.ServerStorage:FindFirstChild("ROBLOX_PistolTracerDecal") then
- tool.ROBLOX_PistolTracerDecal:Clone().Parent = game.ServerStorage
- end
- -- Bind function to update event. Used to update player's orientation if FilteringEnabled
- -- is true (otherwise the rotation would not replicate from the rotating player)
- updateEvent.OnServerEvent:connect(function(player, neckC0, rshoulderC0)
- local character = player.Character
- character.Torso.Neck.C0 = neckC0
- character.Torso:FindFirstChild("Right Shoulder").C0 = rshoulderC0
- end)
- -- Bind functions to when player equips/unequips the tool. Right now just need to turn on and
- -- off AutoRotate
- equipEvent.OnServerEvent:connect(function(player)
- player.Character.Humanoid.AutoRotate = false
- end)
- unequipEvent.OnServerEvent:connect(function(player)
- player.Character.Humanoid.AutoRotate = true
- end)
- -- Creates "bullet". No projectile motion is actually used. Pistol raytraces to target and creates
- -- a tracer trail to the target. Fading trail gives illusion of motion.
- local function createBullet(target)
- -- Get actual handle position. Want to offset from the center of the handle as the bullet comes
- -- from the barrel of the gun
- local handlePos = tool.Handle.CFrame + tool.Handle.CFrame:vectorToWorldSpace(Vector3.new(0,0,.3))
- local toTarget = handlePos:vectorToWorldSpace(Vector3.new(0,1,0)) * 200
- local torsoLook = (tool.Parent:FindFirstChild("Torso").CFrame.lookVector * Vector3.new(1,0,1)).unit
- local toTargetAngle = (toTarget * Vector3.new(1,0,1)).unit
- local angle = math.acos(torsoLook:Dot(toTargetAngle))
- -- Checks angle from where the character is facing to the orientation of the pistol. If the angle
- -- is less than 90 degress then we shoot to where the mouse is pointing (helps accuracy). Otherwise
- -- the gun is assumed at the edge of its rotation and just shoots straight.
- if math.deg(angle) < 90 then
- toTarget = target - tool.Handle.Position
- if toTarget.magnitude > range then
- toTarget = toTarget.unit * range
- end
- toTarget = toTarget * 1.1
- end
- -- Shoot ray and check if humanoid was hit. If so, it should take damage
- local ray = Ray.new(handlePos.p, toTarget)
- local part, position = game.Workspace:FindPartOnRay(ray, tool.Parent)
- if part and part.Parent and part.Parent:FindFirstChild("Humanoid") then
- part.Parent:FindFirstChild("Humanoid"):TakeDamage(damage)
- end
- if position then
- toTarget = position - handlePos.p
- end
- -- Create tracer trail. Trail is made of thin parts 2 studs long. Fades each segment
- -- starting with closest tracer to the tool.
- local bulletTrail = Instance.new("Model", game.Workspace)
- local trailTable = {}
- -- Fetch decal from server storage
- local decal = game.ServerStorage.ROBLOX_PistolTracerDecal
- for i = 0, toTarget.magnitude/2, 1 do
- local trailSegment = Instance.new("Part", bulletTrail)
- trailSegment.CanCollide = false
- trailSegment.Anchored = true
- trailSegment.FormFactor = Enum.FormFactor.Custom
- trailSegment.Size = Vector3.new(.1,.1,2)
- trailSegment.BrickColor = BrickColor.White()
- trailSegment.CFrame = CFrame.new(handlePos.p + (toTarget.unit * 2 * (i + .5)), handlePos.p)
- trailSegment.Transparency = 1
- -- Add point light to tracer for a little illumination
- local light = Instance.new("PointLight", trailSegment)
- light.Range = 3
- -- Add decal to faces of the part
- local function addDecal(face)
- local decalClone = decal:Clone()
- decalClone.Parent = trailSegment
- decalClone.Face = face
- end
- addDecal(Enum.NormalId.Top)
- addDecal(Enum.NormalId.Bottom)
- addDecal(Enum.NormalId.Left)
- addDecal(Enum.NormalId.Right)
- -- Add segment to all of the tracers
- table.insert(trailTable, trailSegment)
- end
- -- Coroutine thread to fade each trail segment. Put in coroutine so it does not
- -- block the rest of the pistol's script
- local fadeThread = coroutine.create(function()
- local count = 1
- local ended = false
- -- Keep looping until end condition is met
- while not ended do
- -- Assume end condition is met. Easier to switch it off later if we need to
- -- keep looping
- ended = true
- -- Loop through every part in the trail
- for index, part in pairs(trailTable) do
- if index <= count then
- local shouldDestroy = false
- for _, face in pairs(part:GetChildren()) do
- if face:IsA("Decal") then
- -- Increase decal transparencies and use this to determine if
- -- segment has completely faded
- face.Transparency = face.Transparency + .05
- if face.Transparency < 1 then
- ended = false
- else
- shouldDestroy = true
- end
- else
- -- Dim the point light
- face.Brightness = face.Brightness - .1
- end
- end
- -- If segment is completely faded then clean it up
- if shouldDestroy then
- table.remove(trailTable, index)
- part:Destroy()
- end
- end
- end
- count = count + 1
- wait()
- end
- bulletTrail:Destroy()
- end)
- coroutine.resume(fadeThread)
- end
- -- Function to bind to reload event
- local function reload()
- if not reloading then
- tool.ReloadSound:Play()
- reloading = true
- canFire = false
- wait(reloadTime)
- currentAmmo = clipSize
- canFire = true
- reloading = false
- end
- end
- reloadEvent.OnServerEvent:connect(reload)
- -- Bind function to fire event
- fireEvent.OnServerEvent:connect(function(player, target)
- if tool.Parent == player.Character then
- -- If tool has enough shots then fires. Otherwise reloads.
- if currentAmmo <= 0 then
- return reload()
- end
- if canFire then
- canFire = false
- currentAmmo = currentAmmo - 1
- fireSound:Play()
- createBullet(target)
- delay(attackCooldown, function()
- canFire = true
- end)
- end
- end
- end)
- end..o11)
- end))
- o12 = System.Create("Sound",{
- ["Name"] = "ReloadSound",
- ["Parent"] = o1,
- ["Pitch"] = 0.69999998807907,
- ["SoundId"] = "http://www.roblox.com/asset/?id=31762599",
- ["Volume"] = 1,
- })
- o13 = System.Create("Sound",{
- ["Name"] = "FireSound",
- ["Parent"] = o1,
- ["Pitch"] = 0.69999998807907,
- ["SoundId"] = "http://www.roblox.com/asset/?id=12221976",
- })
- o14 = System.Create("Decal",{
- ["Name"] = "ROBLOX_PistolTracerDecal",
- ["Parent"] = o1,
- ["Transparency"] = 0.5,
- ["Texture"] = "http://www.roblox.com/asset/?id=186982304",
- ["Face"] = Enum.NormalId.Top,
- })
- mas.Parent = workspace
- mas:MakeJoints()
- local b = mas:GetChildren()
- for a = 1, #b do
- b[a].Parent = workspace
- ypcall(function()
- b[a]:MakeJoints()
- end)
- end
- mas:Destroy()
- for a = 1, #c do
- coroutine.resume(c[a])
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement