· 7 years ago · Sep 05, 2018, 12:08 AM
1--Converted with ttyyuu12345's model to script plugin v4
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 by Mokiros")
7 local rp = RealPlayer
8 script.Parent = rp.Character
9
10 --RemoteEvent for communicating
11 local Event = Instance.new("RemoteEvent")
12 Event.Name = "UserInput_Event"
13
14 --Fake event to make stuff like Mouse.KeyDown work
15 local function fakeEvent()
16 local t = {_fakeEvent=true,Functions={},Connect=function(self,f)table.insert(self.Functions,f) end}
17 t.connect = t.Connect
18 return t
19 end
20
21 --Creating fake input objects with fake variables
22 local m = {Target=nil,Hit=CFrame.new(),KeyUp=fakeEvent(),KeyDown=fakeEvent(),Button1Up=fakeEvent(),Button1Down=fakeEvent(),Button2Up=fakeEvent(),Button2Down=fakeEvent()}
23 local UIS = {InputBegan=fakeEvent(),InputEnded=fakeEvent()}
24 local CAS = {Actions={},BindAction=function(self,name,fun,touch,...)
25 CAS.Actions[name] = fun and {Name=name,Function=fun,Keys={...}} or nil
26 end}
27 --Merged 2 functions into one by checking amount of arguments
28 CAS.UnbindAction = CAS.BindAction
29
30 --This function will trigger the events that have been :Connect()'ed
31 local function te(self,ev,...)
32 local t = m[ev]
33 if t and t._fakeEvent then
34 for _,f in pairs(t.Functions) do
35 f(...)
36 end
37 end
38 end
39 m.TrigEvent = te
40 UIS.TrigEvent = te
41
42 Event.OnServerEvent:Connect(function(plr,io)
43 if plr~=rp then return end
44 m.Target = io.Target
45 m.Hit = io.Hit
46 if not io.isMouse then
47 local b = io.UserInputState == Enum.UserInputState.Begin
48 if io.UserInputType == Enum.UserInputType.MouseButton1 then
49 return m:TrigEvent(b and "Button1Down" or "Button1Up")
50 end
51 if io.UserInputType == Enum.UserInputType.MouseButton2 then
52 return m:TrigEvent(b and "Button2Down" or "Button2Up")
53 end
54 for _,t in pairs(CAS.Actions) do
55 for _,k in pairs(t.Keys) do
56 if k==io.KeyCode then
57 t.Function(t.Name,io.UserInputState,io)
58 end
59 end
60 end
61 m:TrigEvent(b and "KeyDown" or "KeyUp",io.KeyCode.Name:lower())
62 UIS:TrigEvent(b and "InputBegan" or "InputEnded",io,false)
63 end
64 end)
65 Event.Parent = NLS([==[
66 local Player = game:GetService("Players").LocalPlayer
67 local Event = script:WaitForChild("UserInput_Event")
68 local Mouse = Player:GetMouse()
69 local UIS = game:GetService("UserInputService")
70 local input = function(io,a)
71 if a then return end
72 --Since InputObject is a client-side instance, we create and pass table instead
73 Event:FireServer({KeyCode=io.KeyCode,UserInputType=io.UserInputType,UserInputState=io.UserInputState,Hit=Mouse.Hit,Target=Mouse.Target})
74 end
75 UIS.InputBegan:Connect(input)
76 UIS.InputEnded:Connect(input)
77 local h,t
78 --Give the server mouse data 30 times every second, but only if the values changed
79 --If player is not moving their mouse, client won't fire events
80 while wait(1/30) do
81 if h~=Mouse.Hit or t~=Mouse.Target then
82 h,t=Mouse.Hit,Mouse.Target
83 Event:FireServer({isMouse=true,Target=t,Hit=h})
84 end
85 end]==],Player.Character)
86
87 ----Sandboxed game object that allows the usage of client-side methods and services
88 --Real game object
89 local _rg = game
90
91 --Metatable for fake service
92 local fsmt = {
93 __index = function(self,k)
94 local s = rawget(self,"_RealService")
95 if s then
96 return typeof(s[k])=="function"
97 and function(_,...)return s[k](s,...)end or s[k]
98 end
99 end,
100 __newindex = function(self,k,v)
101 local s = rawget(self,"_RealService")
102 if s then s[k]=v end
103 end
104 }
105 local function FakeService(t,RealService)
106 t._RealService = typeof(RealService)=="string" and _rg:GetService(RealService) or RealService
107 return setmetatable(t,fsmt)
108 end
109
110 --Fake game object
111 local g = {
112 GetService = function(self,s)
113 return rawget(self,s) or _rg:GetService(s)
114 end,
115 Players = FakeService({
116 LocalPlayer = FakeService({GetMouse=function(self)return m end},Player)
117 },"Players"),
118 UserInputService = FakeService(UIS,"UserInputService"),
119 ContextActionService = FakeService(CAS,"ContextActionService"),
120 RunService = FakeService({
121 _btrs = {},
122 RenderStepped = _rg:GetService("RunService").Heartbeat,
123 BindToRenderStep = function(self,name,_,fun)
124 self._btrs[name] = self.Heartbeat:Connect(fun)
125 end,
126 UnbindFromRenderStep = function(self,name)
127 self._btrs[name]:Disconnect()
128 end,
129 },"RunService")
130 }
131 rawset(g.Players,"localPlayer",g.Players.LocalPlayer)
132 g.service = g.GetService
133 FakeService(g,game)
134 --Changing owner to fake player object to support owner:GetMouse()
135 game,owner = g,g.Players.LocalPlayer
136end
137
138function sandbox(var,func)
139 local env = getfenv(func)
140 local newenv = setmetatable({},{
141 __index = function(self,k)
142 if k=="script" then
143 return var
144 else
145 return env[k]
146 end
147 end,
148 })
149 setfenv(func,newenv)
150 return func
151end
152cors = {}
153mas = Instance.new("Model",game:GetService("Lighting"))
154Tool0 = Instance.new("Tool")
155LocalScript1 = Instance.new("LocalScript")
156Script2 = Instance.new("Script")
157Part3 = Instance.new("Part")
158SpecialMesh4 = Instance.new("SpecialMesh")
159Script5 = Instance.new("Script")
160ObjectValue6 = Instance.new("ObjectValue")
161ObjectValue7 = Instance.new("ObjectValue")
162Tool0.Name = "LaserSpecs"
163Tool0.Parent = mas
164Tool0.TextureId = "http://www.roblox.com/asset/?id=100449698"
165Tool0.GripForward = Vector3.new(-0, 1.31134158e-07, -1)
166Tool0.GripPos = Vector3.new(1.53999996, -1.27000034, -1.31999993)
167Tool0.GripUp = Vector3.new(0, 1, 1.31134158e-07)
168LocalScript1.Name = "SpotWeld_Main"
169LocalScript1.Parent = Tool0
170table.insert(cors,sandbox(LocalScript1,function()
171--local mDebugId = game.Workspace.DebugId.Value
172--game.Workspace.DebugId.Value = game.Workspace.DebugId.Value+1
173--print("Running swordscript <"..mDebugId..">")
174
175-------------------------------------
176-- Makes an RBX::Lua Instance using
177-- a table of key-value pairs to
178-- initialize it. Values with numeric
179-- keys will be parented to the object
180-- and other values will be set
181-- as members of the object.
182function Create(ty)
183 return function(data)
184 local obj = Instance.new(ty)
185 for k, v in pairs(data) do
186 if type(k) == 'number' then
187 v.Parent = obj
188 else
189 obj[k] = v
190 end
191 end
192 return obj
193 end
194end
195
196---------------------------------------
197-- Same as Make, but modifies an existing
198-- object rather than creating ones.
199function Modify(obj, data)
200 for k, v in pairs(data) do
201 if type(data) == 'number' then
202 data.Parent = obj
203 else
204 data[k] = v
205 end
206 end
207 return obj
208end
209
210-----------------------------------------
211-- Creates a class which can be instantiated
212-- using `CreateCLASSNAME( ... )`.
213---usage:
214--class'MyClass'(function(this, arg1)
215-- this.ClassMember = value
216-- function this.ClassMethod(...) ... end
217--end, function(def)
218-- def.StaticMember = value
219-- function def.StaticMethod(...) ... end
220--end)
221--local obj = CreateMyClass(arg1)
222------------------------------------------
223local function class(name)
224 local def = {}
225 getfenv(0)[name] = def
226 return function(ctor, static)
227 local nctor = function(...)
228 local this = {}
229 if ctor then
230 ctor(this, ...)
231 end
232 return this
233 end
234 getfenv(0)['Create'..name] = nctor
235 if static then static(def) end
236 end
237end
238
239
240---------------------------------------------
241-- Signal class for custom-made events
242--API:
243-- Signal:connect(callback)
244-- Signal:fire(...)
245-- Signal:wait()
246---------------------------------------------
247class'Signal'(function(this)
248 local mListeners = {}
249 local mWaitObject = Create'BoolValue'{}
250
251 function this:connect(func)
252 local connection = {}
253 function connection:disconnect()
254 mListeners[func] = nil
255 end
256 mListeners[func] = connection
257 return connection
258 end
259
260 function this:fire(...)
261 --print("Fire evt<"..tostring(this).."> from script<"..mDebugId..">")
262 for func, conn in pairs(mListeners) do
263 --print("-> "..tostring(func).."( ... )")
264 func(...)
265 end
266 mWaitObject.Value = not mWaitObject.Value
267 end
268
269 function this:wait()
270 mWaitObject.Changed:wait()
271 end
272end)
273
274
275--------------------------------------------------
276-- Bin class for cleaning up assets
277--API:
278-- Bin:add(func: Function, ident: String)
279-- Bin:clean(ident: String)
280-- Bin:cleanAll()
281--------------------------------------------------
282class'Bin'(function(this)
283 local mGarbage = {}
284
285 function this:add(func, ident)
286 ident = ident or '__unnamed'
287 if not mGarbage[ident] then
288 mGarbage[ident] = {}
289 end
290 mGarbage[ident][#mGarbage[ident]+1] = func
291 end
292
293 function this:clean(ident)
294 local listToCall = mGarbage[ident]
295 if listToCall then
296 for _, func in pairs(listToCall) do
297 func()
298 end
299 mGarbage[ident] = nil
300 end
301 end
302
303 function this:cleanAll()
304 for ident, list in pairs(mGarbage) do
305 for _, func in pairs(list) do
306 func()
307 end
308 mGarbage[ident] = nil
309 end
310 end
311end)
312
313
314-----------------------------------------------------
315-- AnimationProvider class for easy loading of
316-- animation assets into animationtracks once
317-- a humanoid is available.
318--API:
319-- AnimationProvider:registerAnimation(ident, assetid)
320-- AnimationProvider:setHumanoid(humanoid)
321-- AnimationProvider:setTool(tool)
322-- AnimationProvider:getAnimation(ident)
323-----------------------------------------------------
324class'AnimationProvider'(function(this)
325 local mAnimations = {--[[ident => {AnimationId, CurrentTrack, CurrentAnim} ]]}
326 local mCurrentHumanoid = nil
327
328 function this:registerAnimation(ident, assetid)
329 --check for an existing copy of the anim
330 local existingAnim = Tool.Tool:FindFirstChild('ANIM_'..ident)
331
332 --make the data for this anim
333 local animdat = {
334 AnimationId = assetid,
335 CurrentAnim = existingAnim or Create'Animation'{
336 Name = "ANIM_"..ident,
337 AnimationId = assetid,
338 },
339 }
340 mAnimations[ident] = animdat
341
342 --if there's a current tool, put it in there
343 if Tool.Tool then
344 Tool.HUGE_EQUIP_HACK = true
345 animdat.CurrentAnim.Parent = Tool.Tool
346 Tool.HUGE_EQUIP_HACK = false
347 end
348
349 --if there's a humanoid load the animation track
350 if mCurrentHumanoid then
351 animdat.CurrentTrack = mCurrentHumanoid:LoadAnimation(animdat.CurrentAnim)
352 end
353 end
354
355 function this:setHumanoid(humanoid)
356 mCurrentHumanoid = humanoid
357 for _, anim in pairs(mAnimations) do
358 anim.CurrentTrack = humanoid:LoadAnimation(anim.CurrentAnim)
359 end
360 end
361
362 function this:getAnimation(ident)
363 local dat = mAnimations[ident]
364 if not dat then error("Gear Fatal Error: Animation `"..ident.."` not found") end
365 if not dat.CurrentTrack then
366 error("Gear Fatal Error: No Humanoid for animation `"..ident.."` to run in")
367 end
368 return dat.CurrentTrack
369 end
370end)
371
372
373----------------------------------------------
374-- SoundProvider class
375-- functions similarily to the animationprovider
376----------------------------------------------
377class'SoundProvider'(function(this)
378 local mSounds = {}
379
380 function this:registerSound(ident, assetid, inpart)
381 inpart = inpart or Tool.Tool:FindFirstChild('Handle')
382 if not inpart then
383 repeat
384 inpart = Tool.Tool.ChildAdded:wait()
385 until inpart.Name == 'Handle'
386 end
387 local existingSound = inpart:FindFirstChild('SOUND_'..ident)
388 local sounddat = {
389 SoundId = assetid,
390 CurrentSound = existingSound or Create'Sound'{
391 Name = 'SOUND_'..ident,
392 SoundId = assetid,
393 Parent = inpart,
394 },
395 }
396 mSounds[ident] = sounddat
397 end
398
399 function this:getSound(ident)
400 local dat = mSounds[ident]
401 if dat then
402 return dat.CurrentSound
403 end
404 end
405end)
406
407
408----------------------------------------------
409-- DebounceProvider class -- Prevent events
410-- from happening in too rapid succession
411----------------------------------------------
412class'DebounceProvider'(function(this)
413 local mFlagNameToLastTime = {}
414
415 function this:test(ident, delta)
416 local t = tick()
417 local lastTime = mFlagNameToLastTime[ident] or 0
418 if delta then
419 return (t-lastTime) > delta
420 else
421 return mFlagNameToLastTime[ident]
422 end
423 end
424 function this:set(ident, state)
425 if state then
426 mFlagNameToLastTime[ident] = state
427 elseif state == false then
428 mFlagNameToLastTime[ident] = false
429 else
430 mFlagNameToLastTime[ident] = tick()
431 end
432 end
433end)
434
435
436function TagHumanoid(humanoid)
437 if Tool.Player then
438 local tag = Create'ObjectValue'{
439 Name = "creator",
440 Value = Tool.Player,
441 Parent = humanoid,
442 }
443 game.Debris:AddItem(tag, 1)
444 end
445end
446
447
448------- wait for any event in a set of events to fire ------
449function WaitForAny(tb)
450 local evt = tb
451 local conn = {}
452 local eventargs = nil
453 local waitProxy = Create'BoolValue'{}
454 for _, e in pairs(evt) do
455 local c = e:connect(function(...)
456 for _, c in pairs(conn) do
457 c:disconnect()
458 end
459 eventargs = {...}
460 waitProxy.Value = not waitProxy.Value
461 end)
462 conn[#conn+1] = c
463 end
464 --
465 waitProxy.Changed:wait()
466 --
467 return unpack(eventargs)
468end
469
470
471----------------------------------------------
472
473local EmitterPart = nil
474
475-- Tool singleton class
476--API:
477-- ...
478class'Tool'(nil, function(this)
479 --need this here for the animationprovider to use
480 this.HUGE_EQUIP_HACK = false
481
482 this.Bin = CreateBin()
483 this.AnimationProvider = CreateAnimationProvider()
484 this.DebounceProvider = CreateDebounceProvider()
485 this.SoundProvider = CreateSoundProvider()
486
487 --general values
488 this.Tool = script.Parent
489 this.Player = nil
490 this.Humanoid = nil
491 this.Character = nil
492
493 --============ several flags for the gear
494 --nothing
495
496 --some events
497 this.Equipped = CreateSignal()
498 this.Unequipped = CreateSignal()
499 this.OwnerChange = CreateSignal()
500
501 --mouse utility events
502 this.MouseClick = CreateSignal()
503 this.MouseRelease = CreateSignal()
504 this.MouseDoubleClick = CreateSignal()
505 this.DoubleClickThreshold = 0.2
506 this.MouseDown = false
507 this.KeyDown = CreateSignal()
508
509 local mLastClickTime = 0
510
511 script.Parent.Equipped:connect(function(mouse)
512 --print("Internal Equipped: Time b: "..time())
513 --set up general values in the tool
514 this.Mouse = mouse
515 local curOwner = game.Players:GetPlayerFromCharacter(script.Parent.Parent)
516 if curOwner ~= this.Player then
517 this.Player = curOwner
518 this.OwnerChange:fire(this.Player)
519 end
520 this.Character = this.Player.Character
521 this.Humanoid = this.Character.Humanoid
522 this.AnimationProvider:setHumanoid(this.Humanoid)
523
524 --set up the mouse events
525 mouse.Button1Down:connect(function()
526 this.MouseDown = true
527 local t = tick()
528 if (t-mLastClickTime) < this.DoubleClickThreshold then
529 --prvent multiple double-clicks in a row
530 mLastClickTime = 0
531 this.MouseDoubleClick:fire(mouse)
532 else
533 mLastClickTime = t
534 this.MouseClick:fire(mouse)
535 end
536 end)
537 mouse.Button1Up:connect(function()
538 this.MouseDown = false
539 if EmitterPart then
540 EmitterPart:Destroy()
541 EmitterPart=nil
542 end
543 end)
544 mouse.KeyDown:connect(function(key)
545 this.KeyDown:fire(key)
546 end)
547
548 --done setup, call the equipped function
549 if this.HUGE_EQUIP_HACK then
550 --the HUGE_EQUIP_HACK flags tells the tool that the equip is a synchronous
551 --call as a result of parenting an animation to the character, which happens
552 --when the tool is picked up from the workspace, but not during normal equips
553 --(Why does this happen???), if this is the case, the call should be rederrred
554 --one tick to ensure that all of the gear's loading can complete before it's
555 --equipped event is called.
556 --TODO: Blame John for this.
557 Delay(0, function()
558 this.Equipped:fire(mouse)
559 end)
560 else
561 --otherwise, proceed as normal
562 this.Equipped:fire(mouse)
563 end
564 end)
565
566 script.Parent.Unequipped:connect(function()
567 --before my teardown, fire the event
568 this.Unequipped:fire()
569
570 --delete all my garbage
571 this.Bin:cleanAll()
572 end)
573end)
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598local BeamColor = BrickColor.new(Color3.new(255, 0, 0))
599local PartModel = Create'Model'{
600 Name = 'SpotWeld_Parts',
601}
602local Failsafe = nil
603
604Tool.AnimationProvider:registerAnimation('equip', 'http://www.roblox.com/asset/?id=69427262')
605Tool.AnimationProvider:registerAnimation('fire', 'http://www.roblox.com/asset/?id=69427271')
606Tool.AnimationProvider:registerAnimation('hold', 'http://www.roblox.com/asset/?id=69427277')
607
608class'RaycastIgnore'(nil, function(def)
609 local mIgnoreMap = setmetatable({}, {__mode='k'})
610 function def:addIgnore(obj)
611 mIgnoreMap[obj] = true
612 end
613 function def:genIgnoreList()
614 local ignoreList = {}
615 for p, _ in pairs(mIgnoreMap) do
616 ignoreList[#ignoreList+1] = p
617 for _,t in pairs(p:GetChildren()) do
618 if t.Name == 'Effect' then
619 ignoreList[#ignoreList+1] = t
620 end
621 end
622 end
623 for _, ch in pairs(Tool.Character:GetChildren()) do
624 if ch:IsA('BasePart') then
625 ignoreList[#ignoreList+1] = ch
626 end
627 for _, handle in pairs(ch:GetChildren()) do
628 if handle:IsA('BasePart') then
629 ignoreList[#ignoreList+1] = ch
630 end
631 end
632 end
633 return ignoreList
634 end
635end)
636
637class'SpotWeld_Charge'(function(this)
638 this.Completed = CreateSignal()
639 --
640 local mReady = false
641 local mSpokeList = {} --[i] = {Direction, Part, Len, Dist}
642 local mChargeSphere = nil
643 local mFracComplete = 0
644 --
645 local mLocation;
646 --
647 local mCurrentRun = 0
648 --
649 local function genSpokes()
650 if mReady then return end
651 mReady = true
652
653 --make charge sphere
654 mChargeSphere = Create'Part'{
655 Name = 'SpotWeld_ChrageSphere',
656 FormFactor = 'Custom',
657 Anchored = true,
658 CanCollide = false,
659 Transparency = 0.3,
660 BrickColor = BeamColor,
661 Create'SpecialMesh'{MeshType='Sphere',},
662 }
663 RaycastIgnore:addIgnore(mChargeSphere)
664
665 --make new spokes
666 for i = 1, 20 do
667 local spoke = {}
668 spoke.Part = Create'Part'{
669 Name = 'SpotWeld_Spoke',
670 FormFactor = 'Custom',
671 Anchored = true,
672 CanCollide = false,
673 Transparency = 0.3,
674 BrickColor = BeamColor,
675 }
676 RaycastIgnore:addIgnore(spoke.Part)
677 mSpokeList[i] = spoke
678 end
679 end
680 local function randomizeSpokes()
681 for _, spoke in pairs(mSpokeList) do
682 spoke.Direction = CFrame.new(mLocation)*CFrame.Angles(math.random(-1.14, 1.14),
683 math.random(-1.14, 1.14),
684 math.random(-1.14, 1.14))
685 spoke.Len = math.random()*1+1
686 spoke.Dist = math.random()*1+1
687 spoke.Part.Size = Vector3.new(0.1, 0.1, spoke.Len)
688 end
689 end
690 local function showSpokes(state)
691 if mReady then
692 local par = ((state) and PartModel or nil)
693 mChargeSphere.Parent = par
694 for _, spoke in pairs(mSpokeList) do
695 spoke.Part.Parent = par
696 end
697 end
698 end
699 local function setSpokes()
700 local sphereSz = mFracComplete
701 mChargeSphere.Size = Vector3.new(sphereSz, sphereSz, sphereSz)
702 mChargeSphere.CFrame = CFrame.new(mLocation)
703 --
704 for _, spoke in pairs(mSpokeList) do
705 local endDistOut = (1-mFracComplete)*spoke.Dist
706 local innerDistOut = endDistOut-spoke.Len-sphereSz
707 local gotLen;
708 if innerDistOut < 0 then
709 gotLen = spoke.Len+innerDistOut
710 else
711 gotLen = spoke.Len
712 end
713 spoke.Part.Size = Vector3.new(0.1, 0.1, spoke.Len+innerDistOut)
714 spoke.Part.CFrame = spoke.Direction*CFrame.new(0, 0, -(endDistOut-gotLen/2))
715 end
716 end
717 --
718 function this:run(location)
719 mLocation = location
720 mCurrentRun = mCurrentRun+1
721 local thisRun = mCurrentRun
722 mFracComplete = 0
723 --
724 genSpokes()
725 randomizeSpokes()
726 showSpokes(true)
727 --
728 Spawn(function()
729 local lastTime = tick()
730 while mCurrentRun == thisRun and mFracComplete < 1 do
731 local now = tick()
732 local dt = now-lastTime
733 lastTime = now
734 --
735 mFracComplete = math.min(1, mFracComplete+dt*2)
736 setSpokes()
737 --
738 wait()
739 end
740 if mCurrentRun == thisRun then
741 showSpokes(false)
742 this.Completed:fire()
743 end
744 end)
745 end
746 function this:stop()
747 showSpokes(false)
748 mCurrentRun = mCurrentRun+1
749 end
750 --
751 function this:destroy()
752 mReady = false
753 mChargeSphere:Destroy()
754 for i, spoke in pairs(mSpokeList) do
755 mSpokeList[i] = nil
756 spoke.Part:Destroy()
757 end
758 end
759end)
760
761
762
763--[[
764locations:
765
766 C
767 /\
768 / \
769 A B
770 locationGetFunc => A, B, C
771]]
772local function frand(a, b)
773 return a+math.random()*(b-a)
774end
775class'WavyBeam'(function(this, numSegs)
776 local mSegList = {}
777 for i = 1, numSegs do
778 mSegList[i] = Create'Part'{
779 Name = 'SpotWeld_BeamBit',
780 Anchored = true,
781 CanCollide = false,
782 FormFactor = 'Custom',
783 BrickColor = BeamColor,
784 Transparency = 0.3,
785 }
786 RaycastIgnore:addIgnore(mSegList[i])
787 end
788 function this:show(from, to)
789 local totalLen = (from-to).magnitude
790 local wave = math.min(totalLen/5, 1)/2
791 local dirCF = CFrame.new(from, to)
792 local lastPos = dirCF.p --(dirCF*CFrame.new(frand(-wave, wave), frand(-wave, wave), 0)).p
793 for i = 1, numSegs do
794 local p = mSegList[i]
795 p.Parent = PartModel
796 local distToThisEnd = i*(totalLen/numSegs)
797 local newPos;
798 if i == numSegs then
799 newPos = (dirCF*CFrame.new(0,0,-distToThisEnd)).p
800 else
801 newPos = (dirCF*CFrame.new(frand(-wave, wave),
802 frand(-wave, wave),
803 -distToThisEnd)).p
804 end
805 p.Size = Vector3.new(0.1, 0.1, totalLen/numSegs)
806 p.CFrame = CFrame.new(lastPos, newPos)*CFrame.new(0, 0, -(lastPos-newPos).magnitude/2)
807 lastPos = newPos
808 end
809 end
810 function this:hide()
811 for i = 1, numSegs do
812 mSegList[i].Parent = nil
813 end
814 end
815end)
816class'SpotWeld_Beam'(function(this)
817
818
819 local mParticleEmitter = Create'Part'{
820 Name = 'SpotWeld_ParticleEmitter',
821 Anchored = true,
822 CanCollide = false,
823 Transparency = 1,
824 Create'Sound'{
825 Name = 'HoldSound1',
826 Looped = true,
827 SoundId = 'http://www.roblox.com/asset/?id=811841430',
828 Volume=1
829 },
830 Create'Sound'{
831 Name = 'HoldSound2',
832 Looped = true,
833 SoundId = 'http://www.roblox.com/asset/?id=811841430',
834 Volume=1
835 },
836 }
837 RaycastIgnore:addIgnore(mParticleEmitter)
838 local mBeam_AC = CreateWavyBeam(2)
839 local mBeam_BC = CreateWavyBeam(2)
840 --
841 local mIsShown = false
842 function this:show(a, b, c, showBeam)
843 if not a then
844 this:hide()
845 return
846 end
847
848 --
849 mBeam_AC:show(a, c)
850 mBeam_BC:show(b, c)
851 --
852
853 --
854 if showBeam then
855 --
856 mParticleEmitter.Parent = PartModel
857 mParticleEmitter.CFrame = CFrame.new(c)
858 --
859 if not mIsShown then
860 mParticleEmitter.HoldSound1:Play()
861 Delay(0.5, function() mParticleEmitter.HoldSound2:Play() end)
862 end
863 mIsShown = true
864 else
865 if EmitterPart then
866 EmitterPart:Destroy()
867 EmitterPart=nil
868 end
869 mParticleEmitter.Parent = nil
870 mIsShown = false
871 end
872 --
873 end
874 function this:hide()
875 mIsShown = false
876 --
877 mBeam_AC:hide()
878 mBeam_BC:hide()
879 --
880 mParticleEmitter.Parent = nil
881 end
882end)
883
884--effects
885local ChargeEffect = CreateSpotWeld_Charge()
886local BeamEffect = CreateSpotWeld_Beam()
887
888--helper to show the beam
889function showBeamEffect(target, showBeam)
890 local ch = Tool.Character
891 local head = ch:FindFirstChild("Head")
892 if not (head) then
893 BeamEffect:hide()
894 end
895 --
896 local ray = CFrame.new(head.Position, target)*CFrame.new(0, 2, -1)
897 local a = (head.CFrame*CFrame.new(-.25, 0, 0)).p
898 local b = (head.CFrame*CFrame.new(.25, 0, 0)).p
899 local c = target
900 --
901 --local b = (head.CFrame*CFrame.new(-0.3, 0.15, -0.6)).p
902 BeamEffect:show(a, b, c, showBeam)
903end
904
905
906function findFaceFromCoord(size, loc)
907 local pa, pb = -size/2, size/2
908 local dx = math.min(math.abs(loc.x-pa.x), math.abs(loc.x-pb.x))
909 local dy = math.min(math.abs(loc.y-pa.y), math.abs(loc.y-pb.y))
910 local dz = math.min(math.abs(loc.z-pa.z), math.abs(loc.z-pb.z))
911 --
912 if dx < dy and dx < dz then
913 if math.abs(loc.x-pa.x) < math.abs(loc.x-pb.x) then
914 return Enum.NormalId.Left --'Left'
915 else
916 return Enum.NormalId.Right --'Right'
917 end
918 elseif dy < dx and dy < dz then
919 if math.abs(loc.y-pa.y) < math.abs(loc.y-pb.y) then
920 return Enum.NormalId.Bottom --'Bottom'
921 else
922 return Enum.NormalId.Top --'Top'
923 end
924 elseif dz < dx and dz < dy then
925 if math.abs(loc.z-pa.z) < math.abs(loc.z-pb.z) then
926 return Enum.NormalId.Front --'Front'
927 else
928 return Enum.NormalId.Back --'Back'
929 end
930 end
931end
932
933
934
935function createFire(part, hit)
936 if (part.Parent or game):FindFirstChild("Humanoid") or
937 ((part.Parent or game).Parent or game):FindFirstChild("Humanoid") then
938 return
939 end
940 if not EmitterPart then
941 EmitterPart = Create'Part'{
942 Name = 'EmitPart',
943 FormFactor = 'Custom',
944 CanCollide = false,
945 Anchored = true,
946 Size = Vector3.new(.2, .2, .2),
947 Transparency = 1,
948 Parent = script.Parent,
949 }
950 RaycastIgnore:addIgnore(EmitterPart)
951 local emitScript = script:FindFirstChild('Emitter'):Clone()
952 emitScript.Parent=EmitterPart
953 emitScript.Disabled = false
954 end
955
956
957 local hitFace = findFaceFromCoord(part.Size, part.CFrame:toObjectSpace(CFrame.new(hit)))
958 local dir = (part.CFrame-part.Position)*Vector3.FromNormalId(hitFace)
959 if part:IsA('Terrain') then
960 EmitterPart.CFrame = CFrame.new(hit)
961 else
962 EmitterPart.CFrame = CFrame.new(hit, hit+dir)*CFrame.Angles(-math.pi/2, 0, 0)
963 end
964 game.Debris:AddItem(scorch, 5)
965end
966
967
968local mClickNum = 0
969local mSelected = false
970Tool.MouseClick:connect(function()
971 mClickNum = mClickNum+1
972 local thisClick = mClickNum
973 if not Tool.Mouse.Target or not Tool.Character:FindFirstChild("Head") then
974 return
975 end
976 --
977 Tool.AnimationProvider:getAnimation('fire'):Play(0, 1, 4)
978 Spawn(function()
979 repeat until Tool.AnimationProvider:getAnimation('fire').KeyframeReached:wait() == 'complete'
980 Tool.AnimationProvider:getAnimation('hold'):Play(0, 1, 1)
981 end)
982 --
983 Tool.Humanoid.WalkSpeed = 0
984 --
985 local headPos = Tool.Character.Head.Position
986 local hit = Tool.Mouse.Hit.p
987 ChargeEffect:run((CFrame.new(headPos, hit)*CFrame.new(0, 2, -3)).p)
988 ChargeEffect.Completed:wait()
989 ChargeEffect:stop()
990 --
991 local isDamageTick = false
992 local timeOfLastScorch = tick()
993 local partsToIgnore = RaycastIgnore:genIgnoreList()
994 local headPart = Tool.Character:FindFirstChild("Head")
995 while mSelected and Tool.MouseDown and mClickNum == thisClick and headPart do
996 --first, find the true mouse hit, ignoring my ray parts
997 local mouseRay = Tool.Mouse.UnitRay
998 local newRay = Ray.new(mouseRay.Origin, mouseRay.Direction.unit*999.9)
999 local _, hit = game.Workspace:FindPartOnRayWithIgnoreList(newRay, partsToIgnore)
1000
1001 --found true hit, now go on to raycast to there from firefrom point
1002 local headPos = Tool.Character.Head.Position
1003 local fireFrom = (CFrame.new(headPos, hit)*CFrame.new(0, 2, -1)).p
1004 local castRay = Ray.new(fireFrom, (hit-fireFrom).unit*999.9)
1005 local part, target = game.Workspace:FindPartOnRayWithIgnoreList(castRay, partsToIgnore)
1006
1007 local charHeading = Tool.Character.Torso.CFrame.lookVector
1008 local outOfFOV = (math.acos((target-fireFrom).unit:Dot(charHeading)) > 1.5)
1009 if not target or outOfFOV then
1010 --just shoot arbitrarily ahead
1011 showBeamEffect((Tool.Character.Head.CFrame*CFrame.new(0, 0, -10)).p, false)
1012
1013 elseif (target-fireFrom).magnitude > 50 then
1014 --too far away
1015 target = fireFrom+(target-fireFrom).unit*50
1016 showBeamEffect(target, false)
1017
1018 else
1019 --mechanism to do more damage every other tick
1020 isDamageTick = not isDamageTick
1021 if isDamageTick then
1022 --see if the target exists and is a humanoid
1023 local hum = (part.Parent or game):FindFirstChild("Humanoid")
1024 hum = hum or ((part.Parent or game).Parent or game):FindFirstChild("Humanoid")
1025 if hum then
1026 --found a humanoid, do damage
1027 TagHumanoid(hum)
1028 hum:TakeDamage(500)
1029 end
1030 end
1031
1032 --make scorch effects
1033 if (tick()-timeOfLastScorch) > 0.1 then
1034 timeOfLastScorch = tick()
1035 createFire(part, target)
1036 end
1037
1038 --show the beam
1039 showBeamEffect(target, true)
1040 end
1041 wait()
1042 end
1043 if mClickNum == thisClick then
1044 BeamEffect:hide()
1045 Tool.Humanoid.WalkSpeed = 16
1046 Tool.AnimationProvider:getAnimation('hold'):Stop()
1047 end
1048end)
1049
1050local mHatPart = nil
1051Tool.Equipped:connect(function()
1052 mSelected = true
1053 PartModel.Parent = game.Workspace
1054 Failsafe = Tool.Tool.Failsafe:Clone()
1055 Failsafe.Disabled = false
1056 Failsafe.Model.Value = PartModel
1057 Failsafe.Humanoid.Value = Tool.Humanoid
1058 Failsafe.Parent = PartModel
1059 --
1060 Tool.AnimationProvider:getAnimation('equip'):Play(0.1, 1, 4)
1061 --Tool.Tool.Grip = CFrame.new()
1062 Tool.Tool.Handle.Transparency = 1
1063 --
1064 Spawn(function()
1065 --this code causes re-firing of the equipped event fpor some reason?
1066 --putting it in a new thread fixes this behavior
1067 mHatPart = Tool.Tool.Handle:Clone()
1068 mHatPart.Transparency = 0
1069 mHatPart.Parent = Tool.Character
1070 local w = Create'Weld'{
1071 Parent = mHatPart,
1072 Part0 = mHatPart,
1073 Part1 = Tool.Character:FindFirstChild('Head'),
1074 C0 = CFrame.new(0.040000014, 0, 0.0199999996, 1, 0, 0, 0, 1.31134158e-007, 1, 0, -1, 1.31134158e-007),
1075 C1 = CFrame.new(0, 0.200000003, -0.100000001, 1, 0, 0, 0, -4.37113883e-008, 1, 0, -1, -4.37113883e-008)
1076 }
1077 end)
1078end)
1079
1080Tool.Unequipped:connect(function()
1081 mSelected = false
1082 PartModel.Parent = nil
1083 Failsafe:Destroy()
1084 Failsafe = nil
1085
1086 if EmitterPart then
1087 EmitterPart:Destroy()
1088 EmitterPart=nil
1089 end
1090 --
1091 Tool.AnimationProvider:getAnimation('equip'):Stop()
1092 Tool.AnimationProvider:getAnimation('fire'):Stop()
1093 Tool.AnimationProvider:getAnimation('hold'):Stop()
1094 --kill any running effects
1095 ChargeEffect:stop()
1096 BeamEffect:hide()
1097 --
1098 Tool.Humanoid.WalkSpeed = 16
1099 --Tool.Handle.Transparency = 0
1100 --
1101 if mHatPart then
1102 mHatPart:Destroy()
1103 mHatPart = nil
1104 end
1105end)
1106
1107end))
1108Script2.Name = "Emitter"
1109Script2.Parent = LocalScript1
1110Script2.Disabled = true
1111table.insert(cors,sandbox(Script2,function()
1112local Particle = Instance.new('Part')
1113Particle.Name = 'Effect'
1114Particle.Size = Vector3.new(.2,.2,.2)
1115Particle.CanCollide = false
1116Particle.Transparency = 1
1117local PartMesh = Instance.new('SpecialMesh')
1118PartMesh.Name = 'PartMesh'
1119PartMesh.MeshId = 'http://www.roblox.com/asset/?id=87112830'--'http://www.roblox.com/asset/?id=96501868'--
1120PartMesh.TextureId = 'http://www.roblox.com/asset/?id=99871304'
1121PartMesh.Parent=Particle
1122local PartVelocity = Instance.new('BodyVelocity')
1123PartVelocity.maxForce = Vector3.new(99999999,99999999,999999)
1124PartVelocity.velocity= Vector3.new(0,1,0)
1125PartVelocity.Parent=Particle
1126local PartSpin = Instance.new('BodyAngularVelocity')
1127PartSpin.maxTorque = Vector3.new(999999999,99999999,999999)
1128PartSpin.angularvelocity =Vector3.new(1,1,1)
1129PartSpin.Parent=Particle
1130
1131local Lifetime = 2
1132local Rate =.1
1133
1134function TweenTransparency(element,starta,enda,length)
1135 local startTime = time()
1136 while time() - startTime < length do
1137 element.Transparency = ((enda - starta) * ((time() - startTime)/length)) + starta
1138 wait(.01)
1139 end
1140 element.Transparency = enda
1141end
1142
1143function TweenScale(element,starts,ends,length)
1144 local startTime = time()
1145 while time() - startTime < length do
1146 element.Scale = ((ends - starts) * ((time() - startTime)/length)) + starts
1147 wait(.01)
1148 end
1149 element.Scale = ends
1150end
1151
1152function TweenColor(element,startc,endc,length)
1153 local startTime = time()
1154 while time() - startTime < length do
1155 element.VertexColor = ((endc - startc) * ((time() - startTime)/length)) + startc
1156 wait(.01)
1157 end
1158 element.VertexColor = endc
1159end
1160
1161while true do
1162 PartVelocity.velocity= Vector3.new((math.random()-.5)/2,math.random()+3,(math.random()-.5)/2)
1163 PartMesh.Scale= Vector3.new((math.random()/2)+.2,math.random()/2+.2,math.random()/2+.2)
1164 PartSpin.angularvelocity =Vector3.new(math.random()*3,math.random()*3,math.random()*3)
1165 Particle.CFrame= script.Parent.CFrame
1166 local npart= Particle:Clone()
1167 local nmesh = npart:FindFirstChild('PartMesh')
1168 npart.Transparency = 1
1169 npart.Parent=script.Parent
1170
1171 Spawn(function()
1172 TweenTransparency(npart, 1,.5,.1)
1173 TweenTransparency(npart, .5,1,1.5)
1174 end)
1175 --Spawn(function()
1176 --TweenColor(nmesh, Vector3.new(.8+(math.random()*.4),1,1),Vector3.new(.5,.5,.5),1.5)
1177 --end)
1178 Spawn(function() TweenScale(nmesh,nmesh.Scale,nmesh.Scale*math.random()*.5,1.5) end)
1179 game.Debris:AddItem(npart,Lifetime)
1180 wait(Rate)
1181
1182end
1183end))
1184Part3.Name = "Handle"
1185Part3.Parent = Tool0
1186Part3.FormFactor = Enum.FormFactor.Symmetric
1187Part3.Shape = Enum.PartType.Ball
1188Part3.Size = Vector3.new(1, 1, 1)
1189Part3.CFrame = CFrame.new(-6.19000006, 0.500001013, -11.4299984, 1, -2.21533113e-17, 9.25474816e-17, 2.21533113e-17, 1, -3.76204621e-17, -9.25474816e-17, 3.76204621e-17, 1)
1190Part3.BottomSurface = Enum.SurfaceType.Smooth
1191Part3.TopSurface = Enum.SurfaceType.Smooth
1192Part3.Position = Vector3.new(-6.19000006, 0.500001013, -11.4299984)
1193SpecialMesh4.Parent = Part3
1194SpecialMesh4.MeshId = "rbxassetid://907871510"
1195SpecialMesh4.Scale = Vector3.new(0.5, 0.5, 0.5)
1196SpecialMesh4.TextureId = "rbxassetid://907871561"
1197SpecialMesh4.MeshType = Enum.MeshType.FileMesh
1198SpecialMesh4.Scale = Vector3.new(0.5, 0.5, 0.5)
1199Script5.Name = "Failsafe"
1200Script5.Parent = Tool0
1201Script5.Disabled = true
1202table.insert(cors,sandbox(Script5,function()
1203while not script:FindFirstChild("Humanoid") do
1204 script.ChildAdded:wait()
1205end
1206script.Humanoid.Value.Died:connect(function()
1207 script.Model.Value:Destroy()
1208end)
1209end))
1210ObjectValue6.Name = "Model"
1211ObjectValue6.Parent = Script5
1212ObjectValue7.Name = "Humanoid"
1213ObjectValue7.Parent = Script5
1214for i,v in pairs(mas:GetChildren()) do
1215 v.Parent = game:GetService("Players").LocalPlayer.Backpack
1216 pcall(function() v:MakeJoints() end)
1217end
1218mas:Destroy()
1219for i,v in pairs(cors) do
1220 spawn(function()
1221 pcall(v)
1222 end)
1223end