· 5 years ago · Feb 11, 2020, 09:12 PM
1--https://github.com/Mokiros/roblox-FE-compatibility
2if game:GetService("RunService"):IsClient() then error("Script must be server-side in order to work; use h/ and not hl/") end
3local Player,game,owner = owner,game
4local RealPlayer = Player
5do
6 print("FE Compatibility code V2 by Mokiros")
7 local RealPlayer = RealPlayer
8 script.Parent = RealPlayer.Character
9
10 --Fake event to make stuff like Mouse.KeyDown work
11 local Disconnect_Function = function(this)
12 this[1].Functions[this[2]] = nil
13 end
14 local Disconnect_Metatable = {__index={disconnect=Disconnect_Function,Disconnect=Disconnect_Function}}
15 local FakeEvent_Metatable = {__index={
16 Connect = function(this,f)
17 local i = tostring(math.random(0,10000))
18 while this.Functions[i] do
19 i = tostring(math.random(0,10000))
20 end
21 this.Functions[i] = f
22 return setmetatable({this,i},Disconnect_Metatable)
23 end
24 }}
25 FakeEvent_Metatable.__index.connect = FakeEvent_Metatable.__index.Connect
26 local function fakeEvent()
27 return setmetatable({Functions={}},FakeEvent_Metatable)
28 end
29
30 --Creating fake input objects with fake variables
31 local FakeMouse = {Hit=CFrame.new(),KeyUp=fakeEvent(),KeyDown=fakeEvent(),Button1Up=fakeEvent(),Button1Down=fakeEvent(),Button2Up=fakeEvent(),Button2Down=fakeEvent()}
32 FakeMouse.keyUp = FakeMouse.KeyUp
33 FakeMouse.keyDown = FakeMouse.KeyDown
34 local UIS = {InputBegan=fakeEvent(),InputEnded=fakeEvent()}
35 local CAS = {Actions={},BindAction=function(self,name,fun,touch,...)
36 CAS.Actions[name] = fun and {Name=name,Function=fun,Keys={...}} or nil
37 end}
38 --Merged 2 functions into one by checking amount of arguments
39 CAS.UnbindAction = CAS.BindAction
40
41 --This function will trigger the events that have been :Connect()'ed
42 local function TriggerEvent(self,ev,...)
43 for _,f in pairs(self[ev].Functions) do
44 f(...)
45 end
46 end
47 FakeMouse.TriggerEvent = TriggerEvent
48 UIS.TriggerEvent = TriggerEvent
49
50 --Client communication
51 local Event = Instance.new("RemoteEvent")
52 Event.Name = "UserInput_Event"
53 Event.OnServerEvent:Connect(function(plr,io)
54 if plr~=RealPlayer then return end
55 FakeMouse.Target = io.Target
56 FakeMouse.Hit = io.Hit
57 if not io.isMouse then
58 local b = io.UserInputState == Enum.UserInputState.Begin
59 if io.UserInputType == Enum.UserInputType.MouseButton1 then
60 return FakeMouse:TriggerEvent(b and "Button1Down" or "Button1Up")
61 end
62 if io.UserInputType == Enum.UserInputType.MouseButton2 then
63 return FakeMouse:TriggerEvent(b and "Button2Down" or "Button2Up")
64 end
65 for _,t in pairs(CAS.Actions) do
66 for _,k in pairs(t.Keys) do
67 if k==io.KeyCode then
68 t.Function(t.Name,io.UserInputState,io)
69 end
70 end
71 end
72 FakeMouse:TriggerEvent(b and "KeyDown" or "KeyUp",io.KeyCode.Name:lower())
73 UIS:TriggerEvent(b and "InputBegan" or "InputEnded",io,false)
74 end
75 end)
76 Event.Parent = NLS([==[local Event = script:WaitForChild("UserInput_Event")
77 local Mouse = owner:GetMouse()
78 local UIS = game:GetService("UserInputService")
79 local input = function(io,RobloxHandled)
80 if RobloxHandled then return end
81 --Since InputObject is a client-side instance, we create and pass table instead
82 Event:FireServer({KeyCode=io.KeyCode,UserInputType=io.UserInputType,UserInputState=io.UserInputState,Hit=Mouse.Hit,Target=Mouse.Target})
83 end
84 UIS.InputBegan:Connect(input)
85 UIS.InputEnded:Connect(input)
86
87 local h,t
88 --Give the server mouse data every second frame, but only if the values changed
89 --If player is not moving their mouse, client won't fire events
90 local HB = game:GetService("RunService").Heartbeat
91 while true do
92 if h~=Mouse.Hit or t~=Mouse.Target then
93 h,t=Mouse.Hit,Mouse.Target
94 Event:FireServer({isMouse=true,Target=t,Hit=h})
95 end
96 --Wait 2 frames
97 for i=1,2 do
98 HB:Wait()
99 end
100 end]==],script)
101
102 ----Sandboxed game object that allows the usage of client-side methods and services
103 --Real game object
104 local RealGame = game
105
106 --Metatable for fake service
107 local FakeService_Metatable = {
108 __index = function(self,k)
109 local s = rawget(self,"_RealService")
110 if s then
111 return typeof(s[k])=="function"
112 and function(_,...)return s[k](s,...)end or s[k]
113 end
114 end,
115 __newindex = function(self,k,v)
116 local s = rawget(self,"_RealService")
117 if s then s[k]=v end
118 end
119 }
120 local function FakeService(t,RealService)
121 t._RealService = typeof(RealService)=="string" and RealGame:GetService(RealService) or RealService
122 return setmetatable(t,FakeService_Metatable)
123 end
124
125 --Fake game object
126 local FakeGame = {
127 GetService = function(self,s)
128 return rawget(self,s) or RealGame:GetService(s)
129 end,
130 Players = FakeService({
131 LocalPlayer = FakeService({GetMouse=function(self)return FakeMouse end},Player)
132 },"Players"),
133 UserInputService = FakeService(UIS,"UserInputService"),
134 ContextActionService = FakeService(CAS,"ContextActionService"),
135 RunService = FakeService({
136 _btrs = {},
137 RenderStepped = RealGame:GetService("RunService").Heartbeat,
138 BindToRenderStep = function(self,name,_,fun)
139 self._btrs[name] = self.Heartbeat:Connect(fun)
140 end,
141 UnbindFromRenderStep = function(self,name)
142 self._btrs[name]:Disconnect()
143 end,
144 },"RunService")
145 }
146 rawset(FakeGame.Players,"localPlayer",FakeGame.Players.LocalPlayer)
147 FakeGame.service = FakeGame.GetService
148 FakeService(FakeGame,game)
149 --Changing owner to fake player object to support owner:GetMouse()
150 game,owner = FakeGame,FakeGame.Players.LocalPlayer
151end
152--Converted with ttyyuu12345's model to script plugin v4
153function sandbox(var,func)
154 local env = getfenv(func)
155 local newenv = setmetatable({},{
156 __index = function(self,k)
157 if k=="script" then
158 return var
159 else
160 return env[k]
161 end
162 end,
163 })
164 setfenv(func,newenv)
165 return func
166end
167cors = {}
168mas = Instance.new("Model",game:GetService("Lighting"))
169Tool0 = Instance.new("Tool")
170Part1 = Instance.new("Part")
171SpecialMesh2 = Instance.new("SpecialMesh")
172Script3 = Instance.new("Script")
173Sound4 = Instance.new("Sound")
174Sound5 = Instance.new("Sound")
175Script6 = Instance.new("Script")
176LocalScript7 = Instance.new("LocalScript")
177Configuration8 = Instance.new("Configuration")
178NumberValue9 = Instance.new("NumberValue")
179IntValue10 = Instance.new("IntValue")
180NumberValue11 = Instance.new("NumberValue")
181IntValue12 = Instance.new("IntValue")
182IntValue13 = Instance.new("IntValue")
183IntValue14 = Instance.new("IntValue")
184ModuleScript15 = Instance.new("ModuleScript")
185Tool0.Name = "RocketLauncher"
186Tool0.Parent = mas
187Tool0.TextureId = "http://www.roblox.com/asset/?id=90021376"
188Tool0.CanBeDropped = false
189Tool0.Grip = CFrame.new(0.699999988, 0, -0.5, 0, 0, -1, -1, 0, 0, 0, 1, 0)
190Tool0.GripForward = Vector3.new(1, -0, -0)
191Tool0.GripPos = Vector3.new(0.699999988, 0, -0.5)
192Tool0.GripRight = Vector3.new(0, -1, 0)
193Tool0.GripUp = Vector3.new(0, 0, 1)
194Part1.Name = "Handle"
195Part1.Parent = Tool0
196Part1.CFrame = CFrame.new(-0.100000001, 17.2200317, 22.2000008, 1, 0, 0, 0, 6.30170107e-05, 1.00000024, 0, -1.00000024, 6.30170107e-05)
197Part1.Orientation = Vector3.new(-90, 0, 0)
198Part1.Position = Vector3.new(-0.100000001, 17.2200317, 22.2000008)
199Part1.Rotation = Vector3.new(-90, 0, 0)
200Part1.Size = Vector3.new(4.92000628, 0.740000546, 0.839999795)
201Part1.BottomSurface = Enum.SurfaceType.Smooth
202Part1.TopSurface = Enum.SurfaceType.Smooth
203Part1.FormFactor = Enum.FormFactor.Custom
204Part1.formFactor = Enum.FormFactor.Custom
205SpecialMesh2.Parent = Part1
206SpecialMesh2.MeshId = "rbxasset://fonts/rocketlauncher.mesh"
207SpecialMesh2.Scale = Vector3.new(0.75, 0.75, 0.75)
208SpecialMesh2.TextureId = "rbxasset://textures/rocketlaunchertex.png"
209SpecialMesh2.MeshType = Enum.MeshType.FileMesh
210Script3.Parent = Tool0
211table.insert(cors,sandbox(Script3,function()
212local tool = script.Parent
213local canFire = true
214local gunWeld
215
216-----------------
217--| Constants |--
218-----------------
219
220local GRAVITY_ACCELERATION = 196.2
221
222local RELOAD_TIME = tool.Configurations.ReloadTime.Value -- Seconds until tool can be used again
223local ROCKET_SPEED = tool.Configurations.RocketSpeed.Value -- Speed of the projectile
224
225local MISSILE_MESH_ID = 'http://www.roblox.com/asset/?id=2251534'
226local MISSILE_MESH_SCALE = Vector3.new(0.35, 0.35, 0.25)
227local ROCKET_PART_SIZE = Vector3.new(1.2, 1.2, 3.27)
228
229local RocketScript = script:WaitForChild('Rocket')
230local SwooshSound = script:WaitForChild('Swoosh')
231local BoomSound = script:WaitForChild('Boom')
232
233local attackCooldown = tool.Configurations.AttackCooldown.Value
234local damage = tool.Configurations.Damage.Value
235local reloadTime = tool.Configurations.ReloadTime.Value
236
237local function createEvent(eventName)
238 local event = game.ReplicatedStorage:FindFirstChild(eventName)
239 if not event then
240 event = Instance.new("RemoteEvent", game.ReplicatedStorage)
241 event.Name = eventName
242 end
243 return event
244end
245
246local updateEvent = createEvent("ROBLOX_RocketUpdateEvent")
247local equipEvent = createEvent("ROBLOX_RocketEquipEvent")
248local unequipEvent = createEvent("ROBLOX_RocketUnequipEvent")
249local fireEvent = createEvent("ROBLOX_RocketFireEvent")
250
251updateEvent.OnServerEvent:connect(function(player, neckC0, rshoulderC0)
252 local character = player.Character
253 local humanoid = character.Humanoid
254
255 if humanoid.Health <= 0 then return end
256
257 if humanoid.RigType == Enum.HumanoidRigType.R6 then
258 character.Torso.Neck.C0 = neckC0
259 character.Torso:FindFirstChild("Right Shoulder").C0 = rshoulderC0
260 gunWeld = character:FindFirstChild("Right Arm"):WaitForChild("RightGrip")
261
262 elseif humanoid.RigType == Enum.HumanoidRigType.R15 then
263 character.Head.Neck.C0 = neckC0
264 character.RightUpperArm.RightShoulder.C0 = rshoulderC0
265 gunWeld = character.RightHand:WaitForChild("RightGrip")
266 end
267end)
268
269equipEvent.OnServerEvent:connect(function(player)
270 player.Character.Humanoid.AutoRotate = false
271end)
272
273unequipEvent.OnServerEvent:connect(function(player)
274 player.Character.Humanoid.AutoRotate = true
275end)
276
277--NOTE: We create the rocket once and then clone it when the player fires
278local Rocket = Instance.new('Part') do
279 -- Set up the rocket part
280 Rocket.Name = 'Rocket'
281 Rocket.FormFactor = Enum.FormFactor.Custom --NOTE: This must be done before changing Size
282 Rocket.Size = ROCKET_PART_SIZE
283 Rocket.CanCollide = false
284
285 -- Add the mesh
286 local mesh = Instance.new('SpecialMesh', Rocket)
287 mesh.MeshId = MISSILE_MESH_ID
288 mesh.Scale = MISSILE_MESH_SCALE
289
290 -- Add fire
291 local fire = Instance.new('Fire', Rocket)
292 fire.Heat = 5
293 fire.Size = 2
294
295 -- Add a force to counteract gravity
296 local bodyForce = Instance.new('BodyForce', Rocket)
297 bodyForce.Name = 'Antigravity'
298 bodyForce.force = Vector3.new(0, Rocket:GetMass() * GRAVITY_ACCELERATION, 0)
299
300 -- Clone the sounds and set Boom to PlayOnRemove
301 local swooshSoundClone = SwooshSound:Clone()
302 swooshSoundClone.Parent = Rocket
303 local boomSoundClone = BoomSound:Clone()
304 boomSoundClone.PlayOnRemove = true
305 boomSoundClone.Parent = Rocket
306
307 -- Finally, clone the rocket script and enable it
308-- local rocketScriptClone = RocketScript:Clone()
309-- rocketScriptClone.Parent = Rocket
310-- rocketScriptClone.Disabled = false
311end
312
313
314fireEvent.OnServerEvent:connect(function(player, target)
315 if canFire and player.Character == tool.Parent then
316 canFire = false
317
318 -- Create a clone of Rocket and set its color
319 local rocketClone = Rocket:Clone()
320 --game.Debris:AddItem(rocketClone, 30)
321 rocketClone.BrickColor = player.TeamColor
322 rocketClone.Touched:connect(function(hit)
323 if hit and hit.Parent and hit.Parent ~= player.Character and hit.Parent ~= tool then
324 local explosion = Instance.new("Explosion", game.Workspace)
325 explosion.Position = rocketClone.Position
326 rocketClone:Destroy()
327 end
328 end)
329
330 spawn(function()
331 wait(30)
332 if rocketClone then rocketClone:Destroy() end
333 end)
334
335 -- Position the rocket clone and launch!
336 local spawnPosition = (tool.Handle.CFrame * CFrame.new(2, 0, 0)).p
337 rocketClone.CFrame = CFrame.new(spawnPosition, target) --NOTE: This must be done before assigning Parent
338 rocketClone.Velocity = rocketClone.CFrame.lookVector * ROCKET_SPEED --NOTE: This should be done before assigning Parent
339 rocketClone.Parent = game.Workspace
340
341 -- Attach creator tags to the rocket early on
342 local creatorTag = Instance.new('ObjectValue', rocketClone)
343 creatorTag.Value = player
344 creatorTag.Name = 'creator' --NOTE: Must be called 'creator' for website stats
345 local iconTag = Instance.new('StringValue', creatorTag)
346 iconTag.Value = tool.TextureId
347 iconTag.Name = 'icon'
348
349 delay(attackCooldown, function()
350 canFire = true
351 end)
352 end
353end)
354end))
355Sound4.Name = "Boom"
356Sound4.Parent = Script3
357Sound4.SoundId = "rbxasset://sounds/collide.wav"
358Sound4.Volume = 1
359Sound5.Name = "Swoosh"
360Sound5.Parent = Script3
361Sound5.Looped = true
362Sound5.SoundId = "rbxasset://sounds/Rocket whoosh 01.wav"
363Sound5.Volume = 0.69999998807907
364Script6.Name = "Rocket"
365Script6.Parent = Script3
366table.insert(cors,sandbox(Script6,function()
367-----------------
368--| Constants |--
369-----------------
370local BLAST_RADIUS = script.Parent.Parent.Configurations.BlastRadius.Value -- Blast radius of the explosion
371local BLAST_DAMAGE = script.Parent.Parent.Configurations.Damage.Value -- Amount of damage done to players
372local BLAST_FORCE = script.Parent.Parent.Configurations.BlastForce.Value -- Amount of force applied to parts
373
374local IGNORE_LIST = {rocket = 1, handle = 1, effect = 1, water = 1} -- Rocket will fly through things named these
375--NOTE: Keys must be lowercase, values must evaluate to true
376
377-----------------
378--| Variables |--
379-----------------
380
381local DebrisService = game:GetService('Debris')
382local PlayersService = game:GetService('Players')
383
384local Rocket = script.Parent
385
386local CreatorTag = Rocket:WaitForChild('creator', 60)
387local SwooshSound = Rocket:WaitForChild('Swoosh', 60)
388
389-----------------
390--| Functions |--
391-----------------
392
393-- Removes any old creator tags and applies a new one to the target
394local function ApplyTags(target)
395 while target:FindFirstChild('creator') do
396 target.creator:Destroy()
397 end
398
399 local creatorTagClone = CreatorTag:Clone()
400 DebrisService:AddItem(creatorTagClone, 1.5)
401 creatorTagClone.Parent = target
402end
403
404-- Returns the ancestor that contains a Humanoid, if it exists
405local function FindCharacterAncestor(subject)
406 if subject and subject ~= game.Workspace then
407 local humanoid = subject:FindFirstChild('Humanoid')
408 if humanoid then
409 return subject, humanoid
410 else
411 return FindCharacterAncestor(subject.Parent)
412 end
413 end
414 return nil
415end
416
417-- Customized explosive effect that doesn't affect teammates and only breaks joints on dead parts
418local function OnExplosionHit(hitPart, hitDistance, blastCenter)
419 if hitPart and hitDistance then
420 local character, humanoid = FindCharacterAncestor(hitPart.Parent)
421
422 if character then
423 local myPlayer = CreatorTag.Value
424 if myPlayer and not myPlayer.Neutral then -- Ignore friendlies caught in the blast
425 local player = PlayersService:GetPlayerFromCharacter(character)
426 if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then
427 return
428 end
429 end
430 end
431
432 if humanoid and humanoid.Health > 0 then -- Humanoids are tagged and damaged
433 if hitPart.Name == 'Torso' then
434 ApplyTags(humanoid)
435 humanoid:TakeDamage(BLAST_DAMAGE)
436 end
437 else -- Loose parts and dead parts are blasted
438 if hitPart.Name ~= 'Handle' then
439 hitPart:BreakJoints()
440 local blastForce = Instance.new('BodyForce', hitPart) --NOTE: We will multiply by mass so bigger parts get blasted more
441 blastForce.force = (hitPart.Position - blastCenter).unit * BLAST_FORCE * hitPart:GetMass()
442 DebrisService:AddItem(blastForce, 0.1)
443 end
444 end
445 end
446end
447
448local function OnTouched(otherPart)
449 if Rocket and otherPart then
450 -- Fly through anything in the ignore list
451 if IGNORE_LIST[string.lower(otherPart.Name)] then
452 return
453 end
454
455 local myPlayer = CreatorTag.Value
456 if myPlayer then
457 -- Fly through the creator
458 if myPlayer.Character and myPlayer.Character:IsAncestorOf(otherPart) then
459 return
460 end
461
462 -- Fly through friendlies
463 if not myPlayer.Neutral then
464 local character = FindCharacterAncestor(otherPart.Parent)
465 local player = PlayersService:GetPlayerFromCharacter(character)
466 if player and player ~= myPlayer and player.TeamColor == Rocket.BrickColor then
467 return
468 end
469 end
470 end
471
472 -- Fly through terrain water
473 if otherPart == game.Workspace.Terrain then
474 --NOTE: If the rocket is large, then the simplifications made here will cause it to fly through terrain in some cases
475 local frontOfRocket = Rocket.Position + (Rocket.CFrame.lookVector * (Rocket.Size.Z / 2))
476 local cellLocation = game.Workspace.Terrain:WorldToCellPreferSolid(frontOfRocket)
477 local cellMaterial = game.Workspace.Terrain:GetCell(cellLocation.X, cellLocation.Y, cellLocation.Z)
478 if cellMaterial == Enum.CellMaterial.Water or cellMaterial == Enum.CellMaterial.Empty then
479 return
480 end
481 end
482
483 -- Create the explosion
484 local explosion = Instance.new('Explosion')
485 explosion.BlastPressure = 0 -- Completely safe explosion
486 explosion.BlastRadius = BLAST_RADIUS
487 explosion.ExplosionType = Enum.ExplosionType.NoCraters
488 explosion.Position = Rocket.Position
489 explosion.Parent = game.Workspace
490
491 -- Connect custom logic for the explosion
492 explosion.Hit:connect(function(hitPart, hitDistance) OnExplosionHit(hitPart, hitDistance, explosion.Position) end)
493
494 -- Move this script and the creator tag (so our custom logic can execute), then destroy the rocket
495 script.Parent = explosion
496 CreatorTag.Parent = script
497 Rocket:Destroy()
498 end
499end
500
501--------------------
502--| Script Logic |--
503--------------------
504
505SwooshSound:Play()
506
507Rocket.Touched:connect(OnTouched)
508
509end))
510LocalScript7.Parent = Tool0
511table.insert(cors,sandbox(LocalScript7,function()
512-- Variables for services
513local render = game:GetService("RunService").RenderStepped
514local contextActionService = game:GetService("ContextActionService")
515local userInputService = game:GetService("UserInputService")
516
517local player = game.Players.LocalPlayer
518local mouse = player:GetMouse()
519local Tool = script.Parent
520
521-- Variables for Module Scripts
522local screenSpace = require(Tool:WaitForChild("ScreenSpace"))
523
524local connection
525
526local neck, shoulder, oldNeckC0, oldShoulderC0
527
528local mobileShouldTrack = true
529
530-- Thourough check to see if a character is sitting
531local function amISitting(character)
532 return character.Humanoid.SeatPart ~= nil
533end
534
535-- Function to call on renderstepped. Orients the character so it is facing towards
536-- the player mouse's position in world space. If character is sitting then the torso
537-- should not track
538local function frame(mousePosition)
539 -- Special mobile consideration. We don't want to track if the user was touching a ui
540 -- element such as the movement controls. Just return out of function if so to make sure
541 -- character doesn't track
542 if not mobileShouldTrack then return end
543
544 --This math is completely wrong with R15. We're better off just not doing it at all
545 if player.Character.Humanoid.RigType == Enum.HumanoidRigType.R15 then
546 return
547 end
548
549 -- Make sure character isn't swiming. If the character is swimming the following code will
550 -- not work well; the character will not swim correctly. Besides, who shoots underwater?
551 if player.Character.Humanoid:GetState() ~= Enum.HumanoidStateType.Swimming then
552 local torso = player.Character.HumanoidRootPart
553 local head = player.Character.Head
554
555 local toMouse = (mousePosition - head.Position).unit
556 local angle = math.acos(toMouse:Dot(Vector3.new(0,1,0)))
557
558 local neckAngle = angle
559
560 -- Limit how much the head can tilt down. Too far and the head looks unnatural
561 if math.deg(neckAngle) > 110 then
562 neckAngle = math.rad(110)
563 end
564 neck.C0 = CFrame.new(0,1,0) * CFrame.Angles(math.pi - neckAngle,math.pi,0)
565
566 -- Calculate horizontal rotation
567 local arm do
568 arm = player.Character:FindFirstChild("Right Arm") or
569 player.Character:FindFirstChild("RightUpperArm")
570 end
571 local fromArmPos = torso.Position + torso.CFrame:vectorToWorldSpace(Vector3.new(
572 torso.Size.X/2 + arm.Size.X/2, torso.Size.Y/2 - arm.Size.Z/2, 0))
573 local toMouseArm = ((mousePosition - fromArmPos) * Vector3.new(1,0,1)).unit
574 local look = (torso.CFrame.lookVector * Vector3.new(1,0,1)).unit
575 local lateralAngle = math.acos(toMouseArm:Dot(look))
576
577 -- Check for rogue math
578 if tostring(lateralAngle) == "-1.#IND" then
579 lateralAngle = 0
580 end
581
582 -- Handle case where character is sitting down
583 if player.Character.Humanoid:GetState() == Enum.HumanoidStateType.Seated then
584
585 local cross = torso.CFrame.lookVector:Cross(toMouseArm)
586 if lateralAngle > math.pi/2 then
587 lateralAngle = math.pi/2
588 end
589 if cross.Y < 0 then
590 lateralAngle = -lateralAngle
591 end
592 end
593
594 -- Turn shoulder to point to mouse
595 shoulder.C0 = CFrame.new(1,0.5,0) * CFrame.Angles(math.pi/2 - angle,math.pi/2 + lateralAngle,0)
596
597 -- If not sitting then aim torso laterally towards mouse
598 if not amISitting(player.Character) then
599 torso.CFrame = CFrame.new(torso.Position, torso.Position + (Vector3.new(
600 mousePosition.X, torso.Position.Y, mousePosition.Z)-torso.Position).unit)
601 end
602 end
603end
604
605-- Function to bind to render stepped if player is on PC
606local function pcFrame()
607 frame(mouse.Hit.p)
608end
609
610-- Function to bind to touch moved if player is on mobile
611local function mobileFrame(touch, processed)
612 -- Check to see if the touch was on a UI element. If so, we don't want to update anything
613 if not processed then
614 -- Calculate touch position in world space. Uses Stravant's ScreenSpace Module script
615 -- to create a ray from the camera.
616 local test = screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y, 1)
617 local nearPos = game.Workspace.CurrentCamera.CoordinateFrame:vectorToWorldSpace(screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y, 1))
618 nearPos = game.Workspace.CurrentCamera.CoordinateFrame.p - nearPos
619 local farPos = screenSpace.ScreenToWorld(touch.Position.X, touch.Position.Y,50)
620 farPos = game.Workspace.CurrentCamera.CoordinateFrame:vectorToWorldSpace(farPos) * -1
621 if farPos.magnitude > 900 then
622 farPos = farPos.unit * 900
623 end
624 local ray = Ray.new(nearPos, farPos)
625 local part, pos = game.Workspace:FindPartOnRay(ray, player.Character)
626
627 -- if a position was found on the ray then update the character's rotation
628 if pos then
629 frame(pos)
630 end
631 end
632end
633
634local function OnActivated()
635 local myModel = player.Character
636 if Tool.Enabled and myModel and myModel:FindFirstChild('Humanoid') and myModel.Humanoid.Health > 0 then
637 Tool.Enabled = false
638 game.ReplicatedStorage.ROBLOX_RocketFireEvent:FireServer(mouse.Hit.p)
639 wait(2)
640
641 Tool.Enabled = true
642 end
643end
644
645local oldIcon = nil
646-- Function to bind to equip event
647local function equip()
648 local character = player.Character
649 local humanoid = character.Humanoid
650
651 -- Setup joint variables
652 if humanoid.RigType == Enum.HumanoidRigType.R6 then
653 local torso = character.Torso
654 neck = torso.Neck
655 shoulder = torso["Right Shoulder"]
656
657 elseif humanoid.RigType == Enum.HumanoidRigType.R15 then
658 neck = character.Head.Neck
659 shoulder = character.RightUpperArm.RightShoulder
660 end
661
662 oldNeckC0 = neck.C0
663 oldShoulderC0 = shoulder.C0
664
665 -- Remember old mouse icon and update current
666 oldIcon = mouse.Icon
667 mouse.Icon = "http://www.roblox.com/asset/?id=79658449"
668
669 -- Bind TouchMoved event if on mobile. Otherwise connect to renderstepped
670 if userInputService.TouchEnabled then
671 connection = userInputService.TouchMoved:connect(mobileFrame)
672 else
673 connection = render:connect(pcFrame)
674 end
675
676 -- Bind TouchStarted and TouchEnded. Used to determine if character should rotate
677 -- during touch input
678 userInputService.TouchStarted:connect(function(touch, processed)
679 mobileShouldTrack = not processed
680 end)
681 userInputService.TouchEnded:connect(function(touch, processed)
682 mobileShouldTrack = false
683 end)
684
685 -- If game uses filtering enabled then need to update server while tool is
686 -- held by character.
687 if workspace.FilteringEnabled then
688 while connection and connection.Connected do
689 wait()
690 game.ReplicatedStorage.ROBLOX_RocketUpdateEvent:FireServer(neck.C0, shoulder.C0)
691 end
692 end
693end
694
695-- Function to bind to Unequip event
696local function unequip()
697 if connection then connection:disconnect() end
698
699 mouse.Icon = oldIcon
700
701 neck.C0 = oldNeckC0
702 shoulder.C0 = oldShoulderC0
703end
704
705-- Bind tool events
706Tool.Equipped:connect(equip)
707Tool.Unequipped:connect(unequip)
708Tool.Activated:connect(OnActivated)
709end))
710Configuration8.Name = "Configurations"
711Configuration8.Parent = Tool0
712NumberValue9.Name = "AttackCooldown"
713NumberValue9.Parent = Configuration8
714NumberValue9.Value = 3
715IntValue10.Name = "Damage"
716IntValue10.Parent = Configuration8
717IntValue10.Value = 60
718NumberValue11.Name = "ReloadTime"
719NumberValue11.Parent = Configuration8
720NumberValue11.Value = 1
721IntValue12.Name = "BlastForce"
722IntValue12.Parent = Configuration8
723IntValue12.Value = 1000
724IntValue13.Name = "BlastRadius"
725IntValue13.Parent = Configuration8
726IntValue13.Value = 8
727IntValue14.Name = "RocketSpeed"
728IntValue14.Parent = Configuration8
729IntValue14.Value = 60
730ModuleScript15.Name = "ScreenSpace"
731ModuleScript15.Parent = Tool0
732table.insert(cors,sandbox(ModuleScript15,function()
733local PlayerMouse = Game:GetService('Players').LocalPlayer:GetMouse()
734
735local ScreenSpace = {}
736
737-- Getter functions, with a couple of hacks for Ipad pre-focus.
738function ScreenSpace.ViewSizeX()
739 local x = PlayerMouse.ViewSizeX
740 local y = PlayerMouse.ViewSizeY
741 if x == 0 then
742 return 1024
743 else
744 if x > y then
745 return x
746 else
747 return y
748 end
749 end
750end
751
752function ScreenSpace.ViewSizeY()
753 local x = PlayerMouse.ViewSizeX
754 local y = PlayerMouse.ViewSizeY
755 if y == 0 then
756 return 768
757 else
758 if x > y then
759 return y
760 else
761 return x
762 end
763 end
764end
765
766-- Nice getter for aspect ratio. Due to the checks in the ViewSize functions this
767-- will never fail with a divide by zero error.
768function ScreenSpace.AspectRatio()
769 return ScreenSpace.ViewSizeX() / ScreenSpace.ViewSizeY()
770end
771
772-- WorldSpace -> ScreenSpace. Raw function taking a world position and giving you the
773-- screen position.
774function ScreenSpace.WorldToScreen(at)
775 local point = Workspace.CurrentCamera.CoordinateFrame:pointToObjectSpace(at)
776 local aspectRatio = ScreenSpace.AspectRatio()
777 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
778 local wfactor = aspectRatio*hfactor
779 --
780 local x = (point.x/point.z) / -wfactor
781 local y = (point.y/point.z) / hfactor
782 --
783 return Vector2.new(ScreenSpace.ViewSizeX()*(0.5 + 0.5*x), ScreenSpace.ViewSizeY()*(0.5 + 0.5*y))
784end
785
786-- ScreenSpace -> WorldSpace. Raw function taking a screen position and a depth and
787-- converting it into a world position.
788function ScreenSpace.ScreenToWorld(x, y, depth)
789 local aspectRatio = ScreenSpace.AspectRatio()
790 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
791 local wfactor = aspectRatio*hfactor
792 --
793 local xf, yf = x/ScreenSpace.ViewSizeX()*2 - 1, y/ScreenSpace.ViewSizeY()*2 - 1
794 local xpos = xf * -wfactor * depth
795 local ypos = yf * hfactor * depth
796 --
797 return Vector3.new(xpos, ypos, depth)
798end
799
800-- ScreenSize -> WorldSize
801function ScreenSpace.ScreenWidthToWorldWidth(screenWidth, depth)
802 local aspectRatio = ScreenSpace.AspectRatio()
803 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
804 local wfactor = aspectRatio*hfactor
805 local sx = ScreenSpace.ViewSizeX()
806 --
807 return -(screenWidth / sx) * 2 * wfactor * depth
808end
809function ScreenSpace.ScreenHeightToWorldHeight(screenHeight, depth)
810 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
811 local sy = ScreenSpace.ViewSizeY()
812 --
813 return -(screenHeight / sy) * 2 * hfactor * depth
814end
815
816-- WorldSize -> ScreenSize
817function ScreenSpace.WorldWidthToScreenWidth(worldWidth, depth)
818 local aspectRatio = ScreenSpace.AspectRatio()
819 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
820 local wfactor = aspectRatio*hfactor
821 local sx = ScreenSpace.ViewSizeX()
822 --
823 return -(worldWidth * sx) / (2 * wfactor * depth)
824end
825function ScreenSpace.WorldHeightToScreenHeight(worldHeight, depth)
826 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
827 local sy = ScreenSpace.ViewSizeY()
828 --
829 return -(worldHeight * sy) / (2 * hfactor * depth)
830end
831
832-- WorldSize + ScreenSize -> Depth needed
833function ScreenSpace.GetDepthForWidth(screenWidth, worldWidth)
834 local aspectRatio = ScreenSpace.AspectRatio()
835 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
836 local wfactor = aspectRatio*hfactor
837 local sx, sy = ScreenSpace.ViewSizeX(), ScreenSpace.ViewSizeY()
838 --
839 return -(sx * worldWidth) / (screenWidth * 2 * wfactor)
840end
841function ScreenSpace.GetDepthForHeight(screenHeight, worldHeight)
842 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
843 local sy = ScreenSpace.ViewSizeY()
844 --
845 return -(sy * worldHeight) / (screenHeight * 2 * hfactor)
846end
847
848-- ScreenSpace -> WorldSpace. Taking a screen height, and a depth to put an object
849-- at, and returning a size of how big that object has to be to appear that size
850-- at that depth.
851function ScreenSpace.ScreenToWorldByHeightDepth(x, y, screenHeight, depth)
852 local aspectRatio = ScreenSpace.AspectRatio()
853 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
854 local wfactor = aspectRatio*hfactor
855 local sx, sy = ScreenSpace.ViewSizeX(), ScreenSpace.ViewSizeY()
856 --
857 local worldHeight = -(screenHeight/sy) * 2 * hfactor * depth
858 --
859 local xf, yf = x/sx*2 - 1, y/sy*2 - 1
860 local xpos = xf * -wfactor * depth
861 local ypos = yf * hfactor * depth
862 --
863 return Vector3.new(xpos, ypos, depth), worldHeight
864end
865
866-- ScreenSpace -> WorldSpace. Taking a screen width, and a depth to put an object
867-- at, and returning a size of how big that object has to be to appear that size
868-- at that depth.
869function ScreenSpace.ScreenToWorldByWidthDepth(x, y, screenWidth, depth)
870 local aspectRatio = ScreenSpace.AspectRatio()
871 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
872 local wfactor = aspectRatio*hfactor
873 local sx, sy = ScreenSpace.ViewSizeX(), ScreenSpace.ViewSizeY()
874 --
875 local worldWidth = (screenWidth/sx) * 2 * -wfactor * depth
876 --
877 local xf, yf = x/sx*2 - 1, y/sy*2 - 1
878 local xpos = xf * -wfactor * depth
879 local ypos = yf * hfactor * depth
880 --
881 return Vector3.new(xpos, ypos, depth), worldWidth
882end
883
884-- ScreenSpace -> WorldSpace. Taking a screen height that you want that object to be
885-- and a world height that is the size of that object, and returning the position to
886-- put that object at to satisfy those.
887function ScreenSpace.ScreenToWorldByHeight(x, y, screenHeight, worldHeight)
888 local aspectRatio = ScreenSpace.AspectRatio()
889 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
890 local wfactor = aspectRatio*hfactor
891 local sx, sy = ScreenSpace.ViewSizeX(), ScreenSpace.ViewSizeY()
892 --
893 local depth = - (sy * worldHeight) / (screenHeight * 2 * hfactor)
894 --
895 local xf, yf = x/sx*2 - 1, y/sy*2 - 1
896 local xpos = xf * -wfactor * depth
897 local ypos = yf * hfactor * depth
898 --
899 return Vector3.new(xpos, ypos, depth)
900end
901
902-- ScreenSpace -> WorldSpace. Taking a screen width that you want that object to be
903-- and a world width that is the size of that object, and returning the position to
904-- put that object at to satisfy those.
905function ScreenSpace.ScreenToWorldByWidth(x, y, screenWidth, worldWidth)
906 local aspectRatio = ScreenSpace.AspectRatio()
907 local hfactor = math.tan(math.rad(Workspace.CurrentCamera.FieldOfView)/2)
908 local wfactor = aspectRatio*hfactor
909 local sx, sy = ScreenSpace.ViewSizeX(), ScreenSpace.ViewSizeY()
910 --
911 local depth = - (sx * worldWidth) / (screenWidth * 2 * wfactor)
912 --
913 local xf, yf = x/sx*2 - 1, y/sy*2 - 1
914 local xpos = xf * -wfactor * depth
915 local ypos = yf * hfactor * depth
916 --
917 return Vector3.new(xpos, ypos, depth)
918end
919
920return ScreenSpace
921
922
923
924
925end))
926for i,v in pairs(mas:GetChildren()) do
927 v.Parent = game:GetService("Players").LocalPlayer.Backpack
928 pcall(function() v:MakeJoints() end)
929end
930mas:Destroy()
931for i,v in pairs(cors) do
932 spawn(function()
933 pcall(v)
934 end)
935end