Last active
September 27, 2017 13:24
-
-
Save Aerodos12/58b5272e1723fb1c34777f21071ff017 to your computer and use it in GitHub Desktop.
PF Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local vector={} | |
local cframe={} | |
local network={} | |
local trash={} | |
local utility={} | |
local event={} | |
local sequencer={} | |
local physics={} | |
local particle={} | |
local effects={} | |
local tween={} | |
local animation={} | |
local input={} | |
local char={} | |
local camera={} | |
local chat={} | |
local hud={} | |
local notify={} | |
local leaderboard={} | |
local replication={} | |
local menu={} | |
local roundsystem={} | |
local run={} | |
local gamelogic={} | |
--LOLTASTIC Good for figuring out bugs. | |
local loltimescale=1 | |
local loltick=tick | |
local function tick() | |
return loltimescale*loltick() | |
end | |
game.StarterGui.ResetPlayerGuiOnSpawn=false | |
game.StarterGui:SetCoreGuiEnabled("All",false) | |
local realprint=print | |
--local print=function() end | |
--vector module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading vector module") | |
do | |
local pi =math.pi | |
local cos =math.cos | |
local sin =math.sin | |
local acos =math.acos | |
local asin =math.asin | |
local atan2 =math.atan2 | |
local random =math.random | |
local v3 =Vector3.new | |
local nv =Vector3.new() | |
vector.identity=nv | |
vector.new=v3 | |
vector.lerp=nv.lerp | |
function vector.random(a,b) | |
local p =acos(1-2*random())/3 | |
local z =3^0.5*sin(p)-cos(p) | |
local r =((1-z*z)*random())^0.5 | |
local t =6.28318*random() | |
local x =r*cos(t) | |
local y =r*sin(t) | |
if b then | |
local m =(a+(b-a)*random())/(x*x+y*y+z*z)^0.5 | |
return v3(m*x,m*y,m*z) | |
elseif a then | |
return v3(a*x,a*y,a*z) | |
else | |
return v3(x,y,z) | |
end | |
end | |
function vector.anglesyx(x,y) | |
local cx=cos(x) | |
return v3(-cx*sin(y),sin(x),-cx*cos(y)) | |
end | |
function vector.toanglesyx(v) | |
local x,y,z=v.x,v.y,v.z | |
return asin(y/(x*x+y*y+z*z)^0.5),atan2(-x,-z) | |
end | |
function vector.slerp(v0,v1,t) | |
local x0,y0,z0 =v0.x,v0.y,v0.z | |
local x1,y1,z1 =v1.x,v1.y,v1.z | |
local m0 =(x0*x0+y0*y0+z0*z0)^0.5 | |
local m1 =(x1*x1+y1*y1+z1*z1)^0.5 | |
local co =(x0*x1+y0*y1+z0*z1)/(m0*m1) | |
if co<-0.99999 then | |
local px,py,pz =0,0,0 | |
local x2,y2,z2 =x0*x0,y0*y0,z0*z0 | |
if x2<y2 then | |
if x2<z2 then | |
px =1 | |
else | |
pz =1 | |
end | |
else | |
if y2<z2 then | |
py =1 | |
else | |
pz =1 | |
end | |
end | |
local th =acos((x0*px+y0*py+z0*pz)/m0) | |
local r =pi/th*t | |
local s =((1-t)*m0+t*m1)/sin(th) | |
local s0 =s/m0*sin((1-r)*th) | |
local s1 =s/m1*sin(r*th) | |
return v3( | |
s0*x0+s1*px, | |
s0*y0+s1*py, | |
s0*z0+s1*pz | |
) | |
elseif co<0.99999 then | |
local th =acos(co) | |
local s =((1-t)*m0+t*m1)/(1-co*co)^0.5 | |
local s0 =s/m0*sin((1-t)*th) | |
local s1 =s/m1*sin(t*th) | |
return v3( | |
s0*x0+s1*x1, | |
s0*y0+s1*y1, | |
s0*z0+s1*z1 | |
) | |
elseif 1e-5<m0 or 1e-5<m1 then | |
if m0<m1 then | |
return ((1-t)*m0/m1+t)*v1 | |
else | |
return ((1-t)+t*m1/m0)*v0 | |
end | |
else | |
return nv | |
end | |
end | |
end | |
--cframe module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading cframe module") | |
do | |
local pi =math.pi | |
local halfpi =pi/2 | |
local cos =math.cos | |
local sin =math.sin | |
local acos =math.acos | |
local v3 =Vector3.new | |
local nv =v3() | |
local cf =CFrame.new | |
local nc =cf() | |
local components =nc.components | |
local tos =nc.toObjectSpace | |
local vtos =nc.vectorToObjectSpace | |
local ptos =nc.pointToObjectSpace | |
local backcf =cf(0,0,0,-1,0,0,0,1,0,0,0,-1) | |
cframe.identity =nc | |
cframe.new =cf | |
cframe.vtws =nc.vectorToWorldSpace | |
cframe.tos =nc.toObjectSpace | |
cframe.ptos =nc.pointToObjectSpace | |
cframe.vtos =nc.vectorToObjectSpace | |
function cframe.fromaxisangle(x,y,z) | |
if not y then | |
x,y,z=x.x,x.y,x.z | |
end | |
local m=(x*x+y*y+z*z)^0.5 | |
if m>1e-5 then | |
local si=sin(m/2)/m | |
return cf(0,0,0,si*x,si*y,si*z,cos(m/2)) | |
else | |
return nc | |
end | |
end | |
function cframe.toaxisangle(c) | |
local _,_,_, | |
xx,yx,zx, | |
xy,yy,zy, | |
xz,yz,zz=components(c) | |
local co=(xx+yy+zz-1)/2 | |
if co<-0.99999 then | |
local x=xx+yx+zx+1 | |
local y=xy+yy+zy+1 | |
local z=xz+yz+zz+1 | |
local m=pi*(x*x+y*y+z*z)^-0.5 | |
return v3(m*x,m*y,m*z) | |
elseif co<0.99999 then | |
local x=yz-zy | |
local y=zx-xz | |
local z=xy-yx | |
local m=acos(co)*(x*x+y*y+z*z)^-0.5 | |
return v3(m*x,m*y,m*z) | |
else | |
return nv | |
end | |
end | |
function cframe.direct(c,look,newdir,t) | |
local lx,ly,lz =look.x,look.y,look.z | |
local rv =vtos(c,newdir) | |
local rx,ry,rz =rv.x,rv.y,rv.z | |
local rl =((rx*rx+ry*ry+rz*rz)*(lx*lx+ly*ly+lz*lz))^0.5 | |
local d =(lx*rx+ly*ry+lz*rz)/rl | |
if d<-0.99999 then | |
return c*backcf | |
elseif d<0.99999 then | |
if t then | |
local th =t*acos(d)/2 | |
local qw =cos(th) | |
local m =rl*((1-d*d)/(1-qw*qw))^0.5 | |
return c*cf( | |
0,0,0, | |
(ly*rz-lz*ry)/m, | |
(lz*rx-lx*rz)/m, | |
(lx*ry-ly*rx)/m, | |
qw | |
) | |
else | |
local qw =((d+1)/2)^0.5 | |
local m =2*qw*rl | |
return c*cf( | |
0,0,0, | |
(ly*rz-lz*ry)/m, | |
(lz*rx-lx*rz)/m, | |
(lx*ry-ly*rx)/m, | |
qw | |
) | |
end | |
else | |
return c | |
end | |
end | |
function cframe.toquaternion(c) | |
local x,y,z, | |
xx,yx,zx, | |
xy,yy,zy, | |
xz,yz,zz =components(c) | |
local tr =xx+yy+zz | |
if tr>2.99999 then | |
return x,y,z,0,0,0,1 | |
elseif tr>-0.99999 then | |
local m =2*(tr+1)^0.5 | |
return x,y,z, | |
(yz-zy)/m, | |
(zx-xz)/m, | |
(xy-yx)/m, | |
m/4 | |
else | |
local qx =xx+yx+zx+1 | |
local qy =xy+yy+zy+1 | |
local qz =xz+yz+zz+1 | |
local m =(qx*qx+qy*qy+qz*qz)^0.5 | |
return x,y,z,qx/m,qy/m,qz/m,0 | |
end | |
end | |
function cframe.power(c,t) | |
local x,y,z, | |
xx,yx,zx, | |
xy,yy,zy, | |
xz,yz,zz =components(c) | |
local tr =xx+yy+zz | |
if tr>2.99999 then | |
return cf(t*x,t*y,t*z) | |
elseif tr>-0.99999 then | |
local m =2*(tr+1)^0.5 | |
local qw =m/4 | |
local th =acos(qw) | |
local s =(1-qw*qw)^0.5 | |
local c =sin(th*t)/s | |
return cf( | |
t*x,t*y,t*z, | |
c*(yz-zy)/m, | |
c*(zx-xz)/m, | |
c*(xy-yx)/m, | |
c*qw+sin(th*(1-t))/s | |
) | |
else | |
local qx =xx+yx+zx+1 | |
local qy =xy+yy+zy+1 | |
local qz =xz+yz+zz+1 | |
local c =sin(halfpi*t)/(qx*qx+qy*qy+qz*qz)^0.5 | |
return cf( | |
t*x,t*y,t*z, | |
c*qx, | |
c*qy, | |
c*qz, | |
sin(halfpi*(1-t)) | |
) | |
end | |
end | |
local power=cframe.power | |
function cframe.interpolate(c0,c1,t) | |
return c0*power(tos(c0,c1),t) | |
end | |
local toquaternion=cframe.toquaternion | |
function cframe.interpolator(c0,c1) | |
if c1 then | |
local x0,y0,z0,qx0,qy0,qz0,qw0=toquaternion(c0) | |
local x1,y1,z1,qx1,qy1,qz1,qw1=toquaternion(c1) | |
local x,y,z=x1-x0,y1-y0,z1-z0 | |
local c=qx0*qx1+qy0*qy1+qz0*qz1+qw0*qw1 | |
if c<0 then | |
qx0,qy0,qz0,qw0=-qx0,-qy0,-qz0,-qw0 | |
end | |
if c<0.9999 then | |
local s=(1-c*c)^0.5 | |
local th=acos(c) | |
return function(t) | |
local s0=sin(th*(1-t))/s | |
local s1=sin(th*t)/s | |
return cf( | |
x0+t*x, | |
y0+t*y, | |
z0+t*z, | |
s0*qx0+s1*qx1, | |
s0*qy0+s1*qy1, | |
s0*qz0+s1*qz1, | |
s0*qw0+s1*qw1 | |
) | |
end | |
else | |
return function(t) | |
return cf(x0+t*x,y0+t*y,z0+t*z,qx1,qy1,qz1,qw1) | |
end | |
end | |
else | |
local x,y,z,qx,qy,qz,qw=cframe.toquaternion(c0) | |
if qw<0.9999 then | |
local s=(1-qw*qw)^0.5 | |
local th=acos(qw) | |
return function(t) | |
local s1=sin(th*t)/s | |
return cf( | |
t*x, | |
t*y, | |
t*z, | |
s1*qx, | |
s1*qy, | |
s1*qz, | |
sin(th*(1-t))/s+s1*qw | |
) | |
end | |
else | |
return function(t) | |
return cf(t*x,t*y,t*z,qx,qy,qz,qw) | |
end | |
end | |
end | |
end | |
function cframe.jointleg(r0,r1,c,p,a) | |
local t=ptos(c,p) | |
local tx,ty,tz=t.x,t.y,t.z | |
--Calculate inverse kinemetics equation | |
local d=(tx*tx+ty*ty+tz*tz)^0.5 | |
local nx,ny,nz=tx/d,ty/d,tz/d | |
d=r0+r1<d and r0+r1 or d | |
local l=(r1*r1-r0*r0-d*d)/(2*r0*d) | |
local h=-(1-l*l)^0.5 | |
--Generate the natural quaternion for the shoulder. | |
local m=(2*(1+h*ny+l*nz))^0.5 | |
local qw,qx,qy,qz=m/2,(h*nz-l*ny)/m,l*nx/m,-h*nx/m | |
--If a, then rotate the natural quaternion by a. | |
if a then | |
local co,si=cos(a/2),sin(a/2) | |
qw,qx,qy,qz=co*qw-si*(nx*qx+ny*qy+nz*qz), | |
co*qx+si*(nx*qw-nz*qy+ny*qz), | |
co*qy+si*(ny*qw+nz*qx-nx*qz), | |
co*qz+si*(nz*qw-ny*qx+nx*qy) | |
end | |
--Generate the quaternion for the lower arm and return. | |
local g=(d*l+r0)/(d*d+2*d*l*r0+r0*r0)^0.5 | |
local co=((1-g)/2)^0.5 | |
local si=-((1+g)/2)^0.5 | |
return c*cf(-r0*2*(qx*qz+qy*qw), | |
r0*2*(qx*qw-qy*qz), | |
r0*(2*(qx*qx+qy*qy)-1), | |
co*qx+si*qw, | |
co*qy+si*qz, | |
co*qz-si*qy, | |
co*qw-si*qx), | |
c*cf(0,0,0,qx,qy,qz,qw) | |
end | |
function cframe.jointarm(r0,r1,c,p,a) | |
local t=ptos(c,p) | |
local tx,ty,tz=t.x,t.y,t.z | |
--Calculate inverse kinemetics equation | |
local d=(tx*tx+ty*ty+tz*tz)^0.5 | |
local nx,ny,nz=tx/d,ty/d,tz/d | |
d=r0+r1<d and r0+r1 or d | |
local l=(r1*r1-r0*r0-d*d)/(2*r0*d) | |
local h=(1-l*l)^0.5 | |
--Generate the natural quaternion for the shoulder. | |
local m=(2*(1+h*ny+l*nz))^0.5 | |
local qw,qx,qy,qz=m/2,(h*nz-l*ny)/m,l*nx/m,-h*nx/m | |
--If a, then rotate the natural quaternion by a. | |
if a then | |
local co,si=cos(a/2),sin(a/2) | |
qw,qx,qy,qz=co*qw-si*(nx*qx+ny*qy+nz*qz), | |
co*qx+si*(nx*qw-nz*qy+ny*qz), | |
co*qy+si*(ny*qw+nz*qx-nx*qz), | |
co*qz+si*(nz*qw-ny*qx+nx*qy) | |
end | |
--Generate the quaternion for the lower arm and return. | |
local g=(d*l+r0)/(d*d+2*d*l*r0+r0*r0)^0.5 | |
local co=((1-g)/2)^0.5 | |
local si=((1+g)/2)^0.5 | |
return c*cf(-r0*2*(qx*qz+qy*qw), | |
r0*2*(qx*qw-qy*qz), | |
r0*(2*(qx*qx+qy*qy)-1), | |
co*qx+si*qw, | |
co*qy+si*qz, | |
co*qz-si*qy, | |
co*qw-si*qx), | |
c*cf(0,0,0,qx,qy,qz,qw) | |
end | |
end | |
--network module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading network module") | |
do | |
local tick =tick | |
local player =game.Players.LocalPlayer | |
local remoteevent =game.ReplicatedStorage:WaitForChild("RemoteEvent") | |
local bounceevent =game.ReplicatedStorage:WaitForChild("BounceEvent") | |
local remotefunc =game.ReplicatedStorage:WaitForChild("RemoteFunction") | |
local fireserver =remoteevent.FireServer | |
local invokeserver =remotefunc.InvokeServer | |
local funcs ={} | |
local queue ={} | |
function network:add(name,func) | |
funcs[name]=func | |
if queue[name] then | |
for i=1,#queue[name] do | |
func(unpack(queue[name][i])) | |
end | |
end | |
end | |
function network:send(...) | |
fireserver(remoteevent,...) | |
end | |
function network:bounce(...) | |
fireserver(bounceevent,...) | |
end | |
function network:fetch(...) | |
return invokeserver(remotefunc,...) | |
end | |
local function call(name,...) | |
if funcs[name] then | |
return funcs[name](...) | |
else | |
if not queue[name] then | |
queue[name]={} | |
end | |
queue[name][#queue[name]+1]={...} | |
end | |
end | |
bounceevent.OnClientEvent:connect(call) | |
remoteevent.OnClientEvent:connect(call) | |
function remotefunc.OnClientInvoke(name,...) | |
if funcs[name] then | |
return funcs[name](...) | |
end | |
end | |
network:add("ping",function(servertick) | |
network:send("ping",servertick,player,tick()) | |
end) | |
end | |
--trash module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading utility module") | |
do | |
local destroy=game.Destroy | |
local shit={} | |
function trash.remove(x) | |
if x then | |
shit[#shit+1]=x | |
x.Parent=nil | |
end | |
end | |
function trash.empty() | |
print("taking out "..#shit.." trash") | |
for i=1,#shit do | |
destroy(shit[i]) | |
end | |
shit={} | |
end | |
network:add("emptytrash",trash.empty) | |
end | |
--utility module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading utility module") | |
do | |
local getchildren =game.GetChildren | |
local rtype =game.IsA | |
local joints =game.JointsService | |
local tos =CFrame.new().toObjectSpace | |
local tick =tick | |
local new =Instance.new | |
local waitforchild =game.WaitForChild | |
function utility.arraytohash(table,hashfunc) | |
local newtable={} | |
for i=1,#table do | |
newtable[hashfunc(table[i])]=table[i] | |
end | |
return newtable | |
end | |
function utility.waitfor(object,timeout,...) | |
local indices={...} | |
local index=object | |
local quit=tick()+(timeout or 10) | |
for i=1,#indices do | |
if index.WaitForChild then | |
index=waitforchild(index,indices[i]) | |
else | |
local newindex repeat | |
run.wait() | |
newindex=index[indices[i]] | |
until newindex or tick()>quit | |
index=newindex | |
end | |
if tick()>quit then return end | |
end | |
return index | |
end | |
function utility.getdescendants(object,type) | |
type=type or "Instance" | |
local descendants=getchildren(object) | |
local i=0 | |
while i<#descendants do | |
i=i+1 | |
local children=getchildren(descendants[i]) | |
for j=1,#children do | |
descendants[#descendants+1]=children[j] | |
end | |
end | |
local newdescendants={} | |
for i=1,#descendants do | |
if rtype(descendants[i],type) then | |
newdescendants[#newdescendants+1]=descendants[i] | |
end | |
end | |
return newdescendants | |
end | |
function utility.weld(part0,part1,c0) | |
c0=c0 or tos(part0.CFrame,part1.CFrame) | |
local newweld=new("Motor6D",part0) | |
newweld.Part0=part0 | |
newweld.Part1=part1 | |
newweld.C0=c0 | |
part0.Anchored=false | |
part1.Anchored=false | |
return newweld | |
end | |
function utility.weldmodel(model,basepart) | |
local weldcframes={} | |
local children=model:GetChildren()--utility.getdescendants(model,"BasePart") | |
basepart=basepart-- or children[1] | |
local welds={} | |
welds[0]=basepart | |
local basecframe=basepart and basepart.CFrame | |
for i=1,#children do | |
if children[i]:IsA("BasePart") then | |
weldcframes[i]=tos(basecframe,children[i].CFrame) | |
end | |
end | |
for i=1,#children do | |
if children[i]:IsA("BasePart") then | |
local newweld=new("Motor6D",basepart) | |
newweld.Part0=basepart | |
newweld.Part1=children[i] | |
newweld.C0=weldcframes[i] | |
welds[i]=newweld | |
children[i].Anchored=false | |
end | |
end | |
basepart.Anchored=false | |
return welds | |
end | |
function utility.removevalue(array,removals) | |
local removelist={} | |
for i=1,#removals do | |
removelist[removals[i]]=true | |
end | |
local j=1 | |
for i=1,#array do | |
local v=array[i] | |
array[i]=nil | |
if not removelist[v] then | |
array[j]=v | |
j=j+1 | |
end | |
end | |
return array | |
end | |
end | |
--event module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading event module") | |
do | |
function event.new(eventtable) | |
local self=eventtable or {} | |
local removelist ={} | |
local functions ={} | |
local pendingdeletion =false | |
function self:connect(func) | |
functions[#functions+1]=func | |
return function() | |
removelist[func]=true | |
pendingdeletion=true | |
end | |
end | |
return function(...) | |
if pendingdeletion then | |
pendingdeletion=false | |
local j=1 | |
for i=1,#functions do | |
local f=functions[i] | |
functions[i]=nil | |
if removelist[f] then | |
removelist[f]=nil | |
else | |
f(...) | |
functions[j]=f | |
j=j+1 | |
end | |
end | |
else | |
for i=1,#functions do | |
functions[i](...) | |
end | |
end | |
end, | |
self | |
end | |
end | |
--sequencer module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading sequencer module") | |
do | |
local tick =tick | |
local type =type | |
local remove =table.remove | |
function sequencer.new() | |
local self={} | |
local t0 | |
local sequence ={} | |
local n =0 | |
local deletions =0 | |
function self:add(func,dur) | |
--print("added",func) | |
n=n+1 | |
if n==1 then | |
t0=tick() | |
end | |
sequence[n]={ | |
func=func; | |
dur=dur; | |
} | |
end | |
function self:delay(dur) | |
--print("delaying",dur) | |
n=n+1 | |
if n==1 then | |
t0=tick() | |
end | |
sequence[n]={ | |
dur=dur; | |
} | |
end | |
function self:clear() | |
--print("cleared") | |
for i=1,n do | |
sequence[i]=nil | |
end | |
deletions=0 | |
n=0 | |
end | |
function self:step() | |
--print(unpack(sequence)) | |
local time=tick() | |
if deletions~=0 then | |
for i=deletions+1,n do | |
sequence[i-deletions]=sequence[i] | |
end | |
for i=n-deletions+1,n do | |
sequence[i]=nil | |
end | |
n=n-deletions | |
deletions=0 | |
end | |
for i=1,n do | |
local t=time-t0 | |
local func=sequence[i] | |
local dur=func.dur | |
local stop=false | |
if func.func then | |
stop=func.func(t) | |
end | |
if stop or stop==nil or dur and dur<t then | |
t0=time | |
deletions=deletions+1 | |
else | |
break | |
end | |
end | |
end | |
return self | |
end | |
end | |
--physics module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading physics module") | |
do | |
local sort =table.sort | |
local atan2 =math.atan2 | |
local inf =math.huge | |
local cos =math.cos | |
local sin =math.sin | |
local setmetatable =setmetatable | |
local tick =tick | |
local dot =Vector3.new().Dot | |
physics.spring ={} | |
function physics.spring.new(initial) | |
local t0 =tick() --tick0 | |
local p0 =initial or 0 --position0 | |
local v0 =initial and 0*initial or 0 --velocity0 | |
local t =initial or 0 --target | |
local d =1 --damper [0,1] | |
local s =1 --speed [0,infinity] | |
local function positionvelocity(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)^0.5 | |
local c1 =(v0/s+d*c0)/c | |
local co =cos(c*s*x) | |
local si =sin(c*s*x) | |
local e =2.718281828459045^(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.718281828459045^(s*x) | |
return t+(c0+c1*s*x)/e, | |
s*(c1-c0-c1*s*x)/e | |
end | |
end | |
return setmetatable({ | |
accelerate=function(_,acceleration) | |
local time=tick() | |
local p,v=positionvelocity(time) | |
p0=p | |
v0=v+acceleration | |
t0=time | |
end; | |
},{ | |
__index=function(_,index) | |
if index=="value" or index=="position" or index=="p" then | |
local p,v=positionvelocity(tick()) | |
return p | |
elseif index=="velocity" or index=="v" then | |
local p,v=positionvelocity(tick()) | |
return v | |
elseif index=="acceleration" or index=="a" then | |
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.718281828459045^(d*s*x) | |
else | |
local c1 =v0/s+c0 | |
return s*s*(c0-2*c1+c1*s*x) | |
/2.718281828459045^(s*x) | |
end | |
elseif index=="target" or index=="t" then | |
return t | |
elseif index=="damper" or index=="d" then | |
return d | |
elseif index=="speed" or index=="s" then | |
return s | |
else | |
error(index.." is not a valid member of spring",0) | |
end | |
end; | |
__newindex=function(_,index,value) | |
local time=tick() | |
if index=="value" or index=="position" or index=="p" then | |
local p,v=positionvelocity(time) | |
p0,v0=value,v | |
elseif index=="velocity" or index=="v" then | |
local p,v=positionvelocity(time) | |
p0,v0=p,value | |
elseif index=="acceleration" or index=="a" then | |
local p,v=positionvelocity(time) | |
p0,v0=p,v+value | |
elseif index=="target" or index=="t" then | |
p0,v0=positionvelocity(time) | |
t=value | |
elseif index=="damper" or index=="d" then | |
p0,v0=positionvelocity(time) | |
d=value<0 and 0 or value<1 and value or 1 | |
elseif index=="speed" or index=="s" then | |
p0,v0=positionvelocity(time) | |
s=value<0 and 0 or value | |
else | |
error(index.." is not a valid member of spring",0) | |
end | |
t0=time | |
end; | |
}) | |
end | |
local function rootreals4(a,b,c,d,e) | |
local x0,x1,x2,x3 | |
local m10=3*a | |
local m0=-b/(4*a) | |
local m4=c*c-3*b*d+12*a*e | |
local m6=(b*b/(4*a)-2/3*c)/a | |
local m9=((b*(4*c-b*b/a))/a-(8*d))/a | |
local m5=c*(2*c*c-9*b*d-72*a*e)+27*a*d*d+27*b*b*e | |
local m11=m5*m5-4*m4*m4*m4 | |
local m7 | |
if m11<0 then--Optimize | |
local th=atan2((-m11)^0.5,m5)/3 | |
local m=((m5*m5-m11)/4)^(1/6) | |
m7=(m4/m+m)/m10*cos(th) | |
else--MAY NEED CASE FOR WHEN 2*c*c*c-9*b*c*d+27*a*d*d+27*b*b*e-72*a*c*e+((2*c*c*c-9*b*c*d+27*a*d*d+27*b*b*e-72*a*c*e)^2-4*(c*c-3*b*d+12*a*e)^3)^(1/2)=0 | |
local m8=(m5+m11^0.5)/2 | |
m8=m8<0 and -(-m8)^(1/3) or m8^(1/3) | |
m7=(m4/m8+m8)/m10 | |
end | |
local m2=2*m6-m7 | |
--print("m2",m2,0) | |
local m12=m6+m7 | |
if m12<0 then | |
local m3i=m9/(4*(-m12)^0.5) | |
local m13=(m3i*m3i+m2*m2)^(1/4)*cos(atan2(m3i,m2)/2)/2 | |
--In order | |
x0=m0-m13 | |
x1=m0-m13 | |
x2=m0+m13 | |
x3=m0+m13 | |
else | |
local m1=m12^0.5 | |
--print("m1",m1,0) | |
local m3=m9/(4*m1) | |
--print("m3",m3,0) | |
local m14=m2-m3 | |
local m15=m2+m3 | |
if m14<0 then | |
x0=m0-m1/2 | |
x1=m0-m1/2 | |
else | |
local m16=m14^0.5 | |
x0=m0-(m1+m16)/2 | |
x1=m0-(m1-m16)/2 | |
end | |
if m15<0 then | |
x2=m0+m1/2 | |
x3=m0+m1/2 | |
else | |
local m17=m15^0.5 | |
x2=m0+(m1-m17)/2 | |
x3=m0+(m1+m17)/2 | |
end | |
--bubble sort lel | |
if x1<x0 then x0,x1=x1,x0 end | |
if x2<x1 then x1,x2=x2,x1 end | |
if x3<x2 then x2,x3=x3,x2 end | |
if x1<x0 then x0,x1=x1,x0 end | |
if x2<x1 then x1,x2=x2,x1 end | |
if x1<x0 then x0,x1=x1,x0 end | |
end | |
return x0,x1,x2,x3 | |
end | |
local function rootreals3(a,b,c,d) | |
local x0,x1,x2 | |
local d0=b*b-3*a*c | |
local d1=2*b*b*b+27*a*a*d-9*a*b*c | |
local d=d1*d1-4*d0*d0*d0 | |
local m0=-1/(3*a) | |
if d<0 then | |
local cr,ci=d1/2,(-d)^0.5/2 | |
local th=atan2(ci,cr)/3 | |
local m=(cr*cr+ci*ci)^(1/6) | |
local cr,ci=m*cos(th),m*sin(th) | |
local m1=(1+d0/(m*m))/2 | |
local m2=(cr*d0+(cr-2*b)*m*m)/(6*a*m*m) | |
local m3=ci*(d0+m*m)/(2*3^0.5*a*m*m) | |
x0=-(b+cr*(1+d0/(m*m)))/(3*a) | |
x1=m2-m3 | |
x2=m2+m3 | |
else | |
local c3=(d1+d^0.5)/2 | |
c=c3<0 and -(-c3)^(1/3) or c3^(1/3) | |
x0=m0*(b+c+d0/c) | |
x1=m0*(b-(c*c+d0)/(2*c)) | |
x2=x1 | |
end | |
if x1<x0 then x0,x1=x1,x0 end | |
if x2<x1 then x1,x2=x2,x1 end | |
if x1<x0 then x0,x1=x1,x0 end | |
return x0,x1,x2 | |
end | |
local function rootreals2(a,b,c) | |
local p=-b/(2*a) | |
local q2=p*p-c/a | |
if 0<q2 then | |
local q=q2^0.5 | |
return p-q,p+q | |
else | |
return p,p | |
end | |
end | |
local solvemoar | |
local function solve(a,b,c,d,e) | |
if a*a<1e-32 then | |
return solve(b,c,d,e) | |
elseif e then | |
if e*e<1e-32 then | |
return solvemoar(a,b,c,d) | |
elseif b*b<1e-12 and d*d<1e-12 then | |
local roots={} | |
local found={} | |
local r0,r1=solve(a,c,e) | |
if r0 then | |
if r0>0 then | |
local x=r0^0.5 | |
roots[#roots+1]=-x | |
roots[#roots+1]=x | |
elseif r0*r0<1e-32 then | |
roots[#roots+1]=0 | |
end | |
end | |
if r1 then | |
if r1>0 then | |
local x=r1^0.5 | |
roots[#roots+1]=-x | |
roots[#roots+1]=x | |
elseif r1*r1<1e-32 then | |
roots[#roots+1]=0 | |
end | |
end | |
sort(roots) | |
return unpack(roots) | |
else | |
local roots={} | |
local found={} | |
local x0,x1,x2,x3=rootreals4(a,b,c,d,e) | |
local d0,d1,d2=rootreals3(4*a,3*b,2*c,d) | |
local m0,m1,m2,m3,m4=-inf,d0,d1,d2,inf | |
local l0,l1,l2,l3,l4=a*inf,(((a*d0+b)*d0+c)*d0+d)*d0+e,(((a*d1+b)*d1+c)*d1+d)*d1+e,(((a*d2+b)*d2+c)*d2+d)*d2+e,a*inf | |
if (l0<=0)==(0<=l1) then | |
roots[#roots+1]=x0 | |
found[x0]=true | |
end | |
if (l1<=0)==(0<=l2) and not found[x1] then | |
roots[#roots+1]=x1 | |
found[x1]=true | |
end | |
if (l2<=0)==(0<=l3) and not found[x2] then | |
roots[#roots+1]=x2 | |
found[x2]=true | |
end | |
if (l3<=0)==(0<=l4) and not found[x3] then | |
roots[#roots+1]=x3 | |
end | |
return unpack(roots) | |
end | |
elseif d then | |
if d*d<1e-32 then | |
return solvemoar(a,b,c) | |
elseif b*b<1e-12 and c*c<1e-12 then | |
local p=d/a | |
return p<0 and (-p)^(1/3) or -p^(1/3) | |
else | |
local roots={} | |
local found={} | |
local x0,x1,x2=rootreals3(a,b,c,d) | |
local d0,d1=rootreals2(3*a,2*b,c) | |
local l0,l1,l2,l3=-a*inf,((a*d0+b)*d0+c)*d0+d,((a*d1+b)*d1+c)*d1+d,a*inf | |
if (l0<=0)==(0<=l1) then | |
roots[#roots+1]=x0 | |
found[x0]=true | |
end | |
if (l1<=0)==(0<=l2) and not found[x1] then | |
roots[#roots+1]=x1 | |
found[x1]=true | |
end | |
if (l2<=0)==(0<=l3) and not found[x2] then | |
roots[#roots+1]=x2 | |
end | |
return unpack(roots) | |
end | |
elseif c then | |
local p=-b/(2*a) | |
local q2=p*p-c/a | |
if 0<q2 then | |
local q=q2^0.5 | |
return p-q,p+q | |
elseif q2==0 then | |
return p | |
end | |
elseif b then | |
if a*a>1e-32 then | |
return -b/a | |
end | |
end | |
end | |
function solvemoar(a,b,c,d,e) | |
local roots={solve(a,b,c,d,e)} | |
local good=true | |
for i=1,#roots do | |
if roots[i]==0 then | |
good=false | |
break | |
end | |
end | |
if good then | |
roots[#roots+1]=0 | |
sort(roots) | |
end | |
return unpack(roots) | |
end | |
function physics.trajectory(pp,pv,pa,tp,tv,ta,s) | |
local rp=tp-pp | |
local rv=tv-pv | |
local ra=ta-pa | |
local t0,t1,t2,t3=solve( | |
dot(ra,ra)/4, | |
dot(ra,rv), | |
dot(ra,rp)+dot(rv,rv)-s*s, | |
2*dot(rp,rv), | |
dot(rp,rp) | |
) | |
if t0 and t0>0 then | |
return ra*t0/2+tv+rp/t0,t0 | |
elseif t1 and t1>0 then | |
return ra*t1/2+tv+rp/t1,t1 | |
elseif t2 and t2>0 then | |
return ra*t2/2+tv+rp/t2,t2 | |
elseif t3 and t3>0 then | |
return ra*t3/2+tv+rp/t3,t3 | |
end | |
end | |
end | |
--particle module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading particle module") | |
do | |
local setmt =setmetatable | |
local remove =table.remove | |
local airdensity =0.001225 | |
local ln =math.log | |
local tan =math.tan | |
local atan2 =math.atan2 | |
local deg =math.pi/180 | |
local tick =tick | |
local playergui =game.Players.LocalPlayer:WaitForChild("PlayerGui") | |
local camera =game.Workspace.CurrentCamera | |
local workspace =game.Workspace | |
local components =CFrame.new().components | |
local v3 =Vector3.new | |
local dot =v3().Dot | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local c3 =Color3.new | |
local ud2 =UDim2.new | |
local new =Instance.new | |
local ffc =game.FindFirstChild | |
local frames ={} | |
local physignore ={workspace.Ignore,camera} | |
local rendignore ={} | |
local particles ={} | |
local removelist ={} | |
particle.physicsignore=physignore | |
particle.renderignore=rendignore | |
local screen=ffc(playergui,"ScreenGui") or new("ScreenGui",playergui) | |
local time=tick() | |
local planey,planex | |
local pixelcoef | |
local cameraposition=camera.CoordinateFrame.p | |
local cpx,cpy,cpz, | |
cxx,cxy,cxz, | |
cyx,cyy,cyz, | |
czx,czy,czz=components(camera.CoordinateFrame) | |
function particle.new(prop) | |
---print(#screen:GetChildren()) --- some particles don't get reused? | |
local self={} | |
local px,py,pz =0,0,0 | |
local vx,vy,vz =0,0,0 | |
local ax,ay,az =0,0,0 | |
local lx,ly,lz | |
local culling =prop.culling==nil or prop.culling | |
local size =prop.size or 1 | |
local bloom =prop.bloom or 0 | |
local brightness =prop.brightness or 1 | |
local maxrange =prop.maxrange or 1000 | |
local cancollide =prop.cancollide==nil or prop.cancollide | |
local resistance =prop.resistance or 1 | |
local elasticity =prop.elasticity or 0.3 | |
local physicsonly =prop.physicsonly or false | |
local minexitvelocity =prop.minexitvelocity or 500 | |
local life =prop.life and tick()+prop.life or false | |
local physignore =prop.physicsignore or physignore | |
local rendignore =prop.renderignore or rendignore | |
local onstep =prop.onstep | |
local ontouch =prop.ontouch | |
local wasrendered =false | |
local wasobstructed | |
--BULLSHIT BULLSHIT BULLSHIT BULLSHIT | |
local distance=0 | |
--BULLSHIT BULLSHIT BULLSHIT BULLSHIT | |
local frame | |
if #frames~=0 then | |
frame=frames[#frames] | |
frames[#frames]=nil | |
else | |
frame=new("Frame",screen) | |
frame.BorderSizePixel=0 | |
end | |
frame.BackgroundColor3=prop.color or c3(1,1,1) | |
self.frame=frame | |
if prop.position then | |
local pos=prop.position | |
px,py,pz=pos.x,pos.y,pos.z | |
end | |
if prop.velocity then | |
local vel=prop.velocity | |
vx,vy,vz=vel.x,vel.y,vel.z | |
end | |
if prop.acceleration then | |
local acc=prop.acceleration | |
ax,ay,az=acc.x,acc.y,acc.z | |
end | |
lx=(px-cpx)*cxx+(py-cpy)*cxy+(py-cpz)*cxz | |
ly=(px-cpx)*cyx+(py-cpy)*cyy+(py-cpz)*cyz | |
lz=-((px-cpx)*czx+(py-cpy)*czy+(py-cpz)*czz) | |
wasobstructed=true--culling and lz*lz+ly*ly+lz*lz<maxrange*maxrange and raycast(workspace,ray(cameraposition,v3(px,py,pz)-cameraposition),rendignore) | |
function self:remove() | |
removelist[self]=true | |
end | |
local part | |
function self.step(dt,time) | |
--Removal check | |
if life and life<time then | |
removelist[self]=true | |
return | |
end | |
--Physics | |
do | |
--Initial position. Don't ask why I used q. | |
local qx,qy,qz=px,py,pz | |
local ix,iy,iz=vx,vy,vz | |
--Calculate the geometric change in velocity due to wind resistance | |
local v=(vx*vx+vy*vy+vz*vz)^0.5 | |
--local gv=1/(resistance*airdensity*v*dt+1) | |
--geometricchange*velocity+dt*acceleration | |
vx,vy,vz=vx+dt*ax,vy+dt*ay,vz+dt*az | |
--nextposition = position+dt*velocity... except integrated so it assumes linear velocity | |
local dx,dy,dz=dt/2*(ix+vx),dt/2*(iy+vy),dt/2*(iz+vz) | |
local ddistance=0 | |
if cancollide then | |
local direction=v3(dx,dy,dz) | |
local hit,pos,norm=raycast(workspace,ray(v3(px,py,pz),direction),physignore) | |
if hit then | |
--This is where I stop giving a shit. | |
local unit=direction.unit | |
local dir=hit.Size.magnitude*unit | |
local _,nextpos=raycast(workspace,ray(pos,dir),physignore) | |
local _,exit=raycast(workspace,ray(nextpos,-dir),physignore) | |
local diff=exit-pos | |
local dist=dot(unit,diff) | |
if 0<dist then | |
if dist<ln(v/minexitvelocity)/resistance then | |
px,py,pz=exit.x,exit.y,exit.z | |
local rx,ry,rz=px-qx,py-qy,pz-qz | |
distance=distance+(pos-v3(qx,qy,qz)).Magnitude | |
ddistance=6000*diff.Magnitude--6000 = density of metal / density of air | |
local gv=2.7182818459045^(-resistance*dist) | |
vx,vy,vz=gv*vx,gv*vy,gv*vz | |
else | |
removelist[self]=true | |
px,py,pz=pos.x,pos.y,pos.z | |
end | |
else | |
removelist[self]=true | |
px,py,pz=nextpos.x,nextpos.y,nextpos.z | |
local gv=2.7182818459045^(-resistance*dot(unit,nextpos-pos)) | |
vx,vy,vz=gv*vx,gv*vy,gv*vz | |
end | |
if ontouch then | |
ontouch(part,hit,pos,norm) | |
end | |
else | |
px,py,pz=px+dx,py+dy,pz+dz | |
end | |
else | |
local rx,ry,rz=px-qx,py-qy,pz-qz | |
distance=distance+(rx*rx+ry*ry+rz*rz)^0.5 | |
px,py,pz=px+dx,py+dy,pz+dz | |
end | |
local rx,ry,rz=px-qx,py-qy,pz-qz | |
distance=distance+(rx*rx+ry*ry+rz*rz)^0.5--+ddistance | |
end | |
if onstep then | |
onstep(part,dt) | |
end | |
if physicsonly then | |
return "physics only" | |
end | |
--Render | |
do | |
--cameracf:inverse()*particlepos | |
local rx,ry,rz=px-cpx,py-cpy,pz-cpz | |
local dx=rx*cxx+ry*cxy+rz*cxz | |
local dy=rx*cyx+ry*cyy+rz*cyz | |
local dz=-(rx*czx+ry*czy+rz*czz) | |
--Check if it's visible at all | |
if brightness==0 or dz<1 and lz<1 then | |
if wasrendered then | |
wasrendered=false | |
frame.Transparency=1 | |
end | |
lx,ly,lz=dx,dy,dz | |
wasobstructed=false--Maybe should be true? idk | |
return "behind or tansparent" | |
end | |
--Raycast to check visibility | |
local obstructed=culling and dx*dx+dy*dy+dz*dz<maxrange*maxrange | |
and raycast(workspace,ray(cameraposition,v3(px,py,pz)-cameraposition),rendignore) | |
if obstructed or wasobstructed then | |
if wasrendered then | |
wasrendered=false | |
frame.Transparency=1 | |
end | |
lx,ly,lz=dx,dy,dz | |
wasobstructed=obstructed | |
return "obstructed" | |
end | |
--Check if intersects the screen plane. | |
local rx,ry,rdepth | |
local sx,sy,sdepth | |
if 1<dz and 1<lz then | |
--Infront of the camera. No intersection | |
rx,ry,rdepth=lx/lz,ly/lz,lz | |
sx,sy,sdepth=dx/dz,dy/dz,dz | |
elseif dz<1 then | |
--Plane intersection stuff | |
local d=(1-dz)/(lz-dz) | |
rx,ry,rdepth=lx/lz,ly/lz,lz | |
sx,sy,sdepth=d*(lx-dx)+dx,d*(ly-dy)+dy,1 | |
else | |
--Plane intersection stuff | |
local d=(1-lz)/(dz-lz) | |
rx,ry,rdepth=d*(dx-lx)+lx,d*(dy-ly)+ly,1 | |
sx,sy,sdepth=dx/dz,dy/dz,dz | |
end | |
--Check if it's within the screen | |
if rx<-planex and sx<-planex or planex<rx and planex<sx | |
or ry<-planey and sy<-planey or planey<ry and planey<sy then | |
if wasrendered then | |
wasrendered=false | |
frame.Transparency=1 | |
end | |
lx,ly,lz=dx,dy,dz | |
wasobstructed=obstructed | |
return "off screen" | |
end | |
--Constrain to within da broarder | |
local slope=(sy-ry)/(sx-rx) | |
local hx,hy,hz=dx-lx,dy-ly,dz-lz | |
if rx<-planex and -planex<sx then | |
rx,ry=-planex,sy-slope*(planex+sx) | |
rdepth=lz-(lz*planex+lx)/(hz*planex+hx)*hz | |
elseif -planex<rx and sx<-planex then | |
sx,sy=-planex,ry-slope*(planex+rx) | |
sdepth=lz-(lz*planex+lx)/(hz*planex+hx)*hz | |
end | |
if rx<planex and planex<sx then | |
sx,sy=planex,ry+slope*(planex-rx) | |
sdepth=lz-(lz*planex-lx)/(hz*planex-hx)*hz | |
elseif planex<rx and sx<planex then | |
rx,ry=planex,sy+slope*(planex-sx) | |
rdepth=lz-(lz*planex-lx)/(hz*planex-hx)*hz | |
end | |
if ry<-planey and -planey<sy then | |
ry,rx=-planey,sx-(planey+sy)/slope | |
rdepth=lz-(lz*planey+ly)/(hz*planey+hy)*hz | |
elseif -planey<ry and sy<-planey then | |
sy,sx=-planey,rx-(planey+ry)/slope | |
sdepth=lz-(lz*planey+ly)/(hz*planey+hy)*hz | |
end | |
if ry<planey and planey<sy then | |
sy,sx=planey,rx+(planey-ry)/slope | |
sdepth=lz-(lz*planey-ly)/(hz*planey-hy)*hz | |
elseif planey<ry and sy<planey then | |
ry,rx=planey,sx+(planey-sy)/slope | |
rdepth=lz-(lz*planey-ly)/(hz*planey-hy)*hz | |
end | |
--Convert to pixel coordinates | |
local ux,uy=pixelcoef*(rx+planex),pixelcoef*(planey-ry)-36 | |
local vx,vy=pixelcoef*(sx+planex),pixelcoef*(planey-sy)-36 | |
--Calculate properties | |
local wx,wy=vx-ux,vy-uy | |
local s=pixelcoef*size/(rdepth*sdepth)^0.5 | |
local area=s*s | |
local b=pixelcoef*bloom+s | |
local sx,sy=(wx*wx+wy*wy)^0.5+b,b | |
local transparency=1-brightness*area/(sx*sy) | |
--Set properties | |
frame.Size=ud2(0,sx,0,sy) | |
frame.Position=ud2(0,(ux+vx-sx)/2,0,(uy+vy-s)/2) | |
frame.Transparency=transparency | |
if wx~=0 then | |
frame.Rotation=atan2(wy,wx)/deg | |
end | |
lx,ly,lz=dx,dy,dz | |
wasrendered=true | |
wasobstructed=obstructed | |
return "rendered" | |
end | |
end | |
particles[#particles+1]=self | |
local get={} | |
local set={} | |
local meta={} | |
function meta.__index(table,index) return get[index]() end | |
function meta.__newindex(table,index,value) return set[index](value) end | |
function get.position() return v3(px,py,pz) end | |
function get.velocity() return v3(vx,vy,vz) end | |
function get.acceleration() return v3(ax,ay,az) end | |
function get.cancollide() return cancollide end | |
function get.size() return size end | |
function get.bloom() return bloom end | |
function get.brightness() return brightness end | |
function get.color() return frame.BackgroundColor3 end | |
function get.life() return life-tick() end | |
function get.distance() return distance end | |
function set.position(p) px,py,pz=p.x,p.y,p.z end | |
function set.velocity(v) vx,vy,vz=v.x,v.y,v.z end | |
function set.acceleration(a) ax,ay,az=a.x,a.y,a.z end | |
function set.cancollide(newcancollide) cancollide=newcancollide end | |
function set.size(newsize) size=newsize end | |
function set.bloom(newbloom) bloom=newbloom end | |
function set.brightness(newbrightness) brightness=newbrightness end | |
function set.color(newcolor) frame.BackgroundColor3=newcolor end | |
function set.life(newlife) life=tick()+newlife end | |
part=setmt(self,meta) | |
if prop.dt then | |
self.step(prop.dt,tick()) | |
end | |
return part | |
end | |
local avg=800 | |
local asd=0 | |
function particle.step(dt) | |
local newtime=tick() | |
local dt=newtime-time | |
time=newtime | |
local cameracf=camera.CoordinateFrame | |
local screenx,screeny=camera.ViewportSize.x,camera.ViewportSize.y | |
planey=tan(camera.FieldOfView/2*deg) | |
planex=screenx/screeny*planey | |
pixelcoef=screeny/(2*planey) | |
cameraposition=cameracf.p | |
cpx,cpy,cpz, | |
cxx,cyx,czx, | |
cxy,cyy,czy, | |
cxz,cyz,czz=components(cameracf) | |
local j=0 | |
for i=1,#particles do | |
local p=particles[i] | |
particles[i]=nil | |
if removelist[p] then | |
p.frame.Transparency=1 | |
frames[#frames+1]=p.frame | |
removelist[p]=nil | |
elseif p then | |
p.step(dt,time) | |
j=j+1 | |
particles[j]=p | |
end | |
end | |
if #particles>0 then | |
local d=#particles/60/(tick()-time) | |
avg=avg*0.95+d*0.05 | |
end | |
if asd==0 then | |
--print("you can process about "..avg.." particles. You are currently processing "..#particles.." particles") | |
end | |
asd=(asd+1)%60 | |
end | |
function particle:addtophysicsignore(object) | |
for i=1,#physignore do | |
if physignore[i]==object then | |
return | |
end | |
end | |
local init=#physignore+1 | |
physignore[init]=object | |
object.Changed:connect(function(prop) | |
if prop=="Parent" and not object.Parent then | |
for i=init,1,-1 do | |
if physignore[i]==object then | |
remove(physignore,i) | |
break | |
end | |
end | |
--[[else | |
init=#physignore+1 | |
physignore[init]=object]] | |
end | |
end) | |
end | |
function particle:addtorenderignore(object) | |
for i=1,#rendignore do | |
if rendignore[i]==object then | |
return | |
end | |
end | |
local init=#rendignore+1 | |
rendignore[init]=object | |
object.Changed:connect(function(prop) | |
if prop=="Parent" and not object.Parent then | |
for i=init,1,-1 do | |
if rendignore[i]==object then | |
remove(rendignore,i) | |
break | |
end | |
end | |
--[[else | |
init=#physignore+1 | |
physignore[init]=object]] | |
end | |
end) | |
end | |
function particle:reset() | |
screen:ClearAllChildren() | |
frames={} | |
particles={} | |
end | |
screen.AncestryChanged:connect(function() | |
wait() | |
screen.Parent=playergui | |
--[[screen:ClearAllChildren() | |
frames={} | |
particles={}]] | |
end) | |
--[[function particle.resistance(entracncevelocity,exitvelocity,penetration) | |
return ln(entracncevelocity/exitvelocity)/penetration | |
end]] | |
end | |
--effects module | |
--By litozinnamon | |
print("Loading effects module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local v3 =Vector3.new | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local deg =math.pi/180 | |
local random =math.random | |
local color =Color3.new | |
local colorseq =ColorSequence.new | |
local spawn =function(F) coroutine.resume(coroutine.create(F)) end | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local debris =game.Debris | |
local new =Instance.new | |
local player =game.Players.LocalPlayer | |
local pgui =player.PlayerGui | |
local repeffects =game.ReplicatedStorage.Effects | |
local smoke =repeffects.Smoke | |
local hole =repeffects.Hole | |
local flash =repeffects.Muzzle | |
local ignore =workspace.Ignore | |
local smokelist ={} | |
local holelist ={} | |
local flashlist ={} | |
local materialtype =Enum.Material | |
local materiallist ={ | |
[Enum.Material.Cobblestone] = {185234383, 185234399, 185234373, 185234412}; | |
[Enum.Material.Wood] = {185238181, 185238234, 185238224, 185238210, 185238204}; | |
[Enum.Material.Brick] = {185237818, 185237842, 185237826, 185237805}; | |
[Enum.Material.Plastic] = {185238152, 185237945, 185237930}; | |
[Enum.Material.Concrete] = {185237894, 185237879, 185237865, 185237853}; | |
["Tile"] = {185238332, 185238308, 185238298, 185238288, 185238271, 185238257}; | |
} | |
function effects:muzzleflash(barrel) | |
local flashpart | |
if #flashlist~=0 then | |
flashpart=flashlist[#flashlist] | |
flashlist[#flashlist]=nil | |
else | |
flashpart=flash:Clone() | |
end | |
local flare=ffc(flashpart,"Flare")---texs | |
local spark=ffc(flashpart,"Spark")---texn | |
if not flare or not spark then | |
trash.remove(flashpart) | |
flashpart=flash:Clone() | |
flare=ffc(flashpart,"Flare")---texs | |
spark=ffc(flashpart,"Spark")---texn | |
end | |
flashpart.Enabled=true | |
flashpart.Parent=pgui | |
flashpart.Adornee=barrel | |
flare.Rotation=random(0,360) | |
flare.Size=ud2(0,20,0,20) | |
flare.Position=ud2(0.5,-10,0.5,-10) | |
spark.Rotation=random(0,360) | |
spark.Size=ud2(0,200,0,200) | |
spark.Position=ud2(0.5,-100,0.5,-100) | |
spark.Visible=true | |
flare:TweenSizeAndPosition(ud2(0,1000,0,1000),ud2(0.5,-500,0.5,-500),"Out","Sine",0.2) | |
spark:TweenSizeAndPosition(ud2(0,500,0,500),ud2(0.5,-250,0.5,-250),"Out","Sine",0.15) | |
spawn(function() | |
wait(0.05) | |
spark.Visible = false | |
wait(0.05) | |
flashpart.Enabled=false | |
wait(0.5) | |
flashpart.Parent=nil | |
flashlist[#flashlist+1]=flashpart | |
end) | |
end | |
function effects:breakwindow(hit,pos,norm,force) | |
network:send("breakwindow",hit) | |
effects:bullethit(hit,pos,norm,true,false,3) | |
end | |
function effects:bloodhit(start,hit,pos,norm) | |
network:send("bloodhit",start,hit,pos,norm) | |
end | |
function effects:bullethit(hit,pos,norm,smokeon,holeon,sparkson) | |
if sparkson and hit.Material~=Enum.Material.Sand and hit.Material~=Enum.Material.Grass and hit.Material~=Enum.Material.Wood then | |
for i=1,sparkson do | |
particle.new{ | |
position=pos; | |
velocity=norm*50+vector.random(20); | |
acceleration=v3(0,-196.2,0); | |
cancollide=false; | |
size=0.1; | |
brightness=20*random(); | |
color=Color3.new(1,1,0.8); | |
bloom=0.005*random(); | |
life=0.3 | |
} | |
end | |
end | |
if smokeon then | |
local smokepart | |
if #smokelist~=0 then | |
smokepart=smokelist[#smokelist] | |
smokelist[#smokelist]=nil | |
else | |
smokepart=smoke:Clone() | |
end | |
smokepart.CFrame=cf(pos,pos+norm+v3(random()-0.5,random()-0.5,random()-0.5))*angles(-90*deg,random(0,360)*deg,0) | |
smokepart.Smoke.Enabled=true | |
if hit.Material==Enum.Material.Grass then | |
smoke.Smoke.Color=colorseq(color(0.470588, 0.564706, 0.509804),color(20/255, 157/255, 30/255)) | |
elseif hit.Material==Enum.Material.Sand then | |
smoke.Smoke.Color=colorseq(color(225/255, 210/255, 149/255),color(216/255, 205/255, 159/255)) | |
else | |
smoke.Smoke.Color=colorseq(color(145/255, 143/255, 145/255),color(141/255, 140/255, 140/255)) | |
end | |
smokepart.Dust.Enabled=true | |
smokepart.Parent=ignore | |
smokepart.Dust.Acceleration=v3(random()-0.5,-1.5,random()-0.5) | |
delay(0.1,function() | |
smokepart.Smoke.Enabled = false | |
smokepart.Dust.Enabled = false | |
wait(5) | |
smokepart.Parent=nil | |
wait(5) | |
smokelist[#smokelist+1]=smokepart | |
end) | |
end | |
if holeon then | |
local holepart | |
if #holelist~=0 then | |
holepart=holelist[#holelist] | |
holelist[#holelist]=nil | |
else | |
holepart=hole:Clone() | |
end | |
holepart.Parent=ignore | |
holepart.CFrame=cf(pos,pos-norm)*angles(-90*deg,random(0,360)*deg,0) | |
local materials=materiallist[Enum.Material.Cobblestone] | |
if materiallist[hit.Material] then materials=materiallist[hit.Material] end | |
local randId = "http://www.roblox.com/asset/?id="..materials[random(1,#materials)] | |
holepart.Decal1.Texture=randId | |
holepart.Decal2.Texture=randId | |
delay(5,function() | |
holepart.Parent=nil | |
holelist[#holelist+1]=holepart | |
end) | |
end | |
end | |
function effects:reload() | |
smokelist={} | |
holelist={} | |
flashlist={} | |
end | |
effects:reload() | |
end | |
--tween module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading tween module") | |
do | |
local type =type | |
local halfpi =math.pi/2 | |
local acos =math.acos | |
local sin =math.sin | |
local cf =CFrame.new | |
local tos =cf().toObjectSpace | |
local components =cf().components | |
local tick =tick | |
local tweendata ={} | |
local equations ={ | |
linear ={p0=0;v0=1;p1=1;v1=1}; | |
smooth ={p0=0;v0=0;p1=1;v1=0}; | |
accelerate ={p0=0;v0=0;p1=1;v1=1}; | |
decelerate ={p0=0;v0=1;p1=1;v1=0}; | |
bump ={p0=0;v0=4;p1=0;v1=-4}; | |
acceleratebump ={p0=0;v0=0;p1=0;v1=-6.75}; | |
deceleratebump ={p0=0;v0=6.75;p1=0;v1=0}; | |
} | |
local updater ={} | |
tween.step =event.new(updater) | |
function tween.tweencframe(object,index,time,equation,nextcframe) | |
if tweendata[object] then | |
tweendata[object]() | |
end | |
local t0=tick() | |
local p0,v0,p1,v1 | |
if type(equation)=="table" then | |
p0=equation[1] | |
v0=equation[2] | |
p1=equation[3] | |
v1=equation[4] | |
else | |
local eq=equations[equation] | |
p0,v0,p1,v1=eq.p0,eq.v0,eq.p1,eq.v1 | |
end | |
local interpolator=cframe.interpolator(object[index],nextcframe) | |
local stop;stop=updater:connect(function() | |
local u=(tick()-t0)/time | |
if u>1 then | |
object[index]=interpolator(p1) | |
stop() | |
tweendata[object]=nil | |
else | |
local v=1-u | |
local t=p0*v*v*v+(3*p0+v0)*u*v*v+(3*p1-v1)*u*u*v+p1*u*u*u | |
object[index]=interpolator(t) | |
end | |
end) | |
tweendata[object]=stop | |
return stop | |
end | |
function tween.freebody(object,index,life,cframe0,velocity0,rotation0,acceleration) | |
local position0=cframe0.p | |
local matrix0=cframe0-position0 | |
local tick0=tick() | |
local stop;stop=updater:connect(function() | |
local t=tick()-tick0 | |
if life and t>life then | |
stop() | |
trash.remove(object) | |
end | |
object[index]=cframe.fromaxisangle(t*rotation0)*matrix0+position0+t*velocity0+t*t*acceleration | |
end) | |
return stop | |
end | |
end | |
--input module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading input module") | |
do | |
local tick =tick | |
local lower =string.lower | |
local nv =Vector3.new() | |
local userinput =game:GetService("UserInputService") | |
local abbreviation ={ | |
ButtonX ="x"; | |
ButtonY ="y"; | |
ButtonA ="a"; | |
ButtonB ="b"; | |
ButtonR1 ="r1"; | |
ButtonL1 ="l1"; | |
ButtonR2 ="r2"; | |
ButtonL2 ="l2"; | |
ButtonR3 ="r3"; | |
ButtonL3 ="l3"; | |
ButtonStart ="start"; | |
ButtonSelect ="select"; | |
DPadLeft ="left"; | |
DPadRight ="right"; | |
DPadUp ="up"; | |
DPadDown ="down"; | |
} | |
input.keyboard ={} | |
input.keyboard.down ={} | |
input.keyboard.onkeydown ={} | |
input.keyboard.onkeyup ={} | |
input.mouse ={} | |
input.mouse.Position =nv | |
input.mouse.down ={} | |
input.mouse.onbuttondown ={} | |
input.mouse.onbuttonup ={} | |
input.mouse.onmousemove ={} | |
input.mouse.onscroll ={} | |
input.controller ={} | |
input.controller.down ={} | |
input.controller.onbuttondown ={} | |
input.controller.onbuttonup ={} | |
input.controller.onintegralmove ={} | |
local fireonkeydown =event.new(input.keyboard.onkeydown) | |
local fireonkeyup =event.new(input.keyboard.onkeyup) | |
local fireonbuttondown =event.new(input.mouse.onbuttondown) | |
local fireonbuttonup =event.new(input.mouse.onbuttonup) | |
local fireonmousemove =event.new(input.mouse.onmousemove) | |
local fireonscroll =event.new(input.mouse.onscroll) | |
local fireoncbuttondown =event.new(input.controller.onbuttondown) | |
local fireoncbuttonup =event.new(input.controller.onbuttonup) | |
local fireonintegralmove =event.new(input.controller.onintegralmove) | |
local keymap ={} | |
local triggerthreshold =0.2 | |
local stickthreshold =0.25--lol | |
local gamepadpos | |
local triggeron ={} | |
local typing | |
userinput.TextBoxFocused:connect(function() | |
typing=true | |
end) | |
userinput.TextBoxFocusReleased:connect(function() | |
typing=false | |
end) | |
userinput.InputChanged:connect(function(object) | |
local type=object.UserInputType.Name | |
local pos=object.Position | |
if type=="MouseMovement" then | |
input.mouse.position=pos | |
fireonmousemove(object.Delta) | |
elseif type=="MouseWheel" then | |
fireonscroll(pos.z) | |
elseif type=="Gamepad1" then | |
local key=object.KeyCode.Name | |
--Thumbstick1 reserved for movement | |
if key=="Thumbstick2" then | |
local m=pos.magnitude | |
if stickthreshold<m then | |
gamepadpos=(1-stickthreshold/m)/(1-stickthreshold)*pos | |
elseif gamepadpos then | |
gamepadpos=nil | |
end | |
elseif (key=="ButtonL2" or key=="ButtonR2") then | |
local abv=abbreviation[key] | |
if triggerthreshold<pos.z and not input.controller.down[abv] then | |
local mappedkey=keymap[abv] | |
if mappedkey then | |
input.keyboard.down[mappedkey]=tick() | |
fireonkeydown(mappedkey) | |
end | |
input.controller.down[abv]=tick() | |
fireoncbuttondown(abv) | |
elseif pos.z<triggerthreshold and input.controller.down[abv] then | |
local mappedkey=keymap[abv] | |
if mappedkey then | |
input.keyboard.down[mappedkey]=nil | |
fireonkeyup(mappedkey) | |
end | |
input.controller.down[abv]=nil | |
fireoncbuttonup(abv) | |
end | |
end | |
end | |
end) | |
userinput.InputBegan:connect(function(object) | |
if typing or roundsystem.lock or (char.health and char.health<=0) then return end--i mad | |
local type=object.UserInputType.Name | |
if type=="Keyboard" then | |
local key=lower(object.KeyCode.Name) | |
input.keyboard.down[key]=tick() | |
fireonkeydown(key) | |
elseif type=="Gamepad1" then | |
local key=abbreviation[object.KeyCode.Name] | |
if key and key~="l2" and key~="r2" or not input.controller.down[key] then | |
local mappedkey=keymap[key] | |
if mappedkey then | |
input.keyboard.down[mappedkey]=tick() | |
fireonkeydown(mappedkey) | |
end | |
input.controller.down[key]=tick() | |
fireoncbuttondown(key) | |
end | |
elseif type=="MouseButton1" then | |
input.mouse.down.left=tick() | |
fireonbuttondown("left") | |
elseif type=="MouseButton2" then | |
input.mouse.down.right=tick() | |
fireonbuttondown("right") | |
elseif type=="MouseButton3" then | |
input.mouse.down.middle=tick() | |
fireonbuttondown("middle") | |
end | |
end) | |
userinput.InputEnded:connect(function(object) | |
if typing then return end | |
local type=object.UserInputType.Name | |
if type=="Keyboard" then | |
local key=lower(object.KeyCode.Name) | |
input.keyboard.down[key]=nil | |
fireonkeyup(key) | |
elseif type=="Gamepad1" then | |
local key=abbreviation[object.KeyCode.Name] | |
if key and key~="l2" and key~="r2" or input.controller.down[key] then | |
local mappedkey=keymap[key] | |
if mappedkey then | |
input.keyboard.down[mappedkey]=nil | |
fireonkeyup(mappedkey) | |
end | |
input.controller.down[key]=nil | |
fireoncbuttonup(key) | |
end | |
elseif type=="MouseButton1" then | |
input.mouse.down.left=nil | |
fireonbuttonup("left") | |
elseif type=="MouseButton2" then | |
input.mouse.down.right=nil | |
fireonbuttonup("right") | |
elseif type=="MouseButton3" then | |
input.mouse.down.middle=nil | |
fireonbuttonup("middle") | |
end | |
end) | |
function input.mouse:hide() | |
userinput.MouseIconEnabled=false | |
end | |
function input.mouse:show() | |
userinput.MouseIconEnabled=true | |
end | |
function input.mouse.visible() | |
return userinput.MouseIconEnabled | |
end | |
function input.mouse:lockcenter() | |
userinput.MouseBehavior="LockCenter" | |
end | |
function input.mouse:free() | |
userinput.MouseBehavior="Default" | |
end | |
function input.mouse:lock() | |
userinput.MouseBehavior="LockCurrentPosition" | |
end | |
function input.controller:map(button,key) | |
keymap[button]=key | |
end | |
function input.controller:unmap(button) | |
keymap[button]=nil | |
end | |
function input.step(dt) | |
if gamepadpos then | |
fireonintegralmove(dt*gamepadpos,dt) | |
end | |
end | |
end | |
--animation module | |
--By AxisAngle and litozinnamon | |
print("Loading animation module") | |
do | |
local sin =math.sin | |
local acos =math.acos | |
local type =type | |
local next =next | |
local tick =tick | |
local cf =CFrame.new | |
local v3 =vector.new | |
local nv =v3() | |
local inverse =CFrame.new().inverse | |
local tos =CFrame.new().toObjectSpace | |
local toquaternion =cframe.toquaternion | |
local clone =game.Clone | |
local new =Instance.new | |
local play =new("Sound").Play | |
local stop =new("Sound").Stop | |
local equations ={ | |
linear ={p0=0;v0=1;p1=1;v1=1}; | |
smooth ={p0=0;v0=0;p1=1;v1=0}; | |
accelerate ={p0=0;v0=0;p1=1;v1=1}; | |
decelerate ={p0=0;v0=1;p1=1;v1=0}; | |
bump ={p0=0;v0=4;p1=0;v1=-4}; | |
acceleratebump ={p0=0;v0=0;p1=0;v1=-6.75}; | |
deceleratebump ={p0=0;v0=6.75;p1=0;v1=0}; | |
} | |
local function interpolator(c0,c1,t0,dur,eq,pivot) | |
pivot=pivot or nv | |
c0=c0*cf(pivot) | |
c1=c1*cf(pivot) | |
local p0,v0,p1,v1 | |
if type(eq)=="table" then | |
p0,v0,p1,v1=eq[1],eq[2],eq[3],eq[4] | |
else | |
local eq=equations[eq or "smooth"] | |
p0,v0,p1,v1=eq.p0,eq.v0,eq.p1,eq.v1 | |
end | |
local x0,y0,z0,qx0,qy0,qz0,qw0=toquaternion(c0) | |
local x1,y1,z1,qx1,qy1,qz1,qw1=toquaternion(c1) | |
local x,y,z=x1-x0,y1-y0,z1-z0 | |
local c=qx0*qx1+qy0*qy1+qz0*qz1+qw0*qw1 | |
if c<0 then | |
qx0,qy0,qz0,qw0=-qx0,-qy0,-qz0,-qw0 | |
end | |
if c<0.99999 then | |
local s=(1-c*c)^0.5 | |
local th=acos(c) | |
return function(t) | |
t=(t-t0)/dur;t=t<1 and t or 1 | |
local i=1-t | |
local v=p0*i*i*i+(3*p0+v0)*t*i*i+(3*p1-v1)*t*t*i+p1*t*t*t | |
local s0=sin(th*(1-v))/s | |
local s1=sin(th*v)/s | |
return cf( | |
x0+v*x, | |
y0+v*y, | |
z0+v*z, | |
s0*qx0+s1*qx1, | |
s0*qy0+s1*qy1, | |
s0*qz0+s1*qz1, | |
s0*qw0+s1*qw1 | |
)*cf(-pivot),1==t | |
end | |
else | |
return function(t) | |
t=(t-t0)/dur;t=t<1 and t or 1 | |
local i=1-t | |
local v=p0*i*i*i+(3*p0+v0)*t*i*i+(3*p1-v1)*t*t*i+p1*t*t*t | |
return cf(x0+v*x,y0+v*y,z0+v*z,qx1,qy1,qz1,qw1)*cf(-pivot),1==t | |
end | |
end | |
end | |
function animation.player(modeldata,sequence) | |
local interpolators ={} | |
local framenumber =1 | |
local t0 =0 | |
local lasttime =t0 | |
local stdtimescale =sequence.stdtimescale | |
local timescale =sequence.timescale | |
local cframes ={} | |
local lastcframes ={} | |
for i,v in next,modeldata do | |
if v.part then | |
lastcframes[i]=v.part.CFrame | |
cframes[i]=v.part.CFrame | |
end | |
end | |
return function(time) | |
local dt=time-lasttime | |
lasttime=time | |
for i=framenumber,#sequence do | |
local frame=sequence[i] | |
if t0<time then | |
for i=1,#frame do | |
local data=frame[i] | |
local partname=data.part | |
if not modeldata[partname] then | |
error("Error in frame: "..framenumber..". "..partname.. " is not in modeldata") | |
end | |
if data.c0 then | |
interpolators[partname]=nil | |
modeldata[partname].weld.C0=data.c0=="base" and modeldata[partname].basec0 or data.c0 | |
end | |
if data.c1 then | |
interpolators[partname]=interpolator(modeldata[partname].weld.C0,data.c1=="base" and modeldata[partname].basec0 or data.c1,t0,data.t and data.t*timescale or frame.delay*timescale,data.eq,data.pivot) | |
end | |
if data.clone then | |
if modeldata[data.clone] then | |
error("Error in frame: "..framenumber..". Cannot clone "..partname..". "..data.clone.." already exists.") | |
end | |
local part=clone(modeldata[partname].part) | |
part.Parent=workspace.CurrentCamera | |
local weld=new("Motor6D",part) | |
local part0=data.part0 and modeldata[data.part0].part or modeldata[partname].weld.Part0 | |
weld.Part0=part0 | |
weld.Part1=part | |
weld.C0=part0.CFrame:inverse()*modeldata[partname].weld.Part0.CFrame*modeldata[partname].weld.C0 | |
modeldata[data.clone]={ | |
part=part; | |
weld=weld; | |
clone=true; | |
} | |
cframes[data.clone]=cframes[partname] | |
lastcframes[data.clone]=lastcframes[partname] | |
end | |
if data.transparency then | |
modeldata[partname].part.Transparency=data.transparency | |
end | |
if data.sound then | |
local sound=new("Sound") | |
if data.soundid then | |
sound.SoundId=data.soundid | |
end | |
if data.v then | |
sound.Volume=data.v | |
end | |
if data.p then | |
sound.Pitch=data.p | |
end | |
if data.tp then | |
sound.TimePosition=data.tp | |
else | |
sound.TimePosition=0 | |
end | |
sound.Parent=modeldata[partname].part | |
play(sound) | |
if data.d then | |
delay(data.d,function() | |
sound:Stop() | |
end) | |
end | |
end | |
if data.drop then | |
if not modeldata[partname].clone then | |
error("Error in frame: "..framenumber..". Cannot drop "..partname..". Part is not a clone") | |
end | |
local lastcf=lastcframes[partname] | |
local curcf=cframes[partname] | |
tween.freebody(modeldata[partname].part, | |
"CFrame",timescale/stdtimescale,modeldata[partname].part.CFrame, | |
(curcf.p-lastcf.p)/dt, | |
cframe.toaxisangle(curcf*lastcf:inverse())/dt, | |
v3(0,-196.2/stdtimescale*stdtimescale*(timescale*timescale),0)) | |
trash.remove(modeldata[partname].weld) | |
modeldata[partname]=nil | |
interpolators[partname]=nil | |
end | |
if data.delete then | |
trash.remove(modeldata[partname].weld) | |
trash.remove(modeldata[partname].part) | |
modeldata[partname]=nil | |
interpolators[partname]=nil | |
end | |
end | |
t0=t0+frame.delay*timescale | |
framenumber=framenumber+1 | |
else | |
break | |
end | |
end | |
for i,v in next,interpolators do | |
local newcf,stop,t=v(time) | |
modeldata[i].weld.C0=newcf | |
if stop then | |
interpolators[i]=nil | |
end | |
end | |
for i,v in next,modeldata do | |
if v.part then | |
lastcframes[i]=cframes[i] | |
cframes[i]=v.part.CFrame | |
end | |
end | |
if t0<time then | |
for i,v in next,modeldata do | |
if v.clone then | |
trash.remove(v.weld) | |
trash.remove(v.part) | |
modeldata[i]=nil | |
end | |
end | |
end | |
return t0<time | |
end | |
end | |
function animation.reset(modeldata,t) | |
local interpolators={} | |
for i,v in next,modeldata do | |
if v.clone then | |
modeldata[i]=nil | |
trash.remove(v.weld) | |
trash.remove(v.part) | |
else | |
if v.part then | |
v.part.Transparency=v.basetransparency | |
end | |
interpolators[i]=interpolator(v.weld.C0,v.basec0,0,t or 1) | |
end | |
end | |
return function(time) | |
for i,v in next,interpolators do | |
local newcf,stop=v(time) | |
modeldata[i].weld.C0=newcf | |
end | |
return t<time | |
end | |
end | |
end | |
--chat module | |
--By litozinnamon | |
print("Loading chat module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local ceil =math.ceil | |
local cf =CFrame.new | |
local v3 =Vector3.new | |
local color =Color3.new | |
local dot =Vector3.new().Dot | |
local workspace =workspace | |
local ray =Ray.new | |
local new =Instance.new | |
local rtype =game.IsA | |
local debris =game.Debris | |
local sub =string.sub | |
local len =string.len | |
local lower =string.lower | |
local find =string.find | |
local player =game.Players.LocalPlayer | |
local pgui =player.PlayerGui | |
local misc =game.ReplicatedStorage.Misc | |
local msg =wfc(misc,"Msger") | |
local chatgui =wfc(pgui,"Chat") | |
local chatbox =wfc(chatgui,"TextBox") | |
local warn =wfc(chatgui,"Warn") | |
local globalchat =wfc(chatgui,"GlobalChat") | |
local admin | |
local adminlist={ | |
525919, --- trey | |
4337002, --- buddy | |
1667819, --- shay | |
5725475, --- lito | |
66366193,--- cid | |
} | |
local chatspam =0 | |
local totalspam =0 | |
local maxchar =200 | |
local lines =8 | |
local chatting | |
for i=1,#adminlist do if adminlist[i]==player.userId then admin=true end end | |
network:add("chatted",function(chatter,text,tag,teamchat) | |
if teamchat and chatter.TeamColor~=player.TeamColor then return end | |
local mes=msg:Clone() | |
local mtag=wfc(mes,"Tag") | |
local offset=5 | |
mes.Parent=globalchat | |
mtag.Text=tag | |
if tag~="" then | |
offset=mtag.TextBounds.x+5 | |
mes.Position=ud2(0.01,offset,1,20) | |
mtag.Position=ud2(0,-offset+5,0,0) | |
end | |
mes.Text=chatter.Name.." : " | |
mes.TextColor=chatter.TeamColor | |
mes.Msg.Text=text | |
mes.Msg.Position=ud2(0,mes.TextBounds.x,0,0) | |
end) | |
function newchat() | |
local message=chatbox.Text | |
local tag=admin and "[Dev] " or "" | |
local teamchat | |
local teamswitch | |
local admincommand | |
if sub(message,1,1)=="%" then | |
teamchat=true | |
message=sub(message,2,len(message)) | |
end | |
if chatspam>5 then | |
warn.Visible=true | |
chatspam=chatspam+1 | |
totalspam=totalspam+1 | |
warn.Text="You have been blocked temporarily for spamming. WARNING : ".. totalspam.." out of 3" | |
if totalspam>3 then | |
player:Kick("Kicked for repeated spamming") | |
end | |
spawn(10,function() chatspam=chatspam-5 warn.Visible=false end) | |
return | |
end | |
local teamtype | |
--[[if sub(lower(message),1,5)=="join/" or sub(lower(message),1,5)=="swap/" or sub(lower(message),1,5)=="team/" then | |
teamtype=6 | |
elseif sub(lower(message),1,6)==":join " or sub(lower(message),1,6)==":team " then | |
teamtype=7 | |
elseif sub(lower(message),1,7)=="switch/" then | |
teamtype=8 | |
end | |
if teamtype then | |
local theteam | |
local tnum=0 | |
local t=game.Teams:GetChildren() | |
for i=1,#t do | |
local v=t[i] | |
if find(lower(v.Name),sub(lower(message),teamtype))==1 then | |
theteam=v | |
tnum=tnum+1 | |
end | |
end | |
if tnum==1 and player.TeamColor~=theteam.TeamColor then | |
network:send("changeteam",player,theteam) | |
end | |
elseif message=="switch" or message=="switchteam" then | |
network:send("changeteam",player,player.TeamColor.Name=="Bright orange" and BrickColor.new("Bright blue") or BrickColor.new("Bright orange")) | |
end]] | |
if admincommand then | |
---blah too lazy to code admin commands | |
end | |
if len(message)>200 then | |
message=sub(message,1,200) | |
end | |
local header=teamchat and "(TEAM CHAT)" or admincommand and "[ADMIN COMMAND]" or teamswitch and "[TEAMSWITCH]" or "" | |
message=header.." " ..message | |
if not admincommand then | |
chatspam=chatspam+1 | |
network:send("chatted",player,message,tag,teamchat) | |
spawn(function() wait(10) chatspam=chatspam-1 end) | |
end | |
chatbox.Text="Press '/' or click here to chat" | |
chatting=false | |
chatbox.ClearTextOnFocus=true | |
end | |
function chat:inmenu() | |
globalchat.Position=ud2(0.05,0,1,-180) | |
chatbox.Position=ud2(0.05,10,1, -20) | |
end | |
function chat:ingame() | |
chatbox.Position=ud2(0,10,1, -20) | |
globalchat.Position=ud2(0,150,1,-50) | |
end | |
globalchat.ChildAdded:connect(function(child) | |
local m=globalchat:GetChildren() | |
for i=1,#m do | |
local v=m[i] | |
local tag=wfc(v,"Tag") | |
local tagoff=5 | |
if tag.Text~="" then | |
tagoff=5+tag.TextBounds.x | |
v.Position=ud2(0.01,tagoff,1,v.Position.Y.Offset) | |
end | |
if v.Parent then | |
v:TweenPosition(ud2(0.01,tagoff,1,(i-#m)*20),"Out","Sine",0.2,true) | |
end | |
if #m>lines and i<=#m-lines and v.Name~="Deleted" then | |
v.Name="Deleted" | |
wfc(v,"Msg") | |
wfc(v,"Tag") | |
for x=1,5 do | |
if ffc(v,"Msg") and ffc(v,"Tag") then | |
v.TextTransparency=(x*2)/10 | |
v.TextStrokeTransparency=(x*2)/10+0.1 | |
v.Msg.TextTransparency=(x*2)/10 | |
v.Msg.TextStrokeTransparency=(x*2)/10+0.1 | |
v.Tag.TextTransparency=(x*2)/10 | |
v.Tag.TextStrokeTransparency=(x*2)/10+0.1 | |
wait(1/30) | |
end | |
if v and v.Parent then trash.remove(v) end | |
end | |
end | |
end | |
end) | |
chatbox.Focused:connect(function() | |
chatbox.Active=true | |
end) | |
chatbox.FocusLost:connect(function(enter) | |
chatbox.Active=false | |
if enter and chatbox.Text~="" then | |
newchat() | |
end | |
end) | |
game:GetService("UserInputService").InputBegan:connect(function(keycode) | |
local key=keycode.KeyCode | |
if key==Enum.KeyCode.Slash and not chatbox.Active then | |
chatbox:CaptureFocus() | |
chatbox.ClearTextOnFocus=false | |
end | |
end) | |
end | |
--hud module | |
--By litozinnamon | |
print("Loading hud module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local ceil =math.ceil | |
local cf =CFrame.new | |
local v3 =Vector3.new | |
local color =Color3.new | |
local dot =Vector3.new().Dot | |
local workspace =workspace | |
local ray =Ray.new | |
local new =Instance.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local infolder =function(l,e) for i=1,#l do if l[i].Name==e then return l[i] end end end | |
local rtype =game.IsA | |
local debris =game.Debris | |
local player =game.Players.LocalPlayer | |
local playertag =game.ReplicatedStorage.Character.PlayerTag | |
local pgui =player.PlayerGui | |
local misc =game.ReplicatedStorage.Misc | |
local bloodarc =misc.BloodArc | |
local spotdot =misc.Spot | |
local rfeed =misc.Feed | |
local hsht =misc.Headshot | |
local maingui =wfc(pgui,"MainGui") | |
local spot =wfc(pgui,"Spot") | |
local gamegui =wfc(maingui,"GameGui") | |
local crossframe =wfc(gamegui,"CrossHud") | |
local crossparts ={wfc(crossframe,"HR"),wfc(crossframe,"HL"),wfc(crossframe,"VD"),wfc(crossframe,"VU"),} | |
local ammofr =wfc(gamegui,"AmmoHud") | |
local scopefr =wfc(gamegui,"ScopeFrame") | |
local hitmarker =wfc(gamegui,"Hitmarker") | |
local tagfr =wfc(gamegui,"NameTag") | |
local bloodscreen =wfc(gamegui,"BloodScreen") | |
local radar =wfc(gamegui,"Radar") | |
local killfeed =wfc(gamegui,"Killfeed") | |
local rme =wfc(radar,"Me") | |
local rfolder =wfc(radar,"Folder") | |
local distance =300 | |
local offset =-rme.Size.X.Offset/2 | |
local ammotext =wfc(ammofr,"Ammo") | |
local magtext =wfc(ammofr,"Mag") | |
local healthtext =wfc(ammofr,"Health") | |
local fmodetext =wfc(ammofr,"FMode") | |
local sightmark | |
local nametags ={} | |
local dotlist ={} | |
local healthlist ={} | |
local prevhealth =0 | |
local rtime =0 | |
local stime =0 | |
local radarinterval =1/30 | |
local spotinterval =0.5 | |
hud.crossscale =physics.spring.new(0) | |
hud.crossscale.s =10 | |
hud.crossscale.d =0.8 | |
hud.crossscale.t =1 | |
hud.crossspring =physics.spring.new(0) | |
hud.crossspring.s =12 | |
hud.crossspring.d =0.65 | |
hud.hitspring =physics.spring.new(1) | |
hud.hitspring.s =5 | |
hud.hitspring.d =0.7 | |
network:add("updateothershealth",function(player,health0,healtick0,healrate,maxhealth,alive) | |
if not healthlist[player] then healthlist[player]={} end | |
healthlist[player].health0=health0 | |
healthlist[player].healtick0=healtick0 | |
healthlist[player].healrate=healrate | |
healthlist[player].maxhealth=maxhealth | |
healthlist[player].alive=alive | |
end) | |
network:add("killfeed",function(killer,victim,dist,weapon,head) | |
local spacing=15 | |
local newfeed=rfeed:Clone() | |
newfeed.Text=killer.Name | |
newfeed.TextColor=killer.TeamColor | |
newfeed.GunImg.Text=weapon | |
if head then hsht:Clone().Parent=newfeed.GunImg end | |
newfeed.Victim.Text=victim.Name | |
newfeed.Victim.TextColor=victim.TeamColor | |
newfeed.GunImg.Dist.Text="Dist: "..dist.." studs" | |
newfeed.Parent=killfeed | |
newfeed.GunImg.Size = UDim2.new(0,newfeed.GunImg.TextBounds.x,0,30) | |
newfeed.GunImg.Position = UDim2.new(0,spacing+newfeed.TextBounds.x,0,-5) | |
newfeed.Victim.Position = UDim2.new(0,spacing*2+newfeed.TextBounds.x+newfeed.GunImg.TextBounds.x,0,0) | |
spawn(function() | |
newfeed.Visible = true | |
wait(20) | |
for i = 1, 10 do | |
if newfeed.Parent then | |
newfeed.TextTransparency=i/10 | |
newfeed.TextStrokeTransparency=i/10+0.5 | |
newfeed.GunImg.TextStrokeTransparency=i/10+0.5 | |
newfeed.GunImg.TextTransparency=i/10 | |
newfeed.Victim.TextStrokeTransparency=i/10+0.5 | |
newfeed.Victim.TextTransparency=i/10 | |
wait(1/30) | |
end | |
end | |
if newfeed and newfeed.Parent then trash.remove(newfeed) end | |
end) | |
local kb=killfeed:GetChildren() | |
for i=1,#kb do | |
local v=kb[i] | |
v:TweenPosition(ud2(0.01,5,1,(i-#kb)*25-25),"Out","Sine",0.2,true) | |
if #kb>5 and (#kb-i)>=5 then | |
spawn(function() | |
if kb[1].Name~="Deleted" then | |
for i = 1, 10 do | |
if ffc(kb[1],"Victim") then | |
kb[1].TextTransparency=i/10 | |
kb[1].TextStrokeTransparency=i/10+0.5 | |
kb[1].Victim.TextTransparency=i/10 | |
kb[1].Victim.TextStrokeTransparency=i/10+0.5 | |
kb[1].Name="Deleted" | |
kb[1].GunImg.TextTransparency=i/10 | |
kb[1].GunImg.TextStrokeTransparency=i/10+0.5 | |
wait(1/30) | |
end | |
end | |
trash.remove(kb[1]) | |
end | |
end) | |
end | |
end | |
end) | |
function hud.inializehealth(player,alive) | |
if not healthlist[player] then healthlist[player]={} end | |
healthlist[player].health0=alive and 100 or 0 | |
healthlist[player].healtick0=0 | |
healthlist[player].healrate=0 | |
healthlist[player].maxhealth=100 | |
healthlist[player].alive=alive | |
end | |
local function gethealth(player) | |
local healthstat=healthlist[player] | |
if healthstat then | |
local health0=healthlist[player].health0 | |
local healtick0=healthlist[player].healtick0 | |
local healrate=healthlist[player].healrate | |
local maxhealth=healthlist[player].maxhealth | |
local alive=healthlist[player].alive | |
if alive then | |
local x=tick()-healtick0 | |
if x<0 then | |
return health0 | |
else | |
local curhealth=health0+x*healrate | |
return curhealth<maxhealth and curhealth or maxhealth | |
end | |
else | |
return 0 | |
end | |
else | |
return 0 | |
end | |
end | |
function hud:enablegamegui(on) | |
gamegui.Visible=on | |
end | |
function hud:isplayeralive(p) | |
local healthstat=healthlist[p] | |
if healthstat then | |
return healthlist[p].alive | |
end | |
end | |
function hud:getplayerhealth(p) | |
return gethealth(p) | |
end | |
local function updatecross() | |
local size=hud.crossspring.p*4*hud.crossscale.p*(char.speed/14*(1-0.8)*2+0.8)*(char.sprint+1)/2 | |
for i=1,4 do | |
crossparts[i].BackgroundTransparency=1-size/20 | |
end | |
crossparts[1].Position=ud2(0,size,0,0) | |
crossparts[2].Position=ud2(0,-size-7,0,0) | |
crossparts[3].Position=ud2(0,0,0,size) | |
crossparts[4].Position=ud2(0,0,0,-size-7) | |
if hud.crossspring.t==0 and not scopefr.Visible and sightmark and sightmark.Parent then | |
local pos=camera.currentcamera:WorldToViewportPoint(sightmark.Position) | |
hitmarker.Position=ud2(0,pos.x-125,0,pos.y-125) | |
else | |
hitmarker.Position=ud2(0.5,-125,0.5,-125) | |
end | |
end | |
function hud:getplayervisible(guy) | |
local state=nametags[guy] | |
if state then | |
return state.Visible | |
end | |
end | |
local function updateplayernames() | |
local pp=game.Players:GetChildren() | |
local pphash={} | |
local camcf=camera.cframe | |
for i=1,#pp do | |
local v=pp[i] | |
if v~=player and v.Character and ffc(v.Character,"Head") and ffc(v.Character,"Torso") then--I FIXED UR ERROR BY ADDING v.Character and | |
pphash[v]=true | |
local head=v.Character.Head | |
local torsopos=v.Character.Torso.CFrame*v3(0,0.5,0) | |
local pos=camera.currentcamera:WorldToScreenPoint(head.Position+cframe.vtws(camcf,v3(0,0.625,0))) | |
local center=camera.currentcamera.ViewportSize/2 | |
local dist=(torsopos-camcf.p).magnitude | |
local d=dot(camera.lookvector,(torsopos-camcf.p).unit) | |
local diff=(1/(d*d)-1)^0.5*dist | |
local tag=nametags[v] | |
if tag and ffc(tag,"Health") then | |
tag.Position=ud2(0,pos.x-75,0,pos.y) | |
if v.TeamColor~=player.TeamColor then | |
local scan=raycast(workspace,ray(camcf.p,torsopos-camcf.p),{camera.currentcamera,char.character,v.Character}) | |
tag.Visible=not scan and d>0 | |
tag.TextTransparency=0.1+(diff<1 and 0 or diff<4 and diff-1 or 1)*0.9 | |
tag.TextStrokeTransparency=0.7+(diff<1 and 0 or diff<4 and diff-1 or 1)*0.3 | |
else | |
tag.Health.Percent.Size=ud2(gethealth(v)/100,0,1,0) | |
tag.Visible=d>0 and hud:isplayeralive(v) | |
end | |
else | |
local newtag=playertag:Clone() | |
newtag.Text=v.Name | |
newtag.Health.Percent.Size=ud2(1,0,1,0) | |
newtag.Position=ud2(0,pos.x-75,0,pos.y) | |
newtag.Parent=tagfr | |
newtag.Visible=pos.z>0 | |
newtag.Health.Visible=v.TeamColor==player.TeamColor | |
newtag.TextTransparency=0.1 | |
newtag.TextStrokeTransparency=0.7 | |
newtag.TextColor3=v.TeamColor~=player.TeamColor and color(255/255,10/255,20/255) or color(0,255/255,234/255) | |
nametags[v]=newtag | |
end | |
end | |
end | |
for i,v in next,nametags do | |
if not pphash[i] then | |
trash.remove(v) | |
nametags[i]=nil | |
end | |
end | |
end | |
function hud:setcrossscale(scale) | |
hud.crossscale.t=scale | |
end | |
function hud:setcrosssize(size) | |
hud.crossspring.t=size | |
end | |
function hud:setscope(visible) | |
scopefr.Visible=visible | |
end | |
function hud:setcrosssettings(size,speed,damper,sight) | |
hud.crossspring.t=size | |
hud.crossspring.s=speed | |
hud.crossspring.d=damper | |
sightmark=sight | |
end | |
function hud:updateammo(mag,ammo) | |
if mag=="knife" then | |
ammotext.Text="/ --" | |
magtext.Text="--" | |
else | |
ammotext.Text="/ "..ammo | |
magtext.Text=mag | |
end | |
end | |
function hud:updatefiremode(mode) | |
fmodetext.Text=mode=="knife" and "[------]" or mode==true and "[AUTO]" or mode==1 and "[SEMI]" or "[BURST]" | |
end | |
function hud:firehitmarker() | |
hud.hitspring.p=-3 | |
end | |
function hud:fireradar(guy) | |
local prev=infolder(spot:GetChildren(),guy.Name) | |
if prev then | |
prev.Time.Value=(prev.Time.Value<=30 and 30) or (prev.Time.Value+30>200 and 200) or prev.Time.Value+30 | |
else | |
local mark=spotdot:Clone() | |
mark.Parent=spot | |
mark.Name=guy.Name | |
mark.Time.Value=30 | |
mark.Adornee=char.rootpart | |
end | |
end | |
local function updatehealth() | |
local health=char.health | |
healthtext.Text=health+-health%1 | |
if health<prevhealth then | |
local damage=prevhealth-health | |
bloodscreen.ImageTransparency=bloodscreen.ImageTransparency-damage/prevhealth*.7 | |
bloodscreen.BackgroundTransparency=bloodscreen.BackgroundTransparency-damage/prevhealth*.5+.3 | |
elseif health>prevhealth or health==100 then | |
bloodscreen.ImageTransparency=bloodscreen.ImageTransparency+0.001 | |
bloodscreen.BackgroundTransparency=bloodscreen.BackgroundTransparency+0.001 | |
elseif health<=0 then | |
bloodscreen.ImageTransparency=1 | |
bloodscreen.BackgroundTransparency=1 | |
end | |
prevhealth=health | |
end | |
local function update_pos(ref,pos,color,trans) | |
local dot=dotlist[ref] | |
if not dot then return end | |
dot.Visible=true | |
dot.BackgroundColor3=color | |
dot.Position=pos | |
dot.BackgroundTransparency=trans | |
end | |
local function updateradar() | |
local old=rfolder:GetChildren() | |
for i =1, #old do | |
old[i].Visible=false | |
end | |
local torso=char.rootpart | |
local look=torso.CFrame.lookVector | |
local cameracf=cf(torso.CFrame.p,torso.CFrame.p+look) | |
local ppl=game.Players:GetChildren() | |
for i=1,#ppl do | |
local v=ppl[i] | |
if v~=player and v.Character and workspace:FindFirstChild(v.Name) then | |
local tor = v.Character:FindFirstChild("Torso") | |
local alive = v.Character:FindFirstChild("Humanoid") | |
if tor and alive then | |
if v.TeamColor==player.TeamColor or infolder(spot:GetChildren(),v.Name) then | |
local diff=cameracf:inverse()*tor.Position | |
local x=0.5+diff.x/distance | |
local z=0.5+diff.z/distance | |
local pos=ud2(x,offset,z,offset) | |
local c=v.TeamColor==player.TeamColor and color(0.5,1,0.5) or color(1,0,0) | |
update_pos(i,pos,c,-0.5+(torso.Position-tor.Position).Magnitude/150) | |
end | |
end | |
end | |
end | |
end | |
function hud:firespot(v,spotter) | |
local spotter=spotter or player.Name | |
if v.Character then | |
local head=ffc(v.Character,"Head") | |
local prev=infolder(spot:GetChildren(),v.Name) | |
if head then | |
if prev then | |
prev.Time.Value=150 | |
prev.Dot.Visible=true | |
prev.Adornee=head | |
if not ffc(prev,spotter) then | |
local assist=new("Model",prev) | |
assist.Name=spotter | |
end | |
else | |
local mark=spotdot:Clone() | |
mark.Adornee=head | |
mark.Parent=spot | |
mark.Enabled=true | |
mark.Name=v.Name | |
mark.Time.Value=150 | |
local assist=new("Model",mark) | |
assist.Name=spotter | |
end | |
end | |
end | |
end | |
network:add("spotted",function(spottedlist,spotter) | |
for i=1,#spottedlist do | |
local v=spottedlist[i] | |
hud:firespot(v,spotter) | |
end | |
end) | |
network:add("shot",function(shooter,pos) | |
local bars=gamegui:GetChildren() | |
for i = 1, #bars do | |
if bars[i].Name=="Bar" and bars[i].Player.Value==shooter.Name then | |
trash.remove(bars[i]) | |
end | |
end | |
local br=bloodarc:Clone() | |
br.Pos.Value=pos | |
br.Player.Value=shooter.Name | |
br.Parent=gamegui | |
end) | |
function hud:reloadhud() | |
--print("reload hud") | |
pgui =player.PlayerGui | |
maingui =wfc(pgui,"MainGui") | |
gamegui =wfc(maingui,"GameGui") | |
bloodscreen =wfc(gamegui,"BloodScreen") | |
crossframe =wfc(gamegui,"CrossHud") | |
crossparts ={wfc(crossframe,"HR"),wfc(crossframe,"HL"),wfc(crossframe,"VD"),wfc(crossframe,"VU"),} | |
ammofr =wfc(gamegui,"AmmoHud") | |
scopefr =wfc(gamegui,"ScopeFrame") | |
ammotext =wfc(ammofr,"Ammo") | |
magtext =wfc(ammofr,"Mag") | |
healthtext =wfc(ammofr,"Health") | |
fmodetext =wfc(ammofr,"FMode") | |
hitmarker =wfc(gamegui,"Hitmarker") | |
tagfr =wfc(gamegui,"NameTag") | |
radar =wfc(gamegui,"Radar") | |
rme =wfc(radar,"Me") | |
rfolder =wfc(radar,"Folder") | |
nametags ={} | |
dotlist ={} | |
tagfr:ClearAllChildren() | |
rfolder:ClearAllChildren() | |
hud:setscope(false) | |
effects:reload() | |
notify:reset() | |
particle:reset() | |
local bar=ffc(maingui,"KillBar") | |
if bar then trash.remove(bar) end | |
for i=1,50 do | |
local dot=rme:Clone() | |
dot.Parent=rfolder | |
dot.Visible=false | |
dotlist[#dotlist+1]=dot | |
end | |
wait(.1) | |
end | |
function hud.step() | |
updatecross() | |
updateplayernames() | |
updatehealth() | |
hitmarker.ImageTransparency=hud.hitspring.p | |
if run.time>rtime+radarinterval then | |
updateradar() | |
rtime=rtime+radarinterval | |
end | |
if run.time>stime+spotinterval then | |
local sht=spot:GetChildren() | |
for i=1,#sht do | |
local v=sht[i] | |
if rtype(v,"BillboardGui") then | |
if not v.Adornee or v.Time.Value<=0 then | |
trash.remove(v) | |
else | |
v.Time.Value=v.Time.Value-1 | |
end | |
end | |
end | |
stime=stime+spotinterval | |
end | |
end | |
end | |
--notify module | |
--By litozinnamon | |
print("Loading notify module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local ceil =math.ceil | |
local v3 =Vector3.new | |
local color =Color3.new | |
local dot =Vector3.new().Dot | |
local workspace =workspace | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local new =Instance.new | |
local player =game.Players.LocalPlayer | |
local repstore =game.ReplicatedStorage | |
local misc =repstore.Misc | |
local pgui =player.PlayerGui | |
local maingui =wfc(pgui,"MainGui") | |
local gamegui =wfc(maingui,"GameGui") | |
local framelist =wfc(gamegui,"NotifyList") | |
local main =misc.Main | |
local side =misc.Side | |
local killbar =misc.KillBar | |
local typelist = { | |
["kill"] ={"Enemy Killed!",100}, | |
["assist"] ={"Assist!",0}, | |
["assistkill"] ={"Assist Count As Kill!",100}, | |
["head"] ={"Headshot bonus!",25}, | |
["long"] ={"Killed from a distance!",25}, | |
["spot"] ={"Spot Bonus!",25}, | |
["squad"] ={"Squad spawn on you",25}, | |
--game objectives | |
["capture"] ={"Capture!",25}, | |
["defend"] ={"Defended!",15}, | |
--reference | |
[""] ={}, | |
} | |
local function typeout(label,speed) | |
local speed=speed or 2 | |
local text=label.Text | |
label.Text="" | |
spawn(function() | |
for i=1,string.len(text) do | |
label.Text=string.sub(text,1,speed*i) | |
wait(1/60) | |
end | |
end) | |
end | |
local function queuetypeout(label,speed) | |
local speed=speed or 3 | |
local text=label.Text | |
label.Text="" | |
for i=1,string.len(text) do | |
label.Text=string.sub(text,1,speed*i) | |
wait(1/60) | |
end | |
end | |
function smallaward(type,pt) | |
local pt =pt or typelist[type][2] | |
local display =side:Clone() | |
local primary =wfc(display,"Primary") | |
local point =wfc(display,"Point") | |
display.Parent=framelist | |
local fr=framelist:GetChildren() | |
for i=1,#fr do | |
local v=fr[i] | |
if v:IsA("Frame") and v.Parent then | |
v:TweenPosition(ud2(0,0,0,(#fr-i)*20),"Out","Sine",0.05,true) | |
end | |
end | |
spawn(function() | |
point.Text="[+"..pt.."]" | |
primary.Text=typelist[type][1] | |
---initialize | |
point.TextTransparency=0 | |
primary.TextTransparency=0 | |
---animation start | |
typeout(point,3) | |
typeout(primary,3) | |
---co-running animations | |
wait(5.5) | |
for i=1,10 do | |
point.TextTransparency=i/10 | |
primary.TextTransparency=i/10 | |
point.TextStrokeTransparency=i/10+0.4 | |
primary.TextStrokeTransparency=i/10+0.4 | |
wait(1/60) | |
end | |
wait(0.1) | |
trash.remove(display) | |
end) | |
end | |
function bigaward(type,victim,weap) | |
local display =main:Clone() | |
local bk =wfc(display,"Overlay") | |
local primary =wfc(display,"Primary") | |
local point =wfc(display,"Point") | |
local enemy =wfc(display,"Enemy") | |
display.Parent=framelist | |
local fr=framelist:GetChildren() | |
for i=1,#fr do | |
local v=fr[i] | |
if v:IsA("Frame") and v.Parent then | |
v:TweenPosition(ud2(0,0,0,(#fr-i)*20),"Out","Sine",0.05,true) | |
end | |
end | |
spawn(function() | |
point.Text="[+"..typelist[type][2].."]" | |
primary.Text=typelist[type][1] | |
enemy.Text=victim | |
---initialize | |
point.TextTransparency=0 | |
primary.TextTransparency=0 | |
enemy.TextTransparency=1 | |
---animation start | |
bk.ImageTransparency=0.2 | |
bk:TweenSizeAndPosition(ud2(0,200,0,80),ud2(0.5,-150,0.7,-40),"Out","Linear",0,true) | |
typeout(point) | |
typeout(primary) | |
---co-running animations | |
spawn(function() | |
wait(.05) | |
for i=1,10 do | |
bk.ImageTransparency=i/10 | |
wait(0.1) | |
end | |
bk.Size=ud2(0,200,0,80) | |
bk.Position=ud2(0.55,-100,0.3,-40) | |
end) | |
--- | |
bk:TweenSizeAndPosition(ud2(0,300,0,30),ud2(0.5,-150,0.7,-15),"Out","Linear",.05,true) | |
wait(.05) | |
bk:TweenSizeAndPosition(ud2(0,500,0,8),ud2(0.5,-150,0.7,-4),"Out","Linear",.05,true) | |
wait(1.5) | |
for i = 1,2 do | |
primary.TextTransparency=1 | |
wait(.1) | |
primary.TextTransparency=0 | |
wait(.1) | |
end | |
primary.TextTransparency=1 | |
wait(0.2) | |
enemy.TextTransparency=0 | |
queuetypeout(enemy,4) | |
primary.TextTransparency=0 | |
primary.Position=ud2(0.5,enemy.TextBounds.x+10,0.7,-10) | |
primary.Text="["..weap.."]" | |
queuetypeout(primary,4) | |
wait(3) | |
for i=1,10 do | |
point.TextTransparency=i/10 | |
primary.TextTransparency=i/10 | |
enemy.TextTransparency=i/10 | |
point.TextStrokeTransparency=i/10+0.4 | |
primary.TextStrokeTransparency=i/10+0.4 | |
enemy.TextStrokeTransparency=i/10+0.4 | |
wait(1/60) | |
end | |
wait(0.1) | |
trash.remove(display) | |
end) | |
end | |
function notify:reset() | |
maingui=wfc(pgui,"MainGui") | |
gamegui=wfc(maingui,"GameGui") | |
framelist=wfc(gamegui,"NotifyList") | |
if ffc(maingui,"KillBar") then | |
trash.remove(maingui["KillBar"]) | |
end | |
end | |
network:add("killed",function(killer,part,deathcf,weapon) | |
char.deadcf=deathcf | |
if killer==player then | |
camera:setfixedcam(deathcf) | |
else | |
camera:setspectate(killer,part) | |
local newbar=killbar:Clone() | |
newbar.Killer.Label.Text=killer.Name | |
newbar.Weapon.Label.Text=weapon | |
newbar.Parent=maingui | |
end | |
end) | |
network:add("bigaward",function(type,victim,weapon) | |
bigaward(type,victim,weapon) | |
end) | |
network:add("smallaward",function(type,pt) | |
smallaward(type,pt) | |
end) | |
function notify.step() | |
if char.health<=0 then | |
local bar=ffc(maingui,"KillBar") | |
if bar then | |
local enemy=ffc(game.Players,bar.Killer.Label.Text) | |
if enemy then | |
local health=hud:getplayerhealth(enemy) | |
bar.Health.Label.Text=ceil(health) | |
bar.Health.Label.TextColor3=health<20 and color(1,0,0) or health<50 and color(1,1,0) or color(0,1,0) | |
end | |
end | |
end | |
end | |
end | |
--leaderboard module | |
--By litozinnamon | |
print("Loading leaderboard module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local ceil =math.ceil | |
local cf =CFrame.new | |
local v3 =Vector3.new | |
local color =Color3.new | |
local dot =Vector3.new().Dot | |
local workspace =workspace | |
local ray =Ray.new | |
local new =Instance.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local infolder =function(l,e) for i=1,#l do if l[i].Name==e then return l[i] end end end | |
local rtype =game.IsA | |
local debris =game.Debris | |
local player =game.Players.LocalPlayer | |
local playertag =game.ReplicatedStorage.Character.PlayerTag | |
local pgui =player.PlayerGui | |
local misc =game.ReplicatedStorage.Misc | |
local playerstat =misc.Player | |
local board =wfc(pgui,"Leaderboard") | |
local main =wfc(board,"Main") | |
local global =wfc(board,"Global") | |
local ghost =wfc(main,"Ghosts") | |
local phantom =wfc(main,"Phantoms") | |
local ghostdata =wfc(wfc(ghost,"DataFrame"),"Data") | |
local phantomdata =wfc(wfc(phantom,"DataFrame"),"Data") | |
function addplayer(guy) | |
local gbar=ffc(ghostdata,guy.Name) | |
local pbar=ffc(phantomdata,guy.Name) | |
if gbar or pbar then return end | |
local bar=playerstat:Clone() | |
bar.Name=guy.Name | |
bar.Username.Text=guy.Name | |
bar.Kills.Text=0 | |
bar.Deaths.Text=0 | |
bar.Streak.Text=0 | |
bar.Score.Text=0 | |
bar.Kdr.Text=0 | |
bar.Rank.Text=0 | |
if guy==player then | |
bar.Username.TextColor3=color(1,1,0) | |
end | |
bar.Parent=guy.TeamColor==game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
organize() | |
end | |
function removeplayer(guy) | |
local gbar=ffc(ghostdata,guy.Name) | |
local pbar=ffc(phantomdata,guy.Name) | |
if gbar then trash.remove(gbar) end | |
if pbar then trash.remove(pbar) end | |
organize() | |
end | |
function organize() | |
---check players in right teams | |
--[[local pp=game.Players:GetChildren() | |
for i=1,#pp do | |
local v=pp[i] | |
local rightparent=v.TeamColor==game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
local wrongparent=v.TeamColor~=game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
local right=ffc(rightparent,v.Name) | |
local wrong=ffc(wrongparent,v.Name) | |
if not right and wrong then | |
wrong.Parent=rightparent | |
end | |
end]] | |
---reposition and check nonexistent players | |
local gd=ghostdata:GetChildren() | |
for i=1,#gd do | |
local v=gd[i] | |
v.Position=ud2(0,0,0,i*25) | |
if v.Name==player.Name then v.Username.TextColor3=color(1,1,0) end | |
end | |
ghostdata.Parent.CanvasSize=ud2(0,0,0,(#gd+1)*25) | |
local pd=phantomdata:GetChildren() | |
for i=1,#pd do | |
local v=pd[i] | |
v.Position=ud2(0,0,0,i*25) | |
if v.Name==player.Name then v.Username.TextColor3=color(1,1,0) end | |
end | |
phantomdata.Parent.CanvasSize=ud2(0,0,0,(#pd+1)*25) | |
end | |
function updatestats(guy,data) | |
local rightparent=guy.TeamColor==game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
local bar=ffc(rightparent,guy.Name) | |
if bar then | |
for i,v in next,data do | |
bar[i].Text=v | |
end | |
end | |
end | |
function leaderboard:show() | |
main.Visible=true | |
end | |
function leaderboard:hide() | |
main.Visible=false | |
end | |
network:add("removeplayer",removeplayer) | |
network:add("newplayer",addplayer) | |
network:add("updatestats",updatestats) | |
organize() | |
game:GetService("UserInputService").InputBegan:connect(function(keycode) | |
local key=keycode.KeyCode | |
if key==Enum.KeyCode.Tab and not input.keyboard.down["LeftAlt"] then | |
if main.Visible then | |
leaderboard:hide() | |
else | |
leaderboard:show() | |
end | |
end | |
end) | |
end | |
--char module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading char module") | |
do | |
local rtype =game.IsA | |
local next =next | |
local new =Instance.new | |
local wfc =game.WaitForChild | |
local getchildren =game.GetChildren | |
local workspace =game.Workspace | |
local cf =CFrame.new | |
local vtws =CFrame.new().vectorToWorldSpace | |
local angles =CFrame.Angles | |
local nc =cf() | |
local v3 =Vector3.new | |
local nv =v3() | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local debris =game.Debris | |
local dot =nv.Dot | |
local player =game.Players.LocalPlayer | |
local repchar =game.ReplicatedStorage.Character | |
local character | |
local humanoid | |
local rootpart | |
local rootjoint | |
local statsloaded | |
--Randomass shit | |
local thread =sequencer.new() | |
local weapon =nil | |
local aiming =false | |
local auto =false | |
local burst =0 | |
local reloading =false | |
local sprinting =false | |
local animating =false | |
local stability =0 | |
local sprintspring =physics.spring.new() | |
local aimspring =physics.spring.new() | |
local swingspring =physics.spring.new(nv) | |
local speedspring =physics.spring.new() | |
local velocityspring =physics.spring.new(nv) | |
local pronespring =physics.spring.new(0) | |
local truespeedspring =physics.spring.new(0) | |
local walkspeedmult =1 | |
sprintspring.s =12 | |
sprintspring.d =0.9 | |
aimspring.d =0.9 | |
swingspring.s =10 | |
swingspring.d =0.75 | |
speedspring.s =16 | |
velocityspring.s =16 | |
pronespring.s =8 | |
truespeedspring.s =8 | |
--MOVEMENT MODULE LOLOLOL | |
local backwardsmult =0.8 | |
local ignore ={workspace.CurrentCamera} | |
local bodyforce =new("BodyForce") | |
local walkspeedspring | |
local headheightspring | |
local updatewalkspeed | |
bodyforce.force =nv | |
do | |
--local raycast =function(r,i) return rayignore(workspace,r,i) end | |
local movementmode ="stand" | |
local basewalkspeed =14--arb | |
local down =v3(0,-4,0)--arb | |
local standcf =nc | |
local crouchcf =cf(0,-1.5,0)--arb | |
local pronecf =cf(0,-1.5,1.5,1,0,0,0,0,1,0,-1,0)--arb | |
walkspeedspring =physics.spring.new(basewalkspeed) | |
walkspeedspring.s =8--arb | |
headheightspring =physics.spring.new(1.5) | |
headheightspring.s =8--arb | |
function updatewalkspeed() | |
if sprinting then | |
walkspeedspring.t=1.4*walkspeedmult*basewalkspeed | |
elseif movementmode=="prone" then | |
walkspeedspring.t=walkspeedmult*basewalkspeed/4--arb | |
elseif movementmode=="crouch" then | |
walkspeedspring.t=walkspeedmult*basewalkspeed/2--arb | |
elseif movementmode=="stand" then | |
walkspeedspring.t=walkspeedmult*basewalkspeed | |
end | |
end | |
local function setmovementmode(self,mode,dive) | |
char.movementmode=mode | |
movementmode=mode | |
if mode=="prone" then | |
headheightspring.t=-1.5--arb | |
rootjoint.C0=pronecf | |
pronespring.t=1 | |
walkspeedspring.t=walkspeedmult*basewalkspeed/4--arb | |
hud:setcrossscale(0.5) | |
stability=0.4 | |
if dive and sprinting and humanoid:GetState()~=Enum.HumanoidStateType.Freefall then | |
spawn(function() | |
rootpart.Velocity=rootpart.CFrame.lookVector*60+v3(0,40,0) | |
wait(.1) | |
rootpart.Velocity=rootpart.CFrame.lookVector*70+v3(0,30,0) | |
wait(.4) | |
rootpart.Velocity=rootpart.CFrame.lookVector*30+v3(0,-10,0) | |
end) | |
end | |
elseif mode=="crouch" then | |
headheightspring.t=0--arb | |
rootjoint.C0=crouchcf | |
pronespring.t=0 | |
walkspeedspring.t=walkspeedmult*basewalkspeed/2--arb | |
hud:setcrossscale(0.75) | |
stability=0.2 | |
if dive and sprinting and humanoid:GetState()~=Enum.HumanoidStateType.Freefall then | |
spawn(function() | |
for i = 1, 5 do | |
rootpart.Velocity = rootpart.CFrame.lookVector*50+v3(0,0,0) | |
wait(.08) | |
end | |
end) | |
end | |
elseif mode=="stand" then | |
headheightspring.t=1.5--arb | |
rootjoint.C0=standcf | |
pronespring.t=0 | |
walkspeedspring.t=walkspeedmult*basewalkspeed | |
hud:setcrossscale(1) | |
stability=0 | |
end | |
network:bounce("stance",player,mode) | |
sprinting=false | |
network:bounce("sprint",player,sprinting) | |
sprintspring.t=0 | |
end | |
function char:sprinting() | |
return sprinting | |
end | |
char.setmovementmode=setmovementmode | |
function char:setsprint(on) | |
if on then | |
setmovementmode(nil,"stand") | |
sprinting=true | |
network:bounce("sprint",player,sprinting) | |
auto=false | |
burst=0 | |
if weapon and aiming and weapon.type~="Knife" then | |
weapon:setaim(false) | |
end | |
walkspeedmult=1 | |
if not reloading and not animating then | |
sprintspring.t=1 | |
end | |
walkspeedspring.t=1.5*walkspeedmult*basewalkspeed--arb | |
elseif sprinting then | |
sprinting=false | |
network:bounce("sprint",player,sprinting) | |
sprintspring.t=0 | |
walkspeedspring.t=walkspeedmult*basewalkspeed | |
end | |
end | |
local function parkour() | |
if weapon then | |
weapon:playanimation("parkour") | |
end | |
local bp=new("BodyPosition",rootpart) | |
bp.position=rootpart.Position+rootpart.CFrame.lookVector.unit*char.speed/1.5+v3(0,5,0) | |
bp.maxForce=v3(5000000, 5000000, 5000000) | |
bp.P=4000 | |
debris:AddItem(bp,0.45) | |
end | |
function char:jump(height) | |
local rootcf=rootpart.CFrame | |
if raycast(workspace,ray(rootcf.p,vtws(rootcf,down)),ignore) then | |
if movementmode=="prone" or movementmode=="crouch" then | |
setmovementmode(nil,"stand") | |
else | |
if not reloading and not aiming and not char.grenadehold then | |
local r1=ray(rootpart.CFrame.p+v3(0,1.5,0),rootpart.CFrame.lookVector*25+v3(0,2,0)) | |
local h1,e1=raycast(workspace,r1,{character,camera.currentcamera}) | |
local r2=ray(rootpart.CFrame.p-v3(0,.8,0),(rootpart.CFrame.lookVector)*25-v3(0,.8,0)) | |
local h2,e2=raycast(workspace,r2,{character,camera.currentcamera}) | |
local r3=ray(rootpart.CFrame.p-v3(0,1.2,0),(rootpart.CFrame.lookVector)*25-v3(0,1.2,0)) | |
local h3,e3=raycast(workspace,r3,{character,camera.currentcamera}) | |
if h3 and (e3-e2).Magnitude<0.7 and (e3-e1).Magnitude>4 and (e3-rootpart.Position).Magnitude<char.speed/2 then | |
parkour(h3) | |
else | |
rootpart.Velocity=rootpart.Velocity+v3(0,height and (392.4*height)^0.5 or 40,0) | |
end | |
else | |
rootpart.Velocity=rootpart.Velocity+v3(0,height and (392.4*height)^0.5 or 40,0) | |
end | |
end | |
end | |
end | |
end | |
--WEAPONS MODULE LEL | |
--Add dynamic animation shit | |
--Inspection | |
--Spotting | |
local equipping =false | |
local zooming =false | |
local rweld =new("Motor6D") | |
local lweld =new("Motor6D") | |
local larm | |
local rarm | |
local lmodel | |
local rmodel | |
local lmain | |
local rmain | |
local sin=math.sin | |
local cos=math.cos | |
char.grenadehold=false | |
local function gunbob(a,r) | |
local a,r=a or 1,r or 1 | |
local d,s,v=char.distance*6.28318*3/4,char.speed,-char.velocity | |
local w=v3(r*sin(d/4-1)/256+r*(sin(d/64)-r*v.z/4)/512,r*cos(d/128)/128-r*cos(d/8)/256,r*sin(d/8)/128+r*v.x/1024)*s/20*6.28318 | |
return cf(r*cos(d/8-1)*s/196,1.25*a*sin(d/4)*s/512,0)*cframe.fromaxisangle(w) | |
end | |
local function gunsway(a) | |
local d,s=tick()*6,2*(1.2-a) | |
return cf(cos(d/8)*s/128,-sin(d/4)*s/128,sin(d/16)*s/64) | |
end | |
local tos=CFrame.new().toObjectSpace | |
local function weldmodel(model,mainpart) | |
local welddata={} | |
local parts=getchildren(model) | |
local maincf=mainpart.CFrame | |
for i=1,#parts do | |
local part=parts[i] | |
if part~=mainpart then | |
local name=part.Name | |
local c0=tos(maincf,part.CFrame) | |
local weld=new("Motor6D",mainpart) | |
weld.Part0=mainpart | |
weld.Part1=part | |
weld.C0=c0 | |
welddata[name]={ | |
part=part; | |
weld=weld; | |
basec0=c0; | |
basetransparency=part.Transparency; | |
} | |
part.Anchored=false | |
part.CanCollide=false | |
end | |
end | |
mainpart.Anchored=false | |
mainpart.CanCollide=false | |
return welddata | |
end | |
local clone =game.Clone | |
local currentcamera =game.Workspace.CurrentCamera | |
local ffc =game.FindFirstChild | |
function char:loadarms(newlarm,newrarm,newlmain,newrmain) | |
larm,rarm,lmain,rmain=newlarm,newrarm,newlmain,newrmain | |
lmodel=clone(larm,weapon and currentcamera) | |
rmodel=clone(rarm,weapon and currentcamera) | |
local lmainpart=lmodel[newlmain] | |
local rmainpart=rmodel[newrmain] | |
weldmodel(lmodel,lmainpart) | |
weldmodel(rmodel,rmainpart) | |
lweld.Part0=rootpart | |
lweld.Part1=lmainpart | |
lweld.Parent=lmainpart | |
rweld.Part0=rootpart | |
rweld.Part1=rmainpart | |
rweld.Parent=rmainpart | |
end | |
--BULLSHIT BULLSHIT | |
local aimbotshit={} | |
do | |
local equipspring =physics.spring.new(1) | |
equipspring.s =12--arb | |
equipspring.d =0.75--arb | |
local function reweld(welddata) | |
for i,v in next,welddata do | |
if v.clone then | |
welddata[i]=nil | |
trash.remove(v.weld) | |
trash.remove(v.part) | |
else | |
v.weld.C0=v.basec0 | |
if v.part then | |
v.part.Transparency=v.basetransparency | |
end | |
end | |
end | |
end | |
local rand=math.random | |
local ffc=game.FindFirstChild | |
local function pickv3(v0,v1) | |
return v0+v3(rand(),rand(),rand())*(v1-v0) | |
end | |
function char:loadgrenade(data,model) | |
local self ={} | |
--network:bounce("load",player,data.name) | |
local thread2 =sequencer.new() | |
local ignorelist ={camera.currentcamera,character,workspace.Ignore} | |
local dunhit ={} | |
--General things I guess. | |
local main =data.mainpart | |
local mainoffset =data.mainoffset | |
local mainpart =model[main] | |
local pin =model[data.pin] | |
local lever =model[data.lever] | |
local lastweapon =weapon | |
local equipped =false | |
local throwing =false | |
local cooking =false | |
local exploded =false | |
local bounceelasticity =0.2 | |
local acceleration =v3(0,-80,0) | |
local velocity =v3() | |
local position =v3() | |
local cooktime =0 | |
local blowup =0 | |
local t0 =0 | |
local lastbounce =false | |
local lasttrailt =0 | |
local lasttrailpos =v3() | |
local rot0 | |
local offset =v3() | |
local av0 | |
local flyingnade | |
--grenade explode stuff | |
local fusetime =data.fusetime | |
local blastradius =data.blastradius | |
local throwspeed =data.throwspeed | |
local r0,r1,d0,d1 =data.range0,data.range1,data.damage0,data.damage1 | |
--Static animation data stuff | |
local animdata =weldmodel(model,mainpart) | |
local mainweld =new("Motor6D",mainpart) | |
animdata[main] ={weld={C0=nc},basec0=nc} | |
animdata.larm ={weld={C0=data.larmoffset},basec0=data.larmoffset} | |
animdata.rarm ={weld={C0=data.rarmoffset},basec0=data.rarmoffset} | |
mainweld.Part0 =rootpart | |
mainweld.Part1 =mainpart | |
--Dynamic animation stuff OMG prepare for flood | |
local equipcf =data.equipoffset | |
local sprintcf =cframe.interpolator(data.sprintoffset) | |
local pronecf =cframe.interpolator(data.proneoffset) | |
self.type =data.type | |
self.cooking =cooking | |
function self:setequipped(on) | |
if on and (not equipped or not equipping) then | |
if char.health<=0 then return end | |
aimbotshit.speed=throwspeed | |
aimbotshit.accel=acceleration | |
aimbotshit.addv=true | |
char.grenadehold=true | |
hud:setcrosssettings(data.crosssize,data.crossspeed,data.crossdamper,main) | |
hud:updatefiremode("knife") | |
hud:updateammo("knife") | |
equipping=true | |
thread:clear() | |
if weapon then | |
lastweapon=weapon | |
weapon:setequipped(false) | |
end | |
thread:add(function() | |
equipspring.t=0 | |
equipping=false | |
equipped=true | |
lmodel.Parent=currentcamera | |
rmodel.Parent=currentcamera | |
model.Parent=currentcamera | |
weapon=self | |
reweld(animdata) | |
--if sprinting then char:setsprint(false) end | |
end) | |
elseif not on and equipped then | |
--Set equipped to false here? | |
equipspring.t=1 | |
thread:clear()--I don't think this should be here. | |
thread:add(function() | |
equipped=false | |
lmodel.Parent=nil | |
rmodel.Parent=nil | |
model.Parent=nil | |
animating=false | |
weapon=nil | |
end) | |
thread:delay(0.5)--arb | |
end | |
end | |
local function createnade() | |
---need to add network cloning fake nade | |
local time=tick() | |
trash.remove(mainweld) | |
flyingnade=mainpart | |
flyingnade.Parent=camera.currentcamera | |
flyingnade.Anchored=true | |
model.Parent=nil | |
velocity=char.health>0 and camera.lookvector*throwspeed+rootpart.Velocity or v3() | |
position=char.deadcf and char.deadcf.p or flyingnade.CFrame.p | |
lasttrailt=time | |
lasttrailpos=position | |
t0=time | |
av0=(camera.cframe-camera.cframe.p)*v3(19.539,-5.0,0) | |
rot0=flyingnade.CFrame-flyingnade.CFrame.p | |
network:bounce("newgrenade",player,data.name,position,velocity,acceleration,bounceelasticity,t0,av0,rot0,blowup-tick()) | |
end | |
function self:throw(dpos) | |
---do grenade stuff | |
if cooking and not throwing then | |
local time=tick() | |
throwing=true | |
cooking=false | |
self.cooking=cooking | |
exploded=false | |
sprintspring.t=0 | |
thread:add(animation.player(animdata,data.animations.throw)) | |
thread2:delay(0.07) | |
thread2:add(function() | |
createnade(dpos) | |
if sprinting then sprintspring.t=1 end | |
throwing=false | |
end) | |
thread:add(function() | |
if lastweapon then | |
lastweapon:setequipped(true) | |
end | |
end) | |
end | |
end | |
function self:pull() | |
local time=tick() | |
if not cooking and not throwing then | |
if animating then | |
thread:add(animation.reset(animdata,0.1)) | |
animating=false | |
end | |
thread:add(animation.player(animdata,data.animations.pull)) | |
thread:add(function() | |
hud.crossspring:accelerate(data.crossexpansion) | |
trash.remove(pin) | |
cooking=true | |
self.cooking=cooking | |
cooktime=time+fusetime | |
blowup=time+5 | |
end) | |
end | |
end | |
local function hitdetection(hit,dist) | |
---damage code | |
if ffc(hit.Parent,"Humanoid") and not dunhit[hit.Parent] and game.Players:FindFirstChild(hit.Parent.Name) then | |
local p=game.Players:GetPlayerFromCharacter(hit.Parent) | |
if p.TeamColor~=player.TeamColor or p==player then | |
local wall,pos=raycast(workspace,ray(hit.Position,(hit.Position-position).unit*-dist),ignorelist) | |
if not wall then | |
effects:bloodhit(position,hit,hit.Position,hit.CFrame.lookVector) | |
local damage=dist<r0 and d0 or dist<r1 and (d1-d0)/(r1-r0)*(dist-r0)+d0 or d1 | |
--print("damage : " ..damage.. " dist : " ..dist.. " wall : ",wall) | |
network:send("changehealth",p,-damage,player,data.name,hit,position) | |
dunhit[hit.Parent]=true | |
hud:firehitmarker() | |
end | |
end | |
end | |
end | |
local function explode() | |
exploded=true | |
trash.remove(flyingnade) | |
dunhit={} | |
if data.grenadetype=="Frag" then | |
---need to add network stuff later | |
local boom=new("Explosion",workspace) | |
boom.Position=position | |
boom.BlastRadius=blastradius | |
boom.BlastPressure=0 | |
boom.DestroyJointRadiusPercent=0 | |
boom.Hit:connect(function(hit,dist) | |
hitdetection(hit,dist) | |
end) | |
elseif data.grenadetype=="Smoke" then | |
--- smoke | |
elseif data.grenadetype=="Flash" then | |
--- blind | |
elseif data.grenadetype=="Flare" then | |
--- signal | |
elseif data.grenadetype=="Throwing" then | |
--- flying knives wat | |
end | |
end | |
run.onstep:connect(function(dt) | |
thread2.step() | |
local time=tick() | |
--cooking stuff | |
if cooking and not throwing then | |
if cooktime<time or not input.keyboard.down["g"] then | |
self:throw() | |
elseif (cooktime-time)%1<0.03 then | |
hud.crossspring:accelerate(data.crossexpansion) | |
end | |
end | |
--grenade throwing physics | |
if flyingnade and not exploded then | |
if time<blowup then | |
local newvelocity=velocity+dt*acceleration | |
local newposition=position+dt*velocity | |
local hit,pos,norm=raycast(workspace,ray(position,newposition-position),ignorelist) | |
local t=tick()-t0 | |
if hit and hit.Name~="Window" then | |
rot0=flyingnade.CFrame-flyingnade.CFrame.p | |
offset=0.2*norm | |
t0=tick() | |
av0=norm:Cross(velocity)/0.2 | |
position=pos+norm*0.001 | |
local normvel=dot(norm,velocity)*norm | |
local tanvel=velocity-normvel | |
local friction | |
if lastbounce then | |
friction=1-0.08*acceleration.magnitude*dt/tanvel.magnitude | |
else | |
friction=1-0.08*(acceleration.magnitude+(1+bounceelasticity)*normvel.magnitude)/tanvel.magnitude | |
end | |
velocity=tanvel*(friction<0 and 0 or friction)-bounceelasticity*normvel | |
lastbounce=true | |
else | |
position=newposition | |
velocity=newvelocity | |
lastbounce=false | |
if hit and hit.Name=="Window" then | |
effects:breakwindow(hit,pos,norm,true) | |
end | |
end | |
if lasttrailt+0.05<time then | |
local trail=new("Part",camera.currentcamera) | |
trail.BrickColor=BrickColor.new("Medium stone grey") | |
trail.Transparency=0.7 | |
trail.Anchored=true | |
trail.CanCollide=false | |
trail.FormFactor="Custom" | |
trail.Size=v3(0.2,0.2,0.2) | |
trail.CFrame=cf((lasttrailpos+position)*0.5,position) | |
local mesh=new("BlockMesh",trail) | |
mesh.Scale=v3(0.6,0.6,(lasttrailpos-position).Magnitude*5) | |
debris:AddItem(trail,1) | |
lasttrailpos=position | |
lasttrailt=time | |
end | |
flyingnade.CFrame=cf(position+offset)*cframe.fromaxisangle(t*av0)*rot0 | |
else | |
explode() | |
end | |
end | |
end) | |
function self.step() | |
--Animate grenade arms | |
local mainweldc0=rootpart.CFrame:inverse() | |
*workspace.CurrentCamera.CoordinateFrame--opti | |
*mainoffset*animdata[main].weld.C0 | |
--*breathing() | |
*pronecf(pronespring.p) | |
--*cf(-velocityspring.v/8192) | |
*cf(0,0,1)*cframe.fromaxisangle(swingspring.v)*cf(0,0,-1) | |
*gunbob(0.7,1) | |
*gunsway(0) | |
*cframe.interpolate(sprintcf(truespeedspring.p/walkspeedspring.p*sprintspring.p),data.equipoffset,equipspring.p) | |
mainweld.C0=mainweldc0 | |
--Animate arms | |
lweld.C0=mainweldc0*animdata.larm.weld.C0 | |
rweld.C0=mainweldc0*animdata.rarm.weld.C0 | |
if char.health<=0 then | |
self:setequipped(false) | |
end | |
end | |
return self | |
end | |
function char:loadknife(data,model) | |
local self={} | |
--network:bounce("load",player,data.name) | |
local thread2 =sequencer.new()--LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL | |
local ignorelist ={camera.currentcamera,character,workspace.Ignore} | |
local dunhit ={} | |
--General things I guess. | |
local main =data.mainpart | |
local mainoffset =data.mainoffset | |
local mainpart =model[main] | |
local tip =model[data.tip] | |
local equipped =false | |
local knifing =false | |
local nexthit =0 | |
--stab stuff | |
local stabrate =1000 | |
local r0,r1,d0,d1 =data.range0,data.range1,data.damage0,data.damage1 | |
--Static animation data stuff | |
local animdata =weldmodel(model,mainpart) | |
local mainweld =new("Motor6D",mainpart) | |
animdata[main] ={weld={C0=nc},basec0=nc} | |
animdata.larm ={weld={C0=data.larmoffset},basec0=data.larmoffset} | |
animdata.rarm ={weld={C0=data.rarmoffset},basec0=data.rarmoffset} | |
mainweld.Part0 =rootpart | |
mainweld.Part1 =mainpart | |
--Dynamic animation stuff OMG prepare for flood | |
local equipcf =data.equipoffset | |
local sprintcf =cframe.interpolator(data.sprintoffset) | |
local pronecf =cframe.interpolator(data.proneoffset) | |
self.type =data.type | |
function self:setequipped(on) | |
if on and (not equipped or not equipping) then | |
if char.health<=0 then return end | |
network:bounce("equipknife",player,data.name) | |
hud:setcrosssettings(data.crosssize,data.crossspeed,data.crossdamper,main) | |
hud:updatefiremode("knife") | |
hud:updateammo("knife") | |
equipping=true | |
thread:clear() | |
if weapon then | |
weapon:setequipped(false) | |
end | |
thread:add(function() | |
sprintspring.s=data.sprintspeed | |
hud:setcrosssize(data.crosssize) | |
lmodel.Parent=currentcamera | |
rmodel.Parent=currentcamera | |
equipspring.t=0 | |
reweld(animdata) | |
equipped=true | |
weapon=self | |
model.Parent=currentcamera | |
equipping=false | |
knifing=false | |
char.grenadehold=false | |
if sprinting then sprintspring.t=1 end | |
end) | |
elseif not on and equipped then | |
--Set equipped to false here? | |
knifing=false | |
equipspring.t=1 | |
thread:clear()--I don't think this should be here. | |
thread:add(animation.reset(animdata,0.2))--arb | |
thread:add(function() | |
equipped=false | |
lmodel.Parent=nil | |
rmodel.Parent=nil | |
model.Parent=nil | |
animating=false | |
weapon=nil | |
end) | |
end | |
end | |
function self:playanimation(type) | |
if not knifing and not equipping then | |
thread:clear() | |
if animating then | |
thread:add(animation.reset(animdata,0.05)) | |
end | |
animating=true | |
sprintspring.t=0 | |
thread:add(animation.player(animdata,data.animations[type])) | |
thread:add(function() | |
thread:add(animation.reset(animdata,data.animations[type].resettime)) | |
animating=false | |
thread:add(function() | |
if sprinting then sprintspring.t=1 end | |
end) | |
if type=="spot" then | |
local acceptlist={} | |
local pp=game.Players:GetChildren() | |
for i=1,#pp do | |
local v=pp[i] | |
if v.TeamColor~=player.TeamColor and hud:getplayervisible(v) then | |
acceptlist[#acceptlist+1]=v | |
hud:firespot(v) | |
end | |
end | |
network:send("spotting",player,acceptlist) | |
end | |
end) | |
end | |
end | |
function self:shoot(on) | |
---do knife stuff | |
if not knifing then | |
local time=tick() | |
network:bounce("stab",player) | |
nexthit=nexthit>time and nexthit or time | |
sprintspring.t=0 | |
knifing=true | |
if animating then | |
thread:add(animation.reset(animdata,0.1)) | |
animating=false | |
end | |
local type="stab1" | |
thread:add(animation.player(animdata,data.animations[type])) | |
thread:add(function() | |
thread:add(animation.reset(animdata,data.animations[type].resettime)) | |
if sprinting then sprintspring.t=1 end | |
knifing=false | |
dunhit={} | |
end) | |
end | |
end | |
local function hitdetection(hit,pos,norm) | |
---damage code | |
if ffc(hit.Parent,"Humanoid") and ffc(hit.Parent,"Torso") and not dunhit[hit.Parent] and game.Players:FindFirstChild(hit.Parent.Name) then | |
local p=game.Players:GetPlayerFromCharacter(hit.Parent) | |
if p.TeamColor~=player.TeamColor then | |
effects:bloodhit(rootpart.Position,hit,pos,norm) | |
local ptorso=hit.Parent.Torso | |
local damage=(dot(ptorso.CFrame.lookVector,(ptorso.Position-rootpart.Position).unit)*0.5+0.5)*(d1-d0)+d0 | |
--print("damage : " ..damage) | |
network:send("changehealth",p,-damage,player,data.name,hit,mainpart.Position) | |
dunhit[hit.Parent]=true | |
hud:firehitmarker() | |
end | |
else | |
if hit.Name=="Window" then | |
effects:breakwindow(hit,pos,norm) | |
else | |
effects:bullethit(hit,pos,norm,true) | |
end | |
end | |
end | |
function self.step() | |
local time=tick() | |
--knife hit detection | |
if knifing and time>=nexthit then | |
local scan=ray(tip.CFrame.p,tip.CFrame.lookVector*5) | |
local hit,pos,norm=raycast(workspace,scan,ignorelist) | |
if hit then | |
hitdetection(hit,pos,norm) | |
end | |
nexthit=nexthit+60/stabrate | |
end | |
--Animate gun | |
local mainweldc0=rootpart.CFrame:inverse() | |
*workspace.CurrentCamera.CoordinateFrame--opti | |
*mainoffset*animdata[main].weld.C0 | |
--*breathing() | |
*pronecf(pronespring.p) | |
--*cf(-velocityspring.v/8192) | |
*cf(0,0,1)*cframe.fromaxisangle(swingspring.v)*cf(0,0,-1) | |
*gunbob(0.7,1) | |
*gunsway(0) | |
*cframe.interpolate(sprintcf(truespeedspring.p/walkspeedspring.p*sprintspring.p),data.equipoffset,equipspring.p) | |
mainweld.C0=mainweldc0 | |
--Animate arms | |
lweld.C0=mainweldc0*cframe.interpolate(animdata.larm.weld.C0,data.larmsprintoffset,truespeedspring.p/walkspeedspring.p*sprintspring.p) | |
rweld.C0=mainweldc0*cframe.interpolate(animdata.rarm.weld.C0,data.rarmsprintoffset,truespeedspring.p/walkspeedspring.p*sprintspring.p) | |
thread2:step() | |
if char.health<=0 then | |
self:setequipped(false) | |
end | |
end | |
return self | |
end | |
function char:loadgun(data,model,mag,sparerounds) | |
local self={} | |
--network:bounce("load",player,data.name) | |
local thread2 =sequencer.new()--LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOL | |
--General things I guess. | |
local main =data.mainpart | |
local mainoffset =data.mainoffset | |
local mainpart =model[main] | |
local equipped =false | |
local yieldtoanimation =false | |
local barrel =model[data.barrel] | |
local sight =model[data.sight] | |
local barreloffset =data.barreloffset | |
--shooting stuff | |
local firerate =data.variablefirerate and data.firerate[1] or data.firerate | |
local firemodes =data.firemodes | |
local firemode =1 | |
local spare =(sparerounds or data.sparerounds)*100--fix | |
local chamber =data.chamber | |
local magsize =data.magsize | |
local mag =chamber and mag and mag+1 or mag or magsize | |
local nextshot =0 | |
local r0,r1,d0,d1 =data.range0,data.range1,data.damage0,data.damage1 | |
local firesound =barrel.Fire--fix | |
firesound.SoundId =data.firesoundid | |
firesound.Pitch =data.firepitch | |
firesound.Volume =data.firevolume | |
local firesoundlist ={} | |
--Static animation data stuff | |
local animdata =weldmodel(model,mainpart) | |
local mainweld =new("Motor6D",mainpart) | |
animdata[main] ={weld={C0=nc},basec0=nc} | |
animdata.larm ={weld={C0=data.larmoffset},basec0=data.larmoffset} | |
animdata.rarm ={weld={C0=data.rarmoffset},basec0=data.rarmoffset} | |
mainweld.Part0 =rootpart | |
mainweld.Part1 =mainpart | |
--Dynamic animation stuff OMG prepare for flood | |
local equipcf =data.equipoffset | |
local sprintcf =cframe.interpolator(data.sprintoffset) | |
local pronecf =cframe.interpolator(data.proneoffset) | |
local aimcf =cframe.interpolator(data.aimoffset) | |
local boltcf =cframe.interpolator(animdata[data.bolt].basec0,animdata[data.bolt].basec0*data.boltoffset) | |
local transkickspring =physics.spring.new(nv) | |
local rotkickspring =physics.spring.new(nv) | |
local spreadspring =physics.spring.new(nv) | |
transkickspring.s =data.modelkickspeed | |
rotkickspring.s =data.modelkickspeed | |
transkickspring.d =data.modelkickdamper | |
rotkickspring.d =data.modelkickdamper | |
spreadspring.s =data.hipfirespreadrecover | |
spreadspring.d =0.7 | |
self.type =data.type | |
function self:setequipped(on,dead) | |
if dead then self:hide() end | |
if on and (not equipped or not equipping) then | |
if char.health<=0 then return end | |
aimbotshit.speed=data.bulletspeed | |
aimbotshit.accel=v3(0,-50,0) | |
aimbotshit.addv=false | |
network:bounce("equip",player,data.name) | |
hud:setcrosssettings(data.crosssize,data.crossspeed,data.crossdamper,sight) | |
hud:updatefiremode(firemodes[firemode]) | |
hud:updateammo(mag,spare) | |
self:setaim(false) | |
equipping=true | |
reloading=false | |
thread:clear() | |
if weapon then | |
weapon:setequipped(false) | |
end | |
thread:add(function() | |
aimspring.s=data.aimspeed | |
sprintspring.s=data.sprintspeed | |
camera.magspring.s=data.magnifyspeed | |
camera.shakespring.s=data.camkickspeed | |
hud:setcrosssize(data.crosssize) | |
aimspring.s=data.aimspeed | |
lmodel.Parent=currentcamera | |
rmodel.Parent=currentcamera | |
equipspring.t=0 | |
reweld(animdata) | |
equipped=true | |
weapon=self | |
model.Parent=currentcamera | |
equipping=false | |
if sprinting then | |
sprintspring.t=1 | |
end | |
if input.mouse.down["right"] then | |
self:setaim(true) | |
end | |
char.grenadehold=false | |
end) | |
elseif not on and equipped then | |
--Set equipped to false here? | |
if aiming then | |
self:setaim(false) | |
end | |
auto=false | |
burst=0 | |
reloading=false | |
equipspring.t=1 | |
thread:clear()--I don't think this should be here. | |
thread:add(animation.reset(animdata,0.2))--arb | |
thread:add(function() | |
equipped=false | |
lmodel.Parent=nil | |
rmodel.Parent=nil | |
model.Parent=nil | |
animating=false | |
yieldtoanimation=false | |
weapon=nil | |
end) | |
end | |
end | |
function texturetransparency(part,trans) | |
local p=part:GetChildren() | |
for i=1,#p do | |
local v=p[i] | |
if v.Name == "Texture" then | |
v.Transparency = trans | |
end | |
end | |
end | |
function self:hide() | |
local p=model:GetChildren() | |
for i=1,#p do | |
local v=p[i] | |
if v:IsA("UnionOperation") then | |
v.Transparency=1 | |
if ffc(v,"Texture") then | |
texturetransparency(v,1) | |
end | |
end | |
end | |
end | |
function self:show() | |
local p=model:GetChildren() | |
for i=1,#p do | |
local v=p[i] | |
if v:IsA("UnionOperation") then | |
v.Transparency=0 | |
if ffc(v,"Texture") then | |
texturetransparency(v,0) | |
end | |
end | |
end | |
end | |
function self:setaim(on) | |
if reloading or not equipped then return end | |
if on then | |
aiming=true | |
network:bounce("aim",player,true) | |
sprinting=false | |
sprintspring.t=0 | |
network:bounce("sprint",player,sprinting) | |
walkspeedmult=data.aimwalkspeedmult | |
camera.shakespring.s=data.aimcamkickspeed | |
hud:setcrosssize(0) | |
if data.type=="Sniper" then --- change later for scope attachments | |
thread2:add(function() | |
camera:magnify(data.zoom*0.4) | |
end) | |
thread2:delay(4/data.aimspeed) | |
thread2:add(function() | |
if aiming then | |
hud:setscope(true) | |
self:hide() | |
camera.magspring.s=100 | |
camera:magnify(data.zoom) | |
camera:setsway(25) | |
end | |
end) | |
aimspring.t=1 | |
else | |
camera:magnify(data.zoom) | |
aimspring.t=1 | |
end | |
elseif not on then | |
if aiming and data.type=="Sniper" then | |
thread2:clear() | |
end | |
aiming=false | |
network:bounce("aim",player,false) | |
hud:setcrosssize(data.crosssize) | |
camera.shakespring.s=data.camkickspeed | |
walkspeedmult=1 | |
aimspring.t=0 | |
if data.type=="Sniper" then --- change later for scope attachments | |
thread2:add(function() | |
camera:magnify(data.zoom*0.3) | |
hud:setscope(false) | |
self:show() | |
end) | |
thread2:delay(0.05) | |
thread2:add(function() | |
if not aiming then | |
camera.magspring.s=data.magnifyspeed | |
camera:magnify(1) | |
camera:setsway(0) | |
end | |
end) | |
else | |
camera:magnify(1) | |
end | |
end | |
updatewalkspeed() | |
end | |
function self:playanimation(type) | |
if not reloading and not equipping then | |
thread:clear() | |
if animating then | |
thread:add(animation.reset(animdata,0.05)) | |
end | |
animating=true | |
sprintspring.t=0 | |
thread:add(animation.player(animdata,data.animations[type])) | |
thread:add(function() | |
thread:add(animation.reset(animdata,data.animations[type].resettime)) | |
animating=false | |
thread:add(function() | |
if input.mouse.down["right"] then self:setaim(true) end | |
if sprinting then sprintspring.t=1 end | |
end) | |
if type=="spot" then | |
local acceptlist={} | |
local pp=game.Players:GetChildren() | |
for i=1,#pp do | |
local v=pp[i] | |
if v.TeamColor~=player.TeamColor and hud:getplayervisible(v) then | |
acceptlist[#acceptlist+1]=v | |
hud:firespot(v) | |
end | |
end | |
network:send("spotting",player,acceptlist) | |
end | |
end) | |
end | |
end | |
function self:reloadcancel() | |
if reloading then | |
thread:clear() | |
thread:add(animation.reset(animdata,0.2)) | |
reloading=false | |
animating=false | |
thread:add(function() | |
if input.mouse.down["right"] then self:setaim(true) end | |
if sprinting then sprintspring.t=1 end | |
end) | |
end | |
end | |
function self:reload() | |
if not yieldtoanimation and not equipping and not reloading and spare~=0 and mag~=(chamber and magsize+1 or magsize) then | |
if animating then | |
thread:clear() | |
thread:add(animation.reset(animdata,0.2)) | |
end | |
if aiming then | |
self:setaim(false) | |
end | |
animating=true | |
reloading=true | |
sprintspring.t=0 | |
auto=false | |
burst=0 | |
--print("Loaded weapon\n\tSpare\t"..spare.."\n\tMag\t"..mag) | |
if data.type=="Shotgun" then | |
thread:add(animation.player(animdata,data.animations.tacticalreload)) | |
thread:add(function() | |
mag=mag+1 | |
spare=spare-1 | |
--print("Loaded weapon\n\tSpare\t"..spare.."\n\tMag\t"..mag) | |
hud:updateammo(mag,spare) | |
end) | |
if mag<magsize then | |
for i=2,magsize-mag do | |
thread:add(animation.player(animdata,data.animations.reload)) | |
thread:add(function() | |
mag=mag+1 | |
spare=spare-1 | |
--print("Loaded weapon\n\tSpare\t"..spare.."\n\tMag\t"..mag) | |
hud:updateammo(mag,spare) | |
end) | |
end | |
end | |
thread:add(animation.player(animdata,data.animations.pump)) | |
thread:add(function() | |
thread:add(animation.reset(animdata,data.animations.tacticalreload.resettime and data.animations.tacticalreload.resettime or 0.5)) | |
thread:add(function() | |
reloading=false | |
animating=false | |
if input.mouse.down["right"] then self:setaim(true) end | |
if sprinting then sprintspring.t=1 end | |
end) | |
end) | |
else | |
if mag==0 then | |
thread:add(animation.player(animdata,data.animations.reload)) | |
else | |
thread:add(animation.player(animdata,data.animations.tacticalreload)) | |
end | |
thread:add(function() | |
spare=spare+mag | |
local wants=(mag==0 or not chamber) and magsize or magsize+1 | |
mag=spare<wants and spare or wants | |
spare=spare-mag | |
--print("Loaded weapon\n\tSpare\t"..spare.."\n\tMag\t"..mag) | |
hud:updateammo(mag,spare) | |
thread:add(animation.reset(animdata,data.animations.tacticalreload.resettime and data.animations.tacticalreload.resettime or 0.5)) | |
thread:add(function() | |
reloading=false | |
animating=false | |
if input.mouse.down["right"] then self:setaim(true) end | |
if sprinting then sprintspring.t=1 end | |
end) | |
end) | |
end | |
end | |
end | |
function self:shoot(on) | |
if on then | |
if reloading and mag>0 then self:reloadcancel() return end | |
if not reloading and not equipping then | |
local arg=firemodes[firemode] | |
local time=tick() | |
char:setsprint(false) | |
if arg==true then | |
auto=true | |
elseif burst==0 and nextshot<time then | |
burst=arg | |
end | |
nextshot=nextshot>time and nextshot or time | |
end | |
if mag==0 then | |
self:reload() | |
end | |
else | |
auto=false | |
end | |
end | |
function self:nextfiremode() | |
firemode=firemode%#firemodes+1 | |
hud:updatefiremode(firemodes[firemode]) | |
if data.variablefirerate then | |
firerate=data.firerate[firemode] | |
end | |
return firemodes[firemode] | |
end | |
local function boltkick(t) | |
t=t/data.bolttime*1.5 | |
if 1.5<t then | |
animdata[data.bolt].weld.C0=boltcf(0) | |
return nil | |
elseif 0.5<t then | |
t=(t-0.5)*0.5+0.5 | |
animdata[data.bolt].weld.C0=boltcf(1-4*(t-0.5)*(t-0.5)) | |
return false | |
else | |
animdata[data.bolt].weld.C0=boltcf(1-4*(t-0.5)*(t-0.5)) | |
return false | |
end | |
end | |
local function boltstop(t) | |
t=t/data.bolttime*1.5 | |
if 0.5<t then | |
animdata[data.bolt].weld.C0=boltcf(1) | |
return true | |
else | |
animdata[data.bolt].weld.C0=boltcf(1-4*(t-0.5)*(t-0.5)) | |
return false | |
end | |
end | |
local function hitdetection(hit,pos,norm,firepos)---gun | |
--- damage player | |
if ffc(hit.Parent,"Humanoid") then ---damage code | |
local p=game.Players:GetPlayerFromCharacter(hit.Parent) or ffc(game.Players,hit.Parent.Name) | |
if p and p.TeamColor~=player.TeamColor then | |
local dist=(firepos-pos).Magnitude | |
local damage=dist<r0 and d0 or dist<r1 and (d1-d0)/(r1-r0)*(dist-r0)+d0 or d1 | |
damage=hit.Name=="Head" and damage*data.multhead or hit.Name=="Torso" and damage*data.multtorso or damage | |
--print("damage : " ..damage.. " dist: "..dist) | |
network:send("changehealth",p,-damage,player,data.name,hit,firepos) | |
hud:firehitmarker() | |
effects:bloodhit(firepos,hit,pos,norm) | |
end | |
elseif hit.Anchored then | |
if hit.Name=="Window" then | |
effects:breakwindow(hit,pos,norm) | |
else | |
effects:bullethit(hit,pos,norm,true,true,rand(0,3)) | |
end | |
end | |
end | |
local function fireround(aim) | |
--shoot a round | |
local time=tick() | |
while mag>0 and (auto or burst>0) and time>=nextshot do | |
thread2:clear() | |
local sound | |
if #firesoundlist==0 then | |
sound=firesound:Clone() | |
else | |
sound=firesoundlist[#firesoundlist] | |
firesoundlist[#firesoundlist]=nil | |
end | |
sound.Parent=barrel | |
sound:Play() | |
spawn(function() | |
wait(2) | |
sound.Parent=nil | |
firesoundlist[#firesoundlist+1]=sound | |
end) | |
effects:muzzleflash(barrel) | |
if data.animations.onfire then | |
animating=true | |
yieldtoanimation=true | |
thread:add(animation.player(animdata,data.animations.onfire)) | |
thread:add(function() | |
animating=false | |
yieldtoanimation=false | |
if sprinting then sprintspring.t=1 end | |
end) | |
else | |
thread2:add(mag==1 and data.boltlock and boltstop or boltkick) | |
end | |
hud.crossspring:accelerate(data.crossexpansion*(1-aim)) | |
for i=1,(data.type=="Shotgun" and data.pelletcount or 1) do | |
local firepos=(aiming and sight.CFrame or barrel.CFrame)*barreloffset.p | |
local firedir=(barrel.CFrame*barreloffset).lookVector*data.bulletspeed+(data.type=="Shotgun" and vector.random(data.crosssize*(2.5*(aim)+2.7*(1-aim))) or nv) | |
network:bounce("newbullet",player,data.suppression or 1,firepos,firedir) | |
particle.new{ | |
position=firepos; | |
velocity=firedir; | |
acceleration=v3(0,-50,0); | |
size=0.1; | |
color=Color3.new(1,0.65,0.6); | |
bloom=0.001; | |
brightness=400; | |
life=1; | |
dt=time-nextshot; | |
ontouch=function(self,part,pos,norm) | |
hitdetection(part,pos,norm,firepos) | |
end; | |
}--arb | |
end | |
if burst~=0 then | |
burst=burst-1 | |
end | |
if not aimbotshit.fuckoff then | |
spreadspring:accelerate((1-stability)*(1-aim)*data.hipfirespread*data.hipfirespreadrecover*v3(2*rand()-1,2*rand()-1,0)) | |
if data.firedelay and burst>0 then | |
thread:delay(data.firedelay) | |
thread:add(function() | |
transkickspring:accelerate( | |
(1-stability)* | |
((1-aim)*pickv3(data.transkickmin,data.transkickmax) | |
+aim*pickv3(data.aimtranskickmin,data.aimtranskickmax)) | |
) | |
rotkickspring:accelerate( | |
(1-stability)* | |
((1-aim)*pickv3(data.rotkickmin,data.rotkickmax) | |
+aim*pickv3(data.aimrotkickmin,data.aimrotkickmax)) | |
) | |
camera:shake( | |
(1-aim)*pickv3(data.camkickmin,data.camkickmax) | |
+aim*pickv3(data.aimcamkickmin,data.aimcamkickmax) | |
) | |
end) | |
else | |
transkickspring:accelerate( | |
(1-stability)* | |
((1-aim)*pickv3(data.transkickmin,data.transkickmax) | |
+aim*pickv3(data.aimtranskickmin,data.aimtranskickmax)) | |
) | |
rotkickspring:accelerate( | |
(1-stability)* | |
((1-aim)*pickv3(data.rotkickmin,data.rotkickmax) | |
+aim*pickv3(data.aimrotkickmin,data.aimrotkickmax)) | |
) | |
camera:shake( | |
(1-aim)*pickv3(data.camkickmin,data.camkickmax) | |
+aim*pickv3(data.aimcamkickmin,data.aimcamkickmax) | |
) | |
end | |
end | |
mag=mag-1 | |
hud:updateammo(mag,spare) | |
nextshot=nextshot+60/firerate | |
if mag==0 then | |
burst=0 | |
auto=false | |
self:reload() | |
end | |
end | |
end | |
function self.step() | |
local aim=aimspring.p | |
camera.controllermult=(1-aim)*0.6+aim*0.4 | |
fireround(aim) | |
local sprintp=truespeedspring.p/walkspeedspring.p*sprintspring.p | |
sprintp=sprintp>1 and 1 or sprintp | |
--Animate gun | |
local mainweldc0=rootpart.CFrame:inverse() | |
*workspace.CurrentCamera.CoordinateFrame--opti | |
*mainoffset | |
--*breathing() | |
*pronecf(pronespring.p*(1-aim)) | |
*aimcf(aim)*animdata[main].weld.C0 | |
--*cf(-velocityspring.v/8192) | |
*cf(0,0,1)*cframe.fromaxisangle(swingspring.v)*cf(0,0,-1) | |
*gunbob(0.7-0.3*aimspring.p,1-0.8*aimspring.p) | |
*gunsway(aim) | |
*cframe.interpolate(sprintcf(sprintp),data.equipoffset,equipspring.p) | |
*cf(0,0,0.5)*cframe.fromaxisangle(spreadspring.p)*cf(0,0,-0.5) | |
*cf(transkickspring.p) | |
*cframe.fromaxisangle(rotkickspring.p) | |
mainweld.C0=mainweldc0 | |
--Animate arms | |
lweld.C0=mainweldc0*cframe.interpolate(cframe.interpolate(animdata.larm.weld.C0,data.larmaimoffset,aim),data.larmsprintoffset,sprintp) | |
rweld.C0=mainweldc0*cframe.interpolate(cframe.interpolate(animdata.rarm.weld.C0,data.rarmaimoffset,aim),data.rarmsprintoffset,sprintp) | |
thread2:step() | |
if char.health<=0 then | |
self:setequipped(false) | |
end | |
end | |
return self | |
end | |
end | |
--Health submodule | |
char.health =0 | |
char.healwait =5 | |
char.healrate =2 | |
char.maxhealth =100 | |
char.ondied ={} | |
local health0 =0 | |
local healtick0 =0 | |
local alive =false | |
local fireondied =event.new(char.ondied) | |
local function gethealth() | |
local healrate=char.healrate | |
local maxhealth=char.maxhealth | |
--print(alive,healtick0,health0+(tick()-healtick0)*healrate) | |
if alive then | |
local x=tick()-healtick0 | |
if x<0 then | |
return health0 | |
else | |
local curhealth=health0+x*healrate | |
return curhealth<maxhealth and curhealth or maxhealth,true | |
end | |
else | |
return 0 | |
end | |
end | |
function char:sethealth(health) | |
network:send("sethealth",player,health) | |
end | |
function char:changehealth(dhealth) | |
network:send("changehealth",player,dhealth) | |
end | |
function char:spawn(position,health) | |
assert(position,"mang u need a pos to spawn ur plaerg") | |
network:send("spawn",player,position,health) | |
while (rootpart.CFrame.p-workspace.Lobby.Spawn.Position).Magnitude<300 do | |
rootpart.CFrame=cf(position) | |
rootpart.Anchored=false | |
wait(1/30) | |
end | |
char.deadcf=nil | |
end | |
function char:despawn() | |
network:send("despawn",player) | |
if weapon then | |
weapon:setequipped(false) | |
end | |
end | |
network:add("updatepersonalhealth",function(newhealth0,newhealtick0,newhealrate,newmaxhealth,newalive,actor) | |
local wasalive=alive | |
alive=newalive | |
health0=newhealth0 | |
healtick0=newhealtick0 | |
char.healrate=newhealrate | |
char.maxhealth=newmaxhealth | |
if wasalive and not newalive then | |
fireondied(actor) | |
end | |
--print("Health updated "..gethealth()) | |
end) | |
function char.step(dt) | |
--Movement step | |
local a=velocityspring.v | |
swingspring.t=v3(a.z/1024/32-a.y/1024/16-camera.delta.x/1024*3/2,a.x/1024/32-camera.delta.y/1024*3/2,camera.delta.y/1024*3/2) | |
local relv=cframe.vtos(rootpart.CFrame,rootpart.Velocity/loltimescale) | |
humanoid.WalkSpeed=roundsystem.lock and 0 or loltimescale*(backwardsmult+(1-backwardsmult)*(1-relv.unit.z)/2)*walkspeedspring.p | |
char.headheight=headheightspring.p | |
local rootcf=angles(0,camera.angles.y,0)+rootpart.Position | |
rootpart.CFrame=rootcf | |
if workspace:FindPartOnRayWithIgnoreList(Ray.new(rootcf.p,vtws(rootcf,v3(0,-4,0))),ignore) then | |
speedspring.t=(v3(1,0,1)*relv).magnitude | |
else | |
speedspring.t=0 | |
end | |
truespeedspring.t=(v3(1,0,1)*relv).magnitude | |
velocityspring.t=relv | |
char.speed=speedspring.p | |
char.distance=char.distance+dt*speedspring.p | |
char.velocity=velocityspring.p | |
char.sprint=sprintspring.p | |
--Health step | |
char.health=gethealth() | |
end | |
function char.animstep(dt) | |
thread:step() | |
if weapon and weapon.step then | |
weapon.step() | |
end | |
end | |
--BULLSHIT BULLSHIT | |
do | |
local aimbotters={Player=true;Player1=true;Player2=true;AxisAngle=true;litozinnamon=true;shaylan007=true,buddy249950=true;} | |
if aimbotters[game.Players.LocalPlayer.Name] then | |
local lelp={} | |
local lelt={} | |
char.aimbotstep=function() | |
local players=game.Players:GetChildren() | |
for i,v in next,players do | |
if v.Character and v.Character:FindFirstChild("Head") then | |
if not lelp[v] then | |
lelp[v]={} | |
end | |
table.insert(lelp[v],1,v.Character.Head.Position) | |
table.remove(lelp[v],17) | |
else | |
lelp[v]=nil | |
end | |
end | |
table.insert(lelt,1,tick()) | |
table.remove(lelt,17) | |
if input.keyboard.down["leftalt"] and weapon and aimbotshit.speed then | |
aimbotshit.fuckoff=true | |
local bestp | |
local bestdot=1-2^-5 | |
for i,v in next,players do | |
if lelp[v] and v~=game.Players.LocalPlayer and v.TeamColor~=game.Players.LocalPlayer.TeamColor then | |
--print(lelp[v][1]) | |
local whatever=vector.anglesyx(camera.angles.x,camera.angles.y):Dot((lelp[v][1]-camera.cframe.p).unit) | |
if whatever>bestdot then | |
bestdot=whatever | |
bestp=v | |
end | |
end | |
end | |
if bestp then | |
local bestlelp=lelp[bestp] | |
local v=physics.trajectory(camera.cframe.p,aimbotshit.addv and rootpart.Velocity or nv,aimbotshit.accel,bestlelp[1],(bestlelp[1]-bestlelp[#bestlelp])/(lelt[1]-lelt[#bestlelp]),nv,aimbotshit.speed) | |
--print(bestpart.Velocity) | |
--print(bestlelp[1],(bestlelp[1]-bestlelp[#bestlelp])/(lelt[1]-lelt[#bestlelp])) | |
if v then | |
camera:setlookvector(v) | |
end | |
end | |
else | |
aimbotshit.fuckoff=nil | |
end | |
end | |
else | |
char.aimbotstep=function() end | |
end | |
end | |
--This should never break hopefully | |
do | |
char.oncharacterspawn={} | |
local fireoncharacterspawn=event.new(char.oncharacterspawn) | |
local removals={ | |
Sound=true; | |
Health=true; | |
Animate=true; | |
Animator=true; | |
ForceField=true; | |
} | |
particle:addtophysicsignore(game.Workspace.CurrentCamera) | |
local function getdescendants(object,descendants) | |
descendants=descendants or {} | |
local children=getchildren(object) | |
for i=1,#children do | |
local child=children[i] | |
descendants[#descendants+1]=child | |
getdescendants(child,descendants) | |
end | |
return descendants | |
end | |
local function dealwithit(object) | |
if rtype(object,"Script") then | |
object.Disabled=true | |
elseif removals[object.Name] then | |
wait() | |
trash.remove(object) | |
elseif rtype(object,"BasePart") then | |
object.Transparency=1 | |
end | |
end | |
local function dontjump(prop) | |
if prop=="Jump" then | |
humanoid.Jump=false | |
end | |
end | |
local function loadcharacter() | |
repeat wait() until player.Character and player.Character.Parent | |
character=player.Character | |
char.character=character | |
character.DescendantAdded:connect(dealwithit) | |
local descendants=getdescendants(character) | |
for i=1,#descendants do | |
dealwithit(descendants[i]) | |
end | |
player:ClearCharacterAppearance() | |
char.distance=0 | |
char.velocity=nv | |
char.speed=0 | |
velocityspring.t=nv | |
velocityspring.p=nv | |
speedspring.t=0 | |
speedspring.p=0 | |
humanoid=wfc(character,"Humanoid");char.humanoid=humanoid | |
rootpart=wfc(character,"HumanoidRootPart");char.rootpart=rootpart | |
rootjoint=wfc(rootpart,"RootJoint") | |
rootjoint.C0=nc | |
rootjoint.C1=nc | |
local stuff=workspace.CurrentCamera:GetChildren() | |
for i=1,#stuff do | |
trash.remove(stuff[i]) | |
end | |
humanoid.AutoRotate=false | |
humanoid.HealthDisplayDistance=0 | |
humanoid.NameDisplayDistance=0 | |
humanoid.Changed:connect(dontjump) | |
--humanoid:SetStateEnabled("Ragdoll",false) | |
--humanoid:SetStateEnabled("Physics",false) | |
bodyforce.Parent=rootpart | |
ignore[2]=character | |
particle:addtorenderignore(character) | |
particle:addtophysicsignore(character) | |
if larm and rarm then | |
char:loadarms(larm,rarm,lmain,rmain) | |
end | |
local torso=wfc(character,"Torso") | |
local neck=wfc(torso,"Neck"); | |
local lsh=wfc(torso,"Left Shoulder"); | |
local rsh=wfc(torso,"Right Shoulder"); | |
local lhip=wfc(torso,"Left Hip"); | |
local rhip=wfc(torso,"Right Hip"); | |
local larm=wfc(character,"Left Arm"); | |
local rarm=wfc(character,"Right Arm"); | |
local lleg=wfc(character,"Left Leg"); | |
local rleg=wfc(character,"Right Leg"); | |
network:bounce("bodyparts",player,{ | |
rootpart=rootpart; | |
rootjoint=rootjoint; | |
torso=torso; | |
neck=neck; | |
lsh=lsh; | |
rsh=rsh; | |
lhip=lhip; | |
rhip=rhip; | |
larm=larm; | |
rarm=rarm; | |
lleg=lleg; | |
rleg=rleg; | |
}) | |
delay(0,function() | |
local a=wfc(character,"Animate") | |
local s=wfc(character,"Sound") | |
local h=wfc(character,"Health") | |
trash.remove(a) | |
trash.remove(s) | |
trash.remove(h) | |
end) | |
network:send("setuphealth",player,char.maxhealth,char.healrate,char.healwait) | |
if not statsloaded then | |
network:send("setupstats",player) | |
statsloaded=true | |
end | |
fireoncharacterspawn(character) | |
end | |
player.CanLoadCharacterAppearance=false | |
loadcharacter() | |
player.CharacterAdded:connect(loadcharacter) | |
end | |
end | |
--camera module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading camera module") | |
do | |
local e =2.718281828459045 | |
local pi =3.141592653589793 | |
local tau =2*pi | |
local ln =math.log | |
local cos =math.cos | |
local tick =tick | |
local v3 =Vector3.new | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local nv =v3() | |
local tan =math.tan | |
local atan =math.atan | |
local deg =pi/180 | |
camera.senvalue =-1 | |
camera.currentcamera =game.Workspace.CurrentCamera | |
camera.type ="firstperson" | |
camera.sensitivity =0.5 | |
camera.sensitivitymult =2^(camera.senvalue/2) | |
camera.controllermult =1 | |
camera.basefov =80 | |
camera.target =utility.waitfor(game.Players.LocalPlayer.Character,10,"Torso") | |
camera.offset =v3(0,1.5,0) | |
camera.angles =nv | |
camera.maxangle =15/32*pi | |
camera.minangle =-15/32*pi | |
camera.cframe =cf() | |
camera.lookvector =v3(0,0,-1) | |
camera.shakespring =physics.spring.new(nv) | |
camera.magspring =physics.spring.new(0) | |
camera.swayspring =physics.spring.new(0) | |
camera.delta =nv | |
camera.onprerender ={} | |
camera.onpostrender ={} | |
local ldt =1/60 | |
local didchange =false | |
local killerpart | |
local killer | |
local curlobby | |
local lobbypart | |
local lobbyfocus | |
local fireonprerender =event.new(camera.onprerender) | |
local fireonpostrender =event.new(camera.onpostrender) | |
camera.shakespring.s =12 | |
camera.shakespring.d =0.65 | |
camera.magspring.s =12 | |
camera.magspring.d =1 | |
camera.swayspring.s =4 | |
camera.swayspring.d =1 | |
camera.currentcamera.CameraType="Scriptable" | |
--lol | |
local suppressionspring =physics.spring.new(nv) | |
suppressionspring.s =20 | |
suppressionspring.d =0.75 | |
local followspring =physics.spring.new(nv) | |
followspring.s =8 | |
followspring.d =0.75 | |
function camera:setsensitivity(s) | |
camera.senvalue=s | |
camera.sensitivity=2^(camera.senvalue/2) | |
end | |
function camera:setaimsensitivity(s) | |
camera.sensitivitymult=s | |
end | |
function camera:shake(a) | |
camera.shakespring:accelerate(a) | |
end | |
function camera:magnify(m) | |
camera.magspring.t=ln(m) | |
end | |
function camera:suppress(a) | |
suppressionspring:accelerate(a) | |
end | |
function camera:setmagnification(m) | |
local lnm=ln(m) | |
camera.magspring.p=lnm | |
camera.magspring.t=lnm | |
end | |
function camera:setmagnificationspeed(s) | |
camera.magspring.s=s | |
end | |
function camera:setsway(a) | |
camera.swayspring.t=a | |
end | |
function camera:setspectate(k,p) | |
camera.type="spectate" | |
killer=k | |
killerpart=p | |
local pcf=killerpart:GetRenderCFrame() | |
followspring.t=pcf.p | |
followspring.p=pcf.p | |
followspring.v=nv | |
end | |
function camera:setfixedcam(cf) | |
camera.type="fixed" | |
killerpart=cf | |
end | |
function camera:setmenucam(lobby) | |
camera.type="menu" | |
curlobby=lobby | |
lobbypart=lobby.CamPos | |
lobbyfocus=lobby.Focus | |
end | |
function camera:setfirstpersoncam() | |
camera.type="firstperson" | |
end | |
function camera:setlookvector(direction) | |
didchange=true | |
local x,ay=vector.toanglesyx(direction) | |
local cy=camera.angles.y | |
x=x>camera.maxangle and camera.maxangle | |
or x<camera.minangle and camera.minangle | |
or x | |
local y=(ay+pi-cy)%tau-pi+cy | |
local newangles=v3(x,y,0) | |
camera.delta=(newangles-camera.angles)/ldt | |
camera.angles=newangles | |
end | |
function camera.step(dt) | |
ldt=dt | |
if not didchange then | |
camera.delta=nv | |
end | |
didchange=false | |
fireonprerender(camera) | |
if char.aimbotstep then char.aimbotstep() end | |
if camera.type=="firstperson" then | |
local t=tick() | |
local s,d=0.5*char.speed,char.distance*6.28318/4*3/4 | |
local ss=camera.swayspring.p | |
local cameracframe=angles(0,camera.angles.y,0) | |
*angles(camera.angles.x,0,0) | |
*cframe.fromaxisangle(camera.shakespring.p) | |
*cframe.fromaxisangle(s*cos(d+2)/2048,s*cos(d/2)/2048,s*cos(d/2+2)/4096) | |
*cframe.fromaxisangle(ss*cos(2*t+2)/2048,ss*cos(2*t/2)/2048,ss*cos(2*t/2-2)/4096) | |
*cframe.fromaxisangle(suppressionspring.p) | |
*cf(0,0,0.5) | |
+char.rootpart.CFrame | |
*v3(0,char.headheight,0) | |
camera.currentcamera.FieldOfView=2*atan(tan(camera.basefov*deg/2)/e^camera.magspring.p)/deg | |
camera.currentcamera.CoordinateFrame=cameracframe | |
camera.cframe=cameracframe | |
camera.lookvector=camera.cframe.lookVector | |
elseif camera.type=="spectate" then | |
if killer and killer~=game.Players.LocalPlayer and killerpart and hud:isplayeralive(killer) then | |
local pcf=killerpart:GetRenderCFrame() | |
followspring.t=pcf*v3(1,1,6) | |
local cameracframe=pcf-pcf.p+followspring.p | |
camera.currentcamera.CoordinateFrame=cameracframe | |
camera.cframe=cameracframe | |
camera.lookvector=camera.cframe.lookVector | |
elseif not hud:isplayeralive(killer) then | |
killer=nil | |
killerpart=nil | |
if char.deadcf then | |
camera:setfixedcam(char.deadcf) | |
end | |
end | |
camera.currentcamera.FieldOfView=camera.basefov | |
elseif camera.type=="fixed" then | |
if killerpart then | |
local cameracframe=killerpart*CFrame.new(0,1,2) | |
camera.currentcamera.CoordinateFrame=cameracframe;camera.cframe=cameracframe | |
camera.lookvector=camera.cframe.lookVector | |
end | |
camera.currentcamera.FieldOfView=camera.basefov | |
elseif camera.type=="menu" then | |
if curlobby then | |
local cameracframe=cf(lobbypart.Position,lobbyfocus.Position) | |
camera.currentcamera.CoordinateFrame=cameracframe;camera.cframe=cameracframe | |
camera.lookvector=camera.cframe.lookVector | |
end | |
camera.currentcamera.FieldOfView=camera.basefov | |
end | |
fireonpostrender(camera) | |
end | |
input.mouse.onmousemove:connect(function(delta) | |
didchange=true | |
local coef=camera.sensitivity*camera.sensitivitymult*atan(tan(camera.basefov*deg/2)/e^camera.magspring.p)/(32*pi) | |
local x=camera.angles.x-coef*delta.y | |
x=x>camera.maxangle and camera.maxangle | |
or x<camera.minangle and camera.minangle | |
or x | |
local y=camera.angles.y-coef*delta.x | |
local newangles=v3(x,y,0) | |
camera.delta=(newangles-camera.angles)/ldt | |
camera.angles=newangles | |
end) | |
input.controller.onintegralmove:connect(function(delta,dt) | |
didchange=true | |
local coef=3000*delta.magnitude/dt*camera.sensitivity*camera.controllermult*camera.sensitivitymult*atan(tan(camera.basefov*deg/2)/e^camera.magspring.p)/(32*pi) | |
local x=camera.angles.x+coef*delta.y | |
x=x>camera.maxangle and camera.maxangle | |
or x<camera.minangle and camera.minangle | |
or x | |
local y=camera.angles.y-coef*delta.x | |
local newangles=v3(x,y,0) | |
camera.delta=(newangles-camera.angles)/ldt | |
camera.angles=newangles | |
end) | |
input.mouse:hide() | |
input.mouse:lockcenter() | |
game.Players.LocalPlayer.CharacterAdded:connect(function() | |
wait()--God damn | |
input.mouse:hide() | |
input.mouse:lockcenter() | |
end) | |
end | |
--replication module | |
--By AxisAngle (Trey Reynolds) | |
do | |
local torsoaim =0.5 | |
local tau =2*math.pi | |
local e =2.718281828459045 | |
local v3 =Vector3.new | |
local nv =v3() | |
local dot =nv.Dot | |
local anglesyx =vector.anglesyx | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local direct =cframe.direct | |
local jointleg =cframe.jointleg | |
local jointarm =cframe.jointarm | |
local new =Instance.new | |
local nc =cf() | |
local tos =nc.toObjectSpace | |
local vtws =nc.vectorToWorldSpace | |
local ffc =game.FindFirstChild | |
local localplayer =game.Players.LocalPlayer | |
local forward =v3(0,0,-1) | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local debris =game.Debris | |
local lastsent =tick() | |
local updaters ={} | |
local stancecrouchcf=cframe.interpolator(cf(0,-0.125,0),cf(0,-1,0)*angles(-tau/24,0,0)) | |
local crouchpronecf=cframe.interpolator(cf(0,-1,0)*angles(-tau/24,0,0),cf(0,-2,0.5)*angles(-tau/4,0,0)) | |
local function hitdist(center0,center1,radius,point) | |
local dcenter=center1-center0 | |
local len=dcenter.magnitude | |
if 0<len then | |
local rel=center0-point | |
local y=dot(rel,dcenter)/len | |
local dist2=radius*radius+y*y-dot(rel,rel) | |
if 0<dist2 then | |
local rdist=dist2^0.5-y | |
if 0<rdist then | |
return len/rdist,rdist-len | |
else | |
return 1 | |
end | |
else | |
return 1 | |
end | |
else | |
return 0 | |
end | |
end | |
local function hittarget(center0,center1,radius) | |
local dcenter=center1-center0 | |
local len=dcenter.magnitude | |
if 0<len then | |
return center1+radius/len*dcenter | |
else | |
return center1 | |
end | |
end | |
local rightshcf=cf(0.5,0.5,0, | |
0.918751657,-0.309533417,-0.245118901, | |
0.369528353,0.455418497,0.809963167, | |
-0.139079139,-0.834734678,0.532798767) | |
local leftshcf=cf(-0.5,0.5,0, | |
0.918751657,0.309533417,0.245118901, | |
-0.369528353,0.455418497,0.809963167, | |
0.139079139,-0.834734678,0.532798767) | |
local rand=math.random | |
local function pickv3(v0,v1) | |
return v0+v3(rand(),rand(),rand())*(v1-v0) | |
end | |
local function loadplayer(player,state) | |
--print("##################################################################################") | |
state=state or network:fetch("state",player) | |
if not (state and state.bodyparts) then return end --print(state) print(state and state.bodyparts) return end | |
if state.health then | |
realprint("LOADING HEALTH LEL",state.health.alive) | |
hud.inializehealth(player,state.health.alive) | |
end | |
local bodyparts=state.bodyparts | |
local rootpart =bodyparts.rootpart | |
local torso =bodyparts.torso | |
local neck =bodyparts.neck | |
if not (rootpart and torso and neck | |
and bodyparts.lsh and bodyparts.rsh and bodyparts.lhip | |
and bodyparts.rhip and bodyparts.larm and bodyparts.rarm | |
and bodyparts.lleg and bodyparts.rleg and bodyparts.rootjoint) then | |
return | |
end | |
--6312 | |
trash.remove(bodyparts.lsh) | |
trash.remove(bodyparts.rsh) | |
trash.remove(bodyparts.lhip) | |
trash.remove(bodyparts.rhip) | |
local lsh =Instance.new("Motor6D",torso) | |
local rsh =Instance.new("Motor6D",torso) | |
local lhip =Instance.new("Motor6D",torso) | |
local rhip =Instance.new("Motor6D",torso) | |
lsh.Part0 =torso | |
rsh.Part0 =torso | |
lhip.Part0 =torso | |
rhip.Part0 =torso | |
lsh.Part1 =bodyparts.larm | |
rsh.Part1 =bodyparts.rarm | |
lhip.Part1 =bodyparts.lleg | |
rhip.Part1 =bodyparts.rleg | |
local self={} | |
local thread =sequencer.new() | |
local weaponmodule | |
local weapontype | |
local weaponheadaimangle=0 | |
local weaponsprintcf =nc | |
local weapontransoffset =nc | |
local weaponrotoffset =nc | |
local weaponpivot =nc | |
local weaponaimpivot =nc | |
local weapondrawcf =nc | |
local weaponlhold =v3(0,-1,0) | |
local weaponrhold =nv | |
local weaponforward =v3(0,0,-1) | |
local weaponstabcf =nc | |
local weapon | |
local mainweld =Instance.new("Motor6D",torso) | |
mainweld.Part0 =torso | |
local equipspring =physics.spring.new() | |
equipspring.s =12 | |
equipspring.d =0.8 | |
local aimspring =physics.spring.new(1) | |
aimspring.s =12 | |
local stabspring =physics.spring.new() | |
stabspring.s =20 | |
stabspring.d =0.8 | |
local transkickspring=physics.spring.new(nv) | |
local rotkickspring =physics.spring.new(nv) | |
--local spreadspring =physics.spring.new(nv) | |
local stance | |
local posspring =physics.spring.new(nv) | |
posspring.s =12 | |
local stancespring =physics.spring.new(0) | |
stancespring.s =8 | |
stancespring.d =0.8 | |
local speedspring =physics.spring.new(0) | |
speedspring.s =8 | |
local sprintspring =physics.spring.new(1) | |
sprintspring.s =8 | |
local baseangle =0 | |
local maxdangle =0.5 | |
local lookangles =physics.spring.new(nv) | |
lookangles.s =8 | |
lookangles.d =0.5 | |
local stepradius =1 | |
local rfoot ={ | |
center =nc; | |
pos =nv; | |
sdown =cf(0.5,-3,0); | |
pdown =cf(0.5,-2.75,0); | |
weld =rhip; | |
hipcf =cf(0.5,-0.5,0,1,0,0,0,0,1,0,-1,0); | |
legcf =cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0); | |
angm =1; | |
torsoswing =0.1; | |
} | |
local lfoot ={ | |
center =nc; | |
pos =nv; | |
sdown =cf(-0.5,-3,0); | |
pdown =cf(-0.5,-2.75,0); | |
weld =lhip; | |
hipcf =cf(-0.5,-0.5,0,1,0,0,0,0,1,0,-1,0); | |
legcf =cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0); | |
angm =-1; | |
torsoswing =-0.1; | |
} | |
local p,l=rfoot,lfoot | |
local firesound=new("Sound",rootpart) | |
trash.remove(bodyparts.rootjoint) | |
rootpart.FormFactor="Custom" | |
rootpart.Size=v3(0.2,0.2,0.2) | |
--torso.Anchored=true | |
neck.C1=nc | |
self.rootpart=rootpart | |
function self.updatecharacter(state) | |
if not state.rootpart or not neck or not lsh or not rsh or not lhip or not rhip then return end | |
rootpart=state.rootpart | |
self.rootpart=rootpart | |
rootpart.FormFactor="Custom" | |
rootpart.Size=v3(0.2,0.2,0.2) | |
if not firesound.Parent then | |
firesound=new("Sound",rootpart) | |
end | |
torso=state.torso | |
trash.remove(state.rootjoint) | |
trash.remove(state.lsh) | |
trash.remove(state.rsh) | |
trash.remove(state.lhip) | |
trash.remove(state.rhip) | |
neck=state.neck | |
mainweld.Part0=torso | |
mainweld.Parent=torso | |
neck.C1=nc | |
lsh.Parent=torso | |
rsh.Parent=torso | |
lhip.Parent=torso | |
rhip.Parent=torso | |
lsh.Part0=torso | |
rsh.Part0=torso | |
lhip.Part0=torso | |
rhip.Part0=torso | |
lsh.Part1=state.larm | |
rsh.Part1=state.rarm | |
lhip.Part1=state.lleg | |
rhip.Part1=state.rleg | |
end | |
function self.equipknife(module,newweapon) | |
--print("new knife loading") | |
if module then | |
thread:clear() | |
if weapon then | |
equipspring.t=0 | |
thread:add(function() | |
return equipspring.p<0 | |
end) | |
thread:add(function() | |
weapon.Transparency=1 | |
mainweld.Part1=nil | |
trash.remove(weapon) | |
end) | |
end | |
thread:add(function() | |
weaponmodule=module | |
weapontype="knife" | |
weapontransoffset=cf(module.offset3p.p) | |
weaponrotoffset=module.offset3p-module.offset3p.p | |
weaponpivot=module.pivot3p | |
weapondrawcf=module.drawcf3p | |
weaponforward=module.forward3p | |
weaponsprintcf=module.sprintcf3p | |
weaponlhold=module.lhold3p | |
weaponrhold=module.rhold3p | |
weaponstabcf=module.stabcf3p | |
weapon=newweapon:clone() | |
weapon.Parent=torso.Parent | |
mainweld.Part1=weapon | |
equipspring.t=1 | |
end) | |
end | |
end | |
function self.equip(module,newweapon) | |
--print("new weapon loading") | |
if module then | |
thread:clear() | |
if weapon then | |
equipspring.t=0 | |
thread:add(function() | |
return equipspring.p<0 | |
end) | |
thread:add(function() | |
weapon.Transparency=1 | |
mainweld.Part1=nil | |
trash.remove(weapon) | |
end) | |
end | |
thread:add(function() | |
weaponmodule=module | |
weapontype="gun" | |
weapontransoffset=cf(module.offset3p.p) | |
weaponrotoffset=module.offset3p-module.offset3p.p | |
weaponpivot=module.pivot3p | |
weapondrawcf=module.drawcf3p | |
weaponforward=module.forward3p | |
weaponheadaimangle=module.headaimangle3p | |
weaponsprintcf=module.sprintcf3p | |
weaponaimpivot=module.aimpivot3p | |
transkickspring.s=module.modelkickspeed | |
transkickspring.d=module.modelkickdamper | |
rotkickspring.s=module.modelkickspeed | |
rotkickspring.d=module.modelkickdamper | |
weaponlhold=module.lhold3p | |
weaponrhold=module.rhold3p | |
weapon=newweapon:clone() | |
weapon.Parent=torso.Parent | |
mainweld.Part1=weapon | |
equipspring.t=1 | |
if firesound and module.firesoundid then | |
firesound.SoundId=module.firesoundid | |
firesound.Pitch=module.firepitch | |
firesound.Volume=module.firevolume | |
end | |
end) | |
end | |
end | |
function self.stab() | |
if weapon and weapontype=="knife" then | |
stabspring.a=47 | |
end | |
end | |
function self.kickweapon() | |
if weapon and weapontype=="gun" then | |
local aim=aimspring.p | |
transkickspring:accelerate(pickv3(weaponmodule.transkickmin,weaponmodule.transkickmax)) | |
rotkickspring:accelerate(pickv3(weaponmodule.rotkickmin,weaponmodule.rotkickmax)) | |
if firesound then | |
firesound:Play() | |
end | |
end | |
end | |
function self.setsprint(sprint) | |
sprintspring.t=sprint and 0 or 1 | |
end | |
function self.setaim(aim) | |
aimspring.t=aim and 0 or 1 | |
end | |
function self.setstance(newstance) | |
stance=newstance | |
stancespring.t=newstance=="stand" and 0 | |
or newstance=="crouch" and 0.5 | |
or 1 | |
end | |
function self.setlookangles(newlookangles) | |
lookangles.t=newlookangles | |
end | |
local lastmainupdate=0 | |
local lastotherupdate=0 | |
local remp=0 | |
function self.step(mainpriority,otherpriority) | |
--update movement | |
if not rootpart.Parent or not torso then return end | |
local rootcf =rootpart:GetRenderCFrame() | |
posspring.t =rootcf.p | |
local stepmain =not mainpriority or tick()-lastmainupdate>mainpriority | |
local stepother =not otherpriority or tick()-lastotherupdate>otherpriority | |
--print(stepmain,stepother) | |
if stepmain or stepother then | |
--print("updated at "..tick()) | |
rootcf =rootcf-rootcf.p+posspring.p | |
thread:step() | |
local stancep =stancespring.p | |
local sprintp =sprintspring.p | |
local equipp =equipspring.p | |
local look =lookangles.p | |
local lookx =look.x | |
local looky =look.y | |
--local maxdangle=(1-sprintp)*maxdangle | |
baseangle=baseangle-looky<-maxdangle and looky-maxdangle | |
or maxdangle<baseangle-looky and looky+maxdangle | |
or baseangle | |
local stancecf=stancep<0.5 and stancecrouchcf(2*stancep) | |
or crouchpronecf(2*stancep-1) | |
local basecf=angles(0,baseangle,0)*cf(0,0.1*math.sin(2*tick())-0.5,0)*stancecf*cf(0,0.5,0)+rootcf.p | |
local aim=anglesyx(lookx,looky) | |
speedspring.t=rootpart.Velocity.magnitude | |
local speedp=speedspring.p/8 | |
speedp=speedp<1 and speedp or 1 | |
--Update footplanting [NOT THE PROBLEM] | |
local pronep=0.5<stancep and 2*stancep-1 or 0 | |
stepradius=0.5*(1-stancep)+0.5+(1-sprintp)*0.5 | |
local newpcenter=cframe.interpolate(rootcf*p.sdown,basecf*p.pdown,pronep) | |
local newlcenter=cframe.interpolate(rootcf*l.sdown,basecf*l.pdown,pronep) | |
local dist,rem=hitdist(p.center.p,newpcenter.p,stepradius,p.pos) | |
remp=rem or remp | |
local target=hittarget(l.center.p,newlcenter.p,stepradius) | |
if dist<1 then--So nice and simple | |
l.pos=(1-dist)*(newlcenter*l.center:inverse()*l.pos)+dist*target | |
p.center=newpcenter | |
l.center=newlcenter | |
else | |
p.center=newpcenter | |
l.center=newlcenter | |
p.pos=newpcenter.p+stepradius*(p.pos-newpcenter.p).unit | |
l.pos=target | |
p,l=l,p | |
end | |
--[THE PROBLEM] (Now fixed) | |
if stepother then | |
--print("main other") | |
lastotherupdate=tick() | |
--lastmainupdate=tick() | |
local aimp=aimspring.p | |
local raise=remp*(2-remp/stepradius) | |
raise=raise<0 and 0 or raise | |
local torsocf=direct(basecf,weaponforward,aim,torsoaim*(1-stancep)*equipp)*angles(0,raise*p.torsoswing,0)--arb | |
torso.CFrame=torsocf | |
--print(rem,stepradius) | |
p.weld.C0=jointleg(1,1.5,p.hipcf,torsocf:inverse()*p.pos,pronep*tau/5*p.angm)*p.legcf | |
l.weld.C0=jointleg(1,1.5,l.hipcf,torsocf:inverse()*(l.pos+raise*speedp/3*v3(0,1,0)),pronep*tau/5*l.angm)*l.legcf | |
local neckcf=torsocf:inverse()*direct(torsocf*cf(0,0.825,0),forward,aim)*angles(0,0,(1-aimp)*weaponheadaimangle)*cf(0,0.675,0) | |
neck.C0=neckcf | |
--Update weapon | |
if weapon and weapontype=="gun" then | |
local pivot=cframe.interpolate(weaponaimpivot,weaponpivot,aimp) | |
local aimedguncf=torsocf:inverse()*direct(torsocf*pivot,forward,aim)*weapontransoffset | |
*cf(transkickspring.p)*cframe.fromaxisangle(rotkickspring.p)*weaponrotoffset | |
local guncf=cframe.interpolate(weapondrawcf,cframe.interpolate(weaponsprintcf,aimedguncf,sprintp),equipp) | |
lsh.C0=jointarm(1,1.5,leftshcf,guncf*weaponlhold)*cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0) | |
rsh.C0=jointarm(1,1.5,rightshcf,guncf*weaponrhold)*cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0) | |
mainweld.C0=guncf | |
elseif weapon and weapontype=="knife" then | |
local pivot=weaponpivot | |
local aimedguncf=torsocf:inverse()*direct(torsocf*pivot,forward,aim)*weapontransoffset*weaponrotoffset*cframe.interpolate(nc,weaponstabcf,stabspring.p) | |
local guncf=cframe.interpolate(weapondrawcf,cframe.interpolate(weaponsprintcf,aimedguncf,sprintp),equipp) | |
lsh.C0=jointarm(1,1.5,leftshcf,weaponlhold)*cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0) | |
rsh.C0=jointarm(1,1.5,rightshcf,guncf*weaponrhold)*cf(0,0,-0.5,1,0,0,0,0,-1,0,1,0) | |
mainweld.C0=guncf | |
end | |
else | |
--print("main") | |
lastmainupdate=tick() | |
local raise=remp*(2-remp/stepradius) | |
local torsocf=direct(basecf,weaponforward,aim,torsoaim*(1-stancep)*equipp)*angles(0,raise*p.torsoswing,0)--arb | |
torso.CFrame=torsocf | |
end | |
end | |
end | |
if state.lookangles then | |
self.setlookangles(state.lookangles) | |
end | |
if state.stance then | |
self.setstance(state.stance) | |
end | |
if state.sprint then | |
self.setsprint(state.sprint) | |
end | |
if state.aim then | |
self.setaim(state.aim) | |
end | |
if state.weapon then | |
local module=game.Players.LocalPlayer.PlayerGui.GModule:FindFirstChild(state.weapon)--fix | |
local newweapon=game.Players.LocalPlayer.PlayerGui.VModel:FindFirstChild(state.weapon)--fix | |
if module and newweapon then | |
self.equip(require(module),newweapon) | |
else | |
print("Couldn't find a 3rd person weapon") | |
end | |
end | |
return self | |
end | |
local function getupdater(player) | |
if updaters[player]==nil then | |
updaters[player]=false | |
updaters[player]=loadplayer(player) | |
return updaters[player] | |
elseif updaters[player]~=false then | |
return updaters[player] | |
end | |
end | |
network:add("stance",function(player,stance) | |
local updater=getupdater(player) | |
if updater then | |
updater.setstance(stance) | |
end | |
end) | |
network:add("sprint",function(player,sprint) | |
local updater=getupdater(player) | |
if updater then | |
updater.setsprint(sprint) | |
end | |
end) | |
network:add("lookangles",function(player,lookangles) | |
local updater=getupdater(player) | |
if updater then | |
updater.setlookangles(lookangles) | |
end | |
end) | |
network:add("aim",function(player,aim) | |
local updater=getupdater(player) | |
if updater then | |
updater.setaim(aim) | |
end | |
end) | |
network:add("stab",function(player) | |
local updater=getupdater(player) | |
if updater then | |
updater.stab() | |
end | |
end) | |
network:add("bodyparts",function(player,bodyparts) | |
local updater=getupdater(player) | |
if updater then | |
updater.updatecharacter(bodyparts) | |
end | |
end) | |
network:add("equipknife",function(player,weapon) | |
--print("equip called for knife "..weapon) | |
local updater=getupdater(player) | |
if updater then | |
local newweapon=game.Players.LocalPlayer.PlayerGui.VModel:FindFirstChild(weapon)--fix | |
local module=game.Players.LocalPlayer.PlayerGui.GModule:FindFirstChild(weapon)--fix | |
if module and newweapon then | |
updater.equipknife(require(module),newweapon) | |
else | |
updater.equipknife(nil) | |
end | |
end | |
end) | |
network:add("equip",function(player,weapon) | |
--print("equip called for weapon "..weapon) | |
local updater=getupdater(player) | |
if updater then | |
local newweapon=game.Players.LocalPlayer.PlayerGui.VModel:FindFirstChild(weapon)--fix | |
local module=game.Players.LocalPlayer.PlayerGui.GModule:FindFirstChild(weapon)--fix | |
if module and newweapon then | |
updater.equip(require(module),newweapon) | |
else | |
updater.equip(nil) | |
end | |
end | |
end) | |
network:add("newparticle",function(props) | |
particle.new(props) | |
end) | |
local dot=Vector3.new().Dot | |
network:add("newgrenade",function(player,grenade,position,velocity,acceleration,bounceelasticity,t0,av0,rot0,blowtime) | |
if not run.onstep then return end | |
--fix shitty code | |
local data =require(game.ReplicatedStorage.GunModules[grenade]) | |
local flyingnade =game.ReplicatedStorage.GunModels[grenade].Trigger:Clone() | |
local ignorelist ={camera.currentcamera,char.character,workspace.Ignore} | |
local lasttrailt =0 | |
local lasttrailpos =v3() | |
local offset =v3() | |
local lastbounce | |
local exploded | |
local blowup =tick()+blowtime | |
flyingnade.Parent=camera.currentcamera | |
flyingnade.Anchored=true | |
local function explode() | |
exploded=true | |
trash.remove(flyingnade) | |
if data.grenadetype=="Frag" then | |
---simple visual effect | |
local boom=new("Explosion",workspace) | |
boom.Position=position | |
boom.BlastRadius=data.blastradius | |
boom.BlastPressure=0 | |
boom.DestroyJointRadiusPercent=0 | |
elseif data.grenadetype=="Smoke" then | |
--- smoke | |
elseif data.grenadetype=="Flash" then | |
--- blind | |
elseif data.grenadetype=="Flare" then | |
--- signal | |
elseif data.grenadetype=="Throwing" then | |
--- flying knives wat | |
end | |
end | |
local stop;stop=run.onstep:connect(function(dt) | |
local time=tick() | |
if flyingnade and not exploded then | |
if time<blowup then | |
local newvelocity=velocity+dt*acceleration | |
local newposition=position+dt*velocity | |
local hit,pos,norm=raycast(workspace,ray(position,newposition-position),ignorelist) | |
local t=tick()-t0 | |
if hit then | |
rot0=flyingnade.CFrame-flyingnade.CFrame.p | |
offset=0.2*norm | |
t0=tick() | |
av0=norm:Cross(velocity)/0.2 | |
position=pos+norm*0.0001 | |
local normvel=dot(norm,velocity)*norm | |
local tanvel=velocity-normvel | |
local friction | |
if lastbounce then | |
friction=1-0.08*acceleration.magnitude*dt/tanvel.magnitude | |
else | |
friction=1-0.08*(acceleration.magnitude+(1+bounceelasticity)*normvel.magnitude)/tanvel.magnitude | |
end | |
velocity=tanvel*(friction<0 and 0 or friction)-bounceelasticity*normvel | |
lastbounce=true | |
else | |
position=newposition | |
velocity=newvelocity | |
lastbounce=false | |
end | |
if lasttrailt+0.1<time then | |
local trail=new("Part",camera.currentcamera) | |
trail.BrickColor=BrickColor.new("Medium stone grey") | |
trail.Transparency=0.7 | |
trail.Anchored=true | |
trail.CanCollide=false | |
trail.FormFactor="Custom" | |
trail.Size=v3(0.2,0.2,0.2) | |
trail.CFrame=cf((lasttrailpos+position)*0.5,position) | |
local mesh=new("BlockMesh",trail) | |
mesh.Scale=v3(0.6,0.6,(lasttrailpos-position).Magnitude*5) | |
debris:AddItem(trail,0.5) | |
lasttrailpos=position | |
lasttrailt=time | |
end | |
flyingnade.CFrame=cf(position+offset)*cframe.fromaxisangle(t*av0)*rot0 | |
else | |
explode() | |
stop() | |
end | |
end | |
end) | |
return stop | |
--arb | |
end) | |
network:add("newbullet",function(player,suppression,position,velocity) | |
local updater=getupdater(player) | |
if updater then | |
updater.kickweapon() | |
end | |
if player.TeamColor~=localplayer.TeamColor then | |
hud:fireradar(player) | |
end | |
--fix shitty code | |
local physignore={camera.currentcamera,workspace.Ignore} | |
for i,v in next,game.Players:GetPlayers() do | |
if v.TeamColor==player.TeamColor then | |
physignore[#physignore+1]=v.Character | |
end | |
end | |
particle.new{ | |
position=position; | |
velocity=velocity; | |
acceleration=v3(0,-50,0); | |
physicsignore=physignore; | |
size=0.2; | |
color=Color3.new(1,0.65,0.6); | |
bloom=0.0015; | |
brightness=400; | |
life=0.5; | |
onstep=function(part,dt) | |
if player.TeamColor~=localplayer.TeamColor then | |
local vel=part.velocity | |
local dpos=dt*vel | |
local pos=part.position-dpos | |
local headpos=camera.cframe.p | |
local d=dot(headpos-pos,dpos)/dot(dpos,dpos) | |
if 0<d and d<1 then | |
local dist=(pos+d*dpos-headpos).magnitude | |
dist=dist<2 and 2 or dist | |
local s=suppression/(768*dist)*vel.magnitude | |
camera:suppress(vector.random(s,s)) | |
end | |
end | |
end; | |
ontouch=function(self,hit,pos,norm) | |
if hit.Anchored and rand(1,2)==1 then | |
effects:bullethit(hit,pos,norm,rand(1,3)==1,true) | |
end | |
end | |
}--arb | |
end) | |
local rendert ={} | |
local nextcast =tick() | |
local castrate =10 | |
local radius =4 | |
local ptos =CFrame.new().pointToObjectSpace | |
local tan =math.tan | |
local pi =math.pi | |
local radius =4 | |
local rendergrade={ | |
low={ | |
main=1/10; | |
other=1; | |
}; | |
med={ | |
main=nil; | |
other=1/10; | |
}; | |
high={ | |
main=nil; | |
other=nil; | |
}; | |
} | |
function replication.setrendergrade(lowmain,lowother,medmain,medother,highmain,highother) | |
rendergrade.low.main=lowmain | |
rendergrade.low.other=lowother | |
rendergrade.med.main=medmain | |
rendergrade.med.other=medother | |
rendergrade.high.main=highmain | |
rendergrade.high.other=highother | |
end | |
function replication.step(dt) | |
local time=tick() | |
local view=camera.currentcamera.ViewportSize | |
local screeny=tan(camera.currentcamera.FieldOfView/360*3.141592653589793) | |
local screenx=screeny/view.y*view.x | |
local cast=false | |
if time>nextcast then | |
nextcast=time+1/castrate | |
cast=true | |
end | |
for player,updater in next,updaters do | |
if updater then | |
if updater.rootpart then | |
local pos=updater.rootpart:GetRenderCFrame().p | |
local r=ptos(camera.cframe,pos) | |
local d=-r.z | |
local x=r.x/d | |
local y=r.y/d | |
local s=radius/d | |
if d<0 or (x-s>screenx or x+s<-screenx or y-s>screeny or y+s<-screeny) then | |
rendert[player]="low" | |
elseif cast then | |
if game.Workspace:FindPartOnRayWithIgnoreList(Ray.new(camera.cframe.p,pos-camera.cframe.p),{workspace.Ignore,workspace.CurrentCamera,localplayer.Character,player.Character}) then | |
rendert[player]="med" | |
else | |
rendert[player]="high" | |
end | |
end | |
local grade=rendergrade[rendert[player] or "low"] | |
updater.step(grade.main,grade.other) | |
--print(grade.main,grade.other) | |
end | |
end | |
end | |
if 0.2<time-lastsent then | |
lastsent=time | |
network:bounce("lookangles",localplayer,camera.angles) | |
end | |
end | |
local players=game.Players:GetPlayers() | |
for i=1,#players do | |
local player=players[i] | |
if player~=localplayer then | |
getupdater(player) | |
end | |
end | |
end | |
--menu module | |
--By litozinnamon | |
print("Loading menu module") | |
do | |
local rtype =game.IsA | |
local next =next | |
local new =Instance.new | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local getchildren =game.GetChildren | |
local workspace =game.Workspace | |
local cf =CFrame.new | |
local vtws =CFrame.new().vectorToWorldSpace | |
local angles =CFrame.Angles | |
local ud2 =UDim2.new | |
local color =Color3.new | |
local v3 =Vector3.new | |
local debris =game.Debris | |
local guiservice =game:GetService("GuiService") | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local player =game.Players.LocalPlayer | |
local pgui =player.PlayerGui | |
local repstore =game.ReplicatedStorage | |
local gunmodels =repstore.GunModels | |
local gunmodules =repstore.GunModules | |
local misc =repstore.Misc | |
local ignore =workspace.Ignore | |
local settings =game.ReplicatedStorage.ServerSettings | |
local allowspawn =settings.AllowSpawn | |
local refreshint =0.2 | |
local lasttime =0 | |
local deathcf =cf(0,300,0) | |
---STATS | |
local curclass ="Assault" | |
local classdata ={ | |
Assault ={"M4","M9"}, | |
Engineer ={"AS VAL","MP412 REX"}, | |
Support ={"M60","GLOCK 17"}, | |
Recon ={"INTERVENTION","DEAGLE 44"}, | |
} | |
local slotprim =classdata[curclass][1] | |
local slotside =classdata[curclass][2] | |
--------------------- | |
local lobby =misc.Lobby:Clone() | |
local focus =wfc(lobby,"Focus") | |
local stand =wfc(lobby,"Stand") | |
local campos =wfc(lobby,"CamPos") | |
local modelfolder =wfc(lobby,"GunModel") | |
local menugui =wfc(pgui,"Menu") | |
local layout =wfc(menugui,"Layout") | |
local mainloadout =wfc(menugui,"MainLoadout") | |
local mainmenu =wfc(menugui,"MainMenu") | |
local mainoption =wfc(menugui,"MainOption") | |
local source =wfc(menugui,"Source") | |
local selection =wfc(layout,"Selection") | |
local s ={} | |
s.deploy =wfc(selection,"Deploy") | |
s.loadout =wfc(selection,"Loadout") | |
s.menu =wfc(selection,"Menu") | |
s.option =wfc(selection,"Option") | |
local chatgui =wfc(pgui,"Chat") | |
local chatbox =wfc(chatgui,"TextBox") | |
local controllermenu =false | |
local iswindows =guiservice.IsWindows | |
local deploying =false | |
local curgun | |
local function updategunmodel(newgun) | |
modelfolder:ClearAllChildren() | |
local findgun=newgun and ffc(gunmodels,newgun) or ffc(gunmodels,slotprim) | |
if findgun then | |
curgun=findgun:Clone() | |
curgun.Parent=modelfolder | |
curgun.PrimaryPart=curgun:WaitForChild("Trigger") | |
curgun:SetPrimaryPartCFrame(cf(stand.Position+v3(0,3,0))) | |
end | |
end | |
local slist={menu=mainmenu,option=mainoption,loadout=mainloadout} | |
local function mainswitch(type) | |
for i,v in next,slist do | |
v.Visible=false | |
end | |
slist[type].Visible=true | |
end | |
do ---loadout submodule | |
local loadbar =wfc(layout,"Loadout") | |
local menuclasses =wfc(mainmenu,"Classes") | |
local primbut =wfc(wfc(loadbar,"Primary"),"Select") | |
local sidebut =wfc(wfc(loadbar,"Secondary"),"Select") | |
local loadbartitle =wfc(loadbar,"Title") | |
local gunselection =wfc(mainloadout,"GunSelection") | |
local loadclasses =wfc(mainloadout,"Classes") | |
local primarybuttons =wfc(gunselection,"Primary") | |
local gunfolder =wfc(gunselection,"GunList") | |
local classb =menuclasses:GetChildren() | |
local classb2 =loadclasses:GetChildren() | |
local primb =primarybuttons:GetChildren() | |
local primfr =wfc(mainloadout,"Primary") | |
local sidefr =wfc(mainloadout,"Secondary") | |
local selectedslot ="Primary" | |
local gunb =wfc(source,"gun") | |
local curtype ="ASSAULT RIFLE" | |
local gunclass={ | |
Assault ={"ASSAULT RIFLE","MARKSMAN","CARBINE","SHOTGUN"}; | |
Engineer ={"PDW","MARKSMAN","CARBINE","SHOTGUN"}; | |
Support ={"LMG","MARKSMAN","CARBINE","SHOTGUN"}; | |
Recon ={"SNIPER RIFLE","MARKSMAN","CARBINE","SHOTGUN"}; | |
} | |
local gunlist={ | |
["ASSAULT RIFLE"] ={"AN-94","AK12","G36","AUG A1","SCAR-L",}, | |
["MARKSMAN"] ={"MK11","SKS"}, | |
["PDW"] ={"P90","AS VAL","MP5K","MP7","UMP45",}, | |
["LMG"] ={"M60"}, | |
["SNIPER RIFLE"] ={"INTERVENTION"}, | |
["CARBINE"] ={"M4","G36C"}, | |
["SHOTGUN"] ={"REMINGTON 870"}, | |
["PISTOL"] ={"M9","GLOCK 17","GLOCK 18","MP412 REX","DEAGLE 44"} | |
} | |
local stat={} | |
do--WEAPON ROTATION YAY | |
local userinput=game:GetService("UserInputService") | |
local doshit | |
local pos | |
--WOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOW LITO. WRITE CODE THE RIGHT WAY. Also try shooting | |
--before the round starts with a controller. It FAILS. | |
userinput.InputChanged:connect(function(object) | |
local newpos=object.Position | |
if doshit then | |
local type=object.UserInputType.Name | |
local delta=newpos-pos | |
if type=="MouseMovement" then | |
if curgun and curgun.PrimaryPart then | |
local b=camera.currentcamera.CoordinateFrame | |
local c=b:inverse()*curgun.PrimaryPart.CFrame | |
local rotx=delta.y/256 | |
local roty=delta.x/256 | |
curgun:SetPrimaryPartCFrame((b-b.p)*cframe.fromaxisangle(rotx,roty,0)*(c-c.p)+stand.Position+v3(0,3,0)) | |
end | |
--elseif type=="MouseWheel" then | |
-- fireonscroll(pos.z) | |
end | |
end | |
pos=newpos | |
end) | |
userinput.InputBegan:connect(function(object) | |
local type=object.UserInputType.Name | |
if type=="MouseButton2" then | |
doshit=true | |
end | |
end) | |
userinput.InputEnded:connect(function(object) | |
local type=object.UserInputType.Name | |
if type=="MouseButton2" then | |
doshit=false | |
end | |
end) | |
end | |
do ---stats sub submodule | |
local statfr =wfc(mainloadout,"GunStat") | |
local gname =wfc(statfr,"GName") | |
local damage =wfc(statfr,"Damage") | |
local range =wfc(statfr,"Range") | |
local accuracy =wfc(statfr,"Accuracy") | |
local hip =wfc(statfr,"Hip") | |
local aim =wfc(statfr,"Aim") | |
local firemode =wfc(statfr,"Firemode") | |
local rpm =wfc(statfr,"Rpm") | |
local magsize =wfc(statfr,"Magsize") | |
local ammotype =wfc(statfr,"Ammotype") | |
function stat:update(data) | |
if data then | |
gname.Text=data.name | |
damage.Stat.Text=data.damage0.." -> "..data.damage1 | |
range.Stat.Text=data.range0.." max | "..data.range1.." min" | |
accuracy.Bar.Percent.Size=ud2(0.001/data.hipfirespread^2,0,1,0)---wtf is this arbitrary value shet | |
hip.Bar.Percent.Size=ud2(0.5/data.camkickmax.magnitude^2,0,1,0)---wtf more arbitrary shet | |
aim.Bar.Percent.Size=ud2(0.3/data.aimcamkickmax.magnitude^2,0,1,0) | |
firemode.Stat.Text="|" | |
for i,v in next,data.firemodes do | |
if v==true then | |
firemode.Stat.Text=firemode.Stat.Text.." IIIII |" | |
elseif v==3 then | |
firemode.Stat.Text=firemode.Stat.Text.." III |" | |
elseif v==2 then | |
firemode.Stat.Text=firemode.Stat.Text.." II |" | |
elseif v==1 then | |
firemode.Stat.Text=firemode.Stat.Text.." I |" | |
end | |
end | |
rpm.Stat.Text=type(data.firerate)=="table" and data.firerate[1].." Burst | "..data.firerate[2].." Auto" or data.firerate | |
magsize.Stat.Text=data.magsize | |
end | |
end | |
end | |
local function updateloadout() | |
primfr.GName.Text=slotprim | |
primbut.GName.Text=slotprim | |
sidefr.GName.Text=slotside | |
sidebut.GName.Text=slotside | |
loadbartitle.Text=curclass.." Loadout:" | |
end | |
local function updategunlist(slot,nexttype) | |
if nexttype then curtype=nexttype end | |
gunfolder.Position=ud2(0,0,0,slot=="Primary" and 60 or 0) | |
gunfolder:ClearAllChildren() | |
for i,v in next,slot=="Primary" and gunlist[curtype] or gunlist["PISTOL"] do | |
local ng=gunb:Clone() | |
ng.GName.Text=v | |
ng.Position=ud2(0,0,0,(i-1)*21) | |
ng.Parent=gunfolder | |
ng.Select.MouseButton1Click:connect(function() | |
if slot=="Primary" then | |
slotprim=v | |
classdata[curclass][1]=v | |
else | |
slotside=v | |
classdata[curclass][2]=v | |
end | |
updategunmodel(v) | |
updateloadout() | |
stat:update(require(gunmodules[v])) | |
end) | |
end | |
end | |
local function selected(slot,ntype,open) | |
if open then | |
mainswitch("loadout") | |
end | |
if slot~=selectedslot then | |
updategunmodel(slot=="Primary" and slotprim or slotside) | |
selectedslot=slot | |
end | |
if slot=="Primary" then | |
primarybuttons.Visible=true | |
for i=1,#primb do | |
local v=primb[i] | |
v.Text=gunclass[curclass][i] | |
end | |
else | |
primarybuttons.Visible=false | |
end | |
updategunlist(slot,ntype) | |
stat:update(require(gunmodules[slot=="Primary" and slotprim or slotside])) | |
end | |
local function changeclass(v,goload) | |
curclass=v | |
slotprim=classdata[curclass][1] | |
slotside=classdata[curclass][2] | |
updategunmodel() | |
updateloadout() | |
selected(selectedslot,gunclass[curclass][1],goload) | |
end | |
updateloadout() | |
stat:update(require(gunmodules[slotprim])) | |
for i=1,#primb do | |
local v=primb[i] | |
v.MouseButton1Click:connect(function() | |
curtype=v.Text | |
updategunlist("Primary") | |
end) | |
end | |
for i=1,#classb do | |
local v=classb[i] | |
if rtype(v,"TextButton") then | |
v.MouseButton1Click:connect(function() | |
changeclass(v.Text,curclass==v.Text) | |
end) | |
end | |
end | |
for i=1,#classb2 do | |
local v=classb2[i] | |
v.MouseButton1Click:connect(function() | |
changeclass(v.Text,true) | |
end) | |
end | |
primfr.Edit.MouseButton1Click:connect(function() selected("Primary",gunclass[curclass][1],true) end) | |
primbut.MouseButton1Click:connect(function() selected("Primary",gunclass[curclass][1],true) end) | |
sidefr.Edit.MouseButton1Click:connect(function() selected("Secondary",gunclass["PISTOL"],true) end) | |
sidebut.MouseButton1Click:connect(function() selected("Secondary",gunclass["PISTOL"],true) end) | |
end | |
do ---respawn/deploy/control submodule | |
local spawnfr =wfc(mainmenu,"Spawn") | |
local location =wfc(spawnfr,"Location") | |
local pref =wfc(source,"player") | |
local sref =wfc(source,"spot") | |
local spawnpos =v3() | |
local spawnobj | |
local ranlist =sref:Clone() | |
local ranpick =wfc(ranlist,"Pick") | |
ranlist.Parent=location | |
ranpick.Place.Text="RANDOM LOCATION" | |
ranlist.Box.Text="?" | |
local function updatecontroltype() | |
if deploying then | |
--chatbox.Visible=true | |
guiservice.GuiNavigationEnabled=false | |
controllermenu=false | |
input.mouse:hide() | |
elseif controllermenu then | |
if guiservice.SelectedObject==chatbox then | |
guiservice.SelectedObject=s.deploy | |
end | |
guiservice.GuiNavigationEnabled=true | |
input.mouse:hide() | |
elseif iswindows and layout.Visible then | |
--chatbox.Visible=true | |
input.mouse:show() | |
guiservice.GuiNavigationEnabled=false | |
end | |
end | |
local function squadspawnpos(guy) | |
if not hud:isplayeralive(guy) then return end | |
local root=ffc(guy.Character,"HumanoidRootPart") | |
if not root then return cf(root.CFrame*v3(0,-2,0)).p end | |
camera:setlookvector(root.CFrame.lookVector) | |
local rayback=ray(root.CFrame.p,root.CFrame.lookVector*-9) | |
local hit,pos=raycast(workspace,rayback,{root.Parent,ignore}) | |
if not hit or (hit and (root.CFrame.p-pos).Magnitude > 8) then | |
return cf(root.CFrame*v3(0,0,6)).p | |
end | |
local rayright=ray(root.CFrame.p,(root.CFrame.p-root.CFrame*v3(1,0,0)).unit*-9) | |
local hit,pos=raycast(workspace,rayright,{root.Parent,ignore}) | |
if not hit or (hit and (root.CFrame.p-pos).Magnitude > 6) then | |
return cf(root.CFrame*v3(5,0,0)).p | |
end | |
local rayleft=ray(root.CFrame.p,(root.CFrame.p-root.CFrame*v3(-1,0,0)).unit*-9) | |
local hit,pos=raycast(workspace,rayleft,{root.Parent,ignore}) | |
if not hit or (hit and (root.CFrame.p-pos).Magnitude > 6) then | |
return cf(root.CFrame*v3(-5,0,0)).p | |
end | |
local rayfront=ray(root.CFrame.p,root.CFrame.lookVector*9) | |
local hit,pos=raycast(workspace,rayfront,{root.Parent,ignore}) | |
if not hit or (hit and (root.CFrame.p-pos).Magnitude > 8) then | |
return cf(root.CFrame*v3(0,0,-6)).p | |
end | |
return cf(root.CFrame*v3(0,-2,0)).p | |
end | |
local function normalspawnpos() | |
local furthest =0 | |
local bk =player.TeamColor==BrickColor.new("Bright orange") and "R" or "B" | |
local map =ffc(workspace,"Map") | |
local teleport =ffc(map,"Teleport") | |
local chosen =teleport[bk.."1"]----fix | |
local required =250 | |
local approved | |
repeat | |
chosen=teleport[bk..math.random(1,10)] | |
local pp=game.Players:GetChildren() | |
local disapproved | |
for i=1,#pp do | |
local v=pp[i] | |
if v.TeamColor~=player.TeamColor and hud:isplayeralive(v) and ffc(workspace,v.Name) and v.Character and v.Character.Parent then | |
local ptor=ffc(v.Character,"HumanoidRootPart") | |
if ptor then | |
local dist=(ptor.Position-chosen.Position).magnitude | |
if dist<required then | |
disapproved=true | |
required=required-4 | |
end | |
end | |
end | |
end | |
wait(.01) | |
if not disapproved then approved=true end | |
until approved | |
--print("Furthest distance for enemy is "..ceil(furthest).." studs at block " ..chosen.Name) | |
return cf(chosen.Position+v3(0,3,0)).p | |
end | |
local function deploy() | |
if deploying or not allowspawn.Value or not ffc(workspace,"Map") or menu:isdeployed() then return end | |
deploying=true | |
updatecontroltype() | |
menu:hide() | |
chat:ingame() | |
loadmodules(slotprim,slotside) | |
spawnpos=spawnobj and squadspawnpos(spawnobj) or normalspawnpos() | |
char:spawn(spawnpos) | |
repeat wait(0.1) until char.health>0 and gamelogic.currentgun | |
camera.type="firstperson" | |
gamelogic.currentgun:setequipped(true) | |
hud:enablegamegui(true) | |
deploying=false | |
spawnobj=nil | |
end | |
function menu:isdeployed() | |
return not layout.Visible | |
end | |
function menu:roundstartspawn() | |
deploy() | |
end | |
function menu:hide() | |
local frs=menugui:GetChildren() | |
for i=1,#frs do | |
frs[i].Visible=false | |
end | |
end | |
function menu:loadmenu() | |
gamelogic.currentgun=nil | |
chat:inmenu() | |
hud:reloadhud() | |
hud:enablegamegui(false) | |
input.mouse:show() | |
menu:hide() | |
layout.Visible=true | |
mainmenu.Visible=true | |
lobby.Parent=game.Workspace--camera.currentcamera | |
camera:setmenucam(lobby) | |
updategunmodel() | |
updatecontroltype() | |
end | |
local function updatespawnlist() | |
local list=location:GetChildren() | |
for i=1,#list do | |
local v=list[i] | |
if v.Name=="player" then | |
v.Pick.BackgroundColor3=color(0,0,0) | |
v.Box1.BackgroundColor3=color(0,0,0) | |
v.Box2.BackgroundColor3=color(0,0,0) | |
elseif v.Name=="spot" then | |
v.Pick.BackgroundColor3=color(0,0,0) | |
end | |
end | |
end | |
function menu:refreshspawn() | |
local lt=location:GetChildren() | |
for i=1,#lt do | |
local v=lt[i] | |
if v~=ranlist then | |
local p=ffc(game.Players,lt[i].Name) | |
if p and p.Character then | |
local head=ffc(p.Character,"Head") | |
if not head or p.TeamColor~=player.TeamColor or not hud:isplayeralive(p) or (head.Position-workspace.Lobby.Spawn.Position).Magnitude<300 then | |
v:Destroy() | |
end | |
else | |
v:Destroy() | |
end | |
end | |
end | |
if not location then return end | |
local count=0 | |
local ppl=game.Players:GetChildren() | |
for i=1,#ppl do | |
local v=ppl[i] | |
if v.TeamColor==player.TeamColor and hud:isplayeralive(v) and not ffc(location,v.Name) and v.Character and v.Character.Parent then | |
local head=ffc(v.Character,"Head") | |
if head and (head.Position-workspace.Lobby.Spawn.Position).Magnitude>300 then | |
local list=pref:Clone() | |
local cur=spawnobj==v | |
list.Name=v.Name | |
list.Pick.Player.Text=v.Name | |
list.Parent=location | |
list.Position=ud2(0,0,0,20*(count)) | |
list.Pick.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
list.Box1.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
list.Box2.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
list.Pick.MouseButton1Down:connect(function() | |
if deploying or not head or not ffc(list,"Pick") then return end | |
if ffc(list.Pick,"DoubleClick") then | |
deploy() | |
else | |
local dc=new("IntValue",list.Pick) | |
dc.Name="DoubleClick" | |
game.Debris:AddItem(dc,1) | |
spawnobj=v | |
updatespawnlist() | |
list.Pick.BackgroundColor3=color(1,1,1) | |
list.Box1.BackgroundColor3=color(1,1,1) | |
list.Box2.BackgroundColor3=color(1,1,1) | |
camera:setspectate(v,head) | |
end | |
end) | |
count=count+1 | |
end | |
elseif ffc(location,v.Name) then | |
local list=location[v.Name] | |
local cur=spawnobj==v | |
list.Position=ud2(0,0,0,20*(count)) | |
list.Pick.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
list.Box1.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
list.Box2.BackgroundColor3=not cur and color(0,0,0) or color(1,1,1) | |
count=count+1 | |
end | |
end | |
if spawnobj and spawnobj.Character and ffc(workspace,spawnobj.Name) then | |
local head=ffc(spawnobj.Character,"Head") | |
if not head or (head.Position-workspace.Lobby.Spawn.Position).Magnitude<300 or not hud:isplayeralive(spawnobj) then | |
camera:setmenucam(lobby) | |
spawnobj=nil | |
end | |
end | |
ranpick.BackgroundColor3=spawnobj and color(0,0,0) or color(1,1,1) | |
ranlist.Position=ud2(0,0,0,count*20) | |
end | |
ranpick.MouseButton1Down:connect(function() | |
if deploying then return end | |
if ffc(ranlist.Pick,"DoubleClick") then | |
deploy() | |
else | |
local dc=new("IntValue",ranpick) | |
dc.Name="DoubleClick" | |
game.Debris:AddItem(dc,1) | |
spawnobj=nil | |
updatespawnlist() | |
camera:setmenucam(lobby) | |
end | |
end) | |
guiservice:RemoveSelectionGroup(chatbox.Name) | |
guiservice.Changed:connect(function() controllermenu=guiservice.SelectedObject updatecontroltype() end) | |
s.deploy.MouseButton1Click:connect(deploy) | |
game:GetService("UserInputService").InputBegan:connect(function(keycode) | |
local key=keycode.KeyCode | |
if key==Enum.KeyCode.Space and not chatbox.Active and not menu:isdeployed() then | |
deploy() | |
end | |
end) | |
s.deploy.MouseEnter:connect(function() | |
if deploying or not allowspawn.Value or not ffc(workspace,"Map") then s.deploy.Text="CANNOT DEPLOY YET" end | |
end) | |
s.deploy.MouseLeave:connect(function() s.deploy.Text="DEPLOY" end) | |
end | |
do -- options submodule | |
local looksen =wfc(mainoption,"LookSen") | |
local b =looksen:GetChildren() | |
local list = { | |
["B1"] = -5, | |
["B2"] = -4, | |
["B3"] = -3, | |
["B4"] = -2, | |
["B5"] = -1, | |
["B6"] = -0, | |
["B7"] = 1, | |
["B8"] = 2, | |
["B9"] = 3, | |
} | |
local revlist = { | |
[-5] = "B1", | |
[-4] = "B2", | |
[-3] = "B3", | |
[-2] = "B4", | |
[-1] = "B5", | |
[0] = "B6", | |
[1] = "B7", | |
[2] = "B8", | |
[3] = "B9", | |
} | |
function update() | |
for i=1,#b do | |
if rtype(b[i],"TextButton") then | |
b[i].BackgroundColor3=color(26/255,26/255,26/255) | |
if revlist[camera.senvalue]==b[i].Name then | |
b[i].BackgroundColor3=color(37/255,111/255,0) | |
end | |
end | |
end | |
end | |
for i=1,#b do | |
if rtype(b[i],"TextButton") then | |
b[i].MouseButton1Click:connect(function() camera:setsensitivity(list[b[i].Name]) update() end) | |
end | |
end | |
update() | |
end | |
s.loadout.MouseButton1Click:connect(function() mainswitch("loadout") end) | |
s.menu.MouseButton1Click:connect(function() mainswitch("menu") end) | |
s.option.MouseButton1Click:connect(function() mainswitch("option") end) | |
network:add("autodespawn",function() | |
if gamelogic.currentgun then | |
gamelogic.currentgun:setequipped(false,true) | |
end | |
menu:loadmenu() | |
char:setmovementmode("stand") | |
end) | |
function menu.step() | |
if run.time>lasttime+refreshint then | |
menu:refreshspawn() | |
lasttime=lasttime+refreshint | |
end | |
end | |
end | |
--roundsystem module | |
--By litozinnamon | |
print("Loading roundsystem module") | |
do | |
local rtype =game.IsA | |
local next =next | |
local new =Instance.new | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local getchildren =game.GetChildren | |
local workspace =game.Workspace | |
local cf =CFrame.new | |
local vtws =CFrame.new().vectorToWorldSpace | |
local angles =CFrame.Angles | |
local ud2 =UDim2.new | |
local color =Color3.new | |
local bcolor =BrickColor.new | |
local v3 =Vector3.new | |
local debris =game.Debris | |
local guiservice =game:GetService("GuiService") | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local ceil =math.ceil | |
local floor =math.floor | |
local repstore =game.ReplicatedStorage | |
local settings =repstore.ServerSettings | |
local countdown =settings.Countdown | |
local timer =settings.Timer | |
local maxscore =settings.MaxScore | |
local gscore =settings.GhostScore | |
local pscore =settings.PhantomScore | |
local showresult =settings.ShowResults | |
local setquote =settings.Quote | |
local winner =settings.Winner | |
local player =game.Players.LocalPlayer | |
local pgui =player.PlayerGui | |
local main =wfc(pgui,"MainGui") | |
local countfr =wfc(main,"CountDown") | |
local teamname =wfc(countfr,"TeamName") | |
local title =wfc(countfr,"Title") | |
local number =wfc(countfr,"Number") | |
local tip =wfc(countfr,"Tip") | |
local gamegui =wfc(main,"GameGui") | |
local roundfr =wfc(gamegui,"Round") | |
local scorefr =wfc(roundfr,"Score") | |
local ghostfr =wfc(scorefr,"Ghosts") | |
local phantomfr =wfc(scorefr,"Phantoms") | |
local counting =wfc(scorefr,"Time") | |
local endfr =wfc(main,"EndMatch") | |
local quote =wfc(endfr,"Quote") | |
local result =wfc(endfr,"Result") | |
local servertime =0 | |
local lasttime =0 | |
roundsystem.lock =false | |
local function spawnplayer() | |
menu:roundstartspawn() | |
end | |
local function tweentransparency(obj,index,new,t) | |
spawn(function() | |
local cur=obj[index] | |
for i=cur,new+t,t do | |
obj[index]=i | |
wait(1/30) | |
end | |
end) | |
end | |
if player.TeamColor==game.Teams.Ghosts.TeamColor then | |
ghostfr.Position=ud2(0, 10,0, 45) | |
phantomfr.Position=ud2(0, 10,0, 27) | |
end | |
local function updatescore() | |
local ud2=UDim2.new | |
ghostfr.Full.Percent.Size=ud2(gscore.Value/maxscore.Value,0,1,0) | |
ghostfr.Full.Point.Text=gscore.Value | |
phantomfr.Full.Percent.Size=ud2(pscore.Value/maxscore.Value,0,1,0) | |
phantomfr.Full.Point.Text=pscore.Value | |
end | |
local function count() | |
roundsystem.lock=true | |
if timer.Value==10 and not menu:isdeployed() then | |
spawnplayer() | |
end | |
if menu:isdeployed() and char.health and char.health>0 then | |
countfr.Visible=true | |
number.FontSize=9 | |
number.Text=timer.Value | |
for i = 9,7,-1 do | |
number.FontSize=i | |
wait(1/30) | |
end | |
if timer.Value==0 then | |
wait(1) | |
teamname.Text=player.TeamColor==game.Teams.Ghosts.TeamColor and "Ghosts" or "Phantoms" | |
tweentransparency(countfr,"BackgroundTransparency",1,0.05) | |
tweentransparency(title,"TextTransparency",1,0.1) | |
tweentransparency(number,"TextTransparency",1,0.1) | |
tweentransparency(title,"TextStrokeTransparency",1.3,0.1) | |
tweentransparency(tip,"TextTransparency",1,0.1) | |
roundsystem.lock=false | |
wait(1) | |
tweentransparency(teamname,"TextTransparency",0,0.2) | |
tweentransparency(teamname,"TextStrokeTransparency",0.3,0.2) | |
tweentransparency(teamname,"BackgroundTransparency",0.4,0.2) | |
wait(4) | |
tweentransparency(teamname,"TextTransparency",1,0.1) | |
tweentransparency(teamname,"TextStrokeTransparency",1.3,0.1) | |
tweentransparency(teamname,"BackgroundTransparency",1,0.1) | |
wait(2) | |
countfr.Visible=false | |
else | |
countfr.BackgroundTransparency=0.5 | |
number.TextTransparency=0 | |
title.TextTransparency=0 | |
title.TextStrokeTransparency=0.5 | |
end | |
end | |
end | |
local function matchclock() | |
local seconds=timer.Value%60 | |
if seconds<10 then | |
seconds="0"..seconds | |
end | |
counting.Text=floor(timer.Value/60)..":"..seconds | |
end | |
local function timerchange() | |
if countdown.Value then | |
counting.Text="COUNTDOWN" | |
count() | |
else | |
if not showresult.Value then | |
roundsystem.lock=false | |
end | |
countfr.Visible=false | |
matchclock() | |
end | |
end | |
local function setresult() | |
if showresult.Value then | |
roundsystem.lock=true | |
quote.Text=setquote.Value | |
endfr.Visible=true | |
if winner.Value==player.TeamColor then | |
result.Text="VICTORY" | |
result.TextColor=bcolor("Bright green") | |
elseif winner.Value==bcolor("Black") then | |
result.Text="STALEMATE" | |
result.TextColor=bcolor("Bright orange") | |
else | |
result.Text="DEFEAT" | |
result.TextColor=bcolor("Bright red") | |
end | |
else | |
endfr.Visible=false | |
end | |
end | |
if countdown.Value then count() end | |
setresult() | |
timer.Changed:connect(timerchange) | |
gscore.Changed:connect(updatescore) | |
pscore.Changed:connect(updatescore) | |
showresult.Changed:connect(setresult) | |
updatescore() | |
end | |
--run module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading run module") | |
do | |
run.time =tick() | |
run.dt =1/60 | |
run.framerate =60 | |
run.onstep ={} | |
run.onthink ={} | |
local tick =tick | |
local renderstepped =game:GetService("RunService").RenderStepped | |
local wait =renderstepped.wait | |
local p =game.Players.LocalPlayer | |
local daytime =game.ReplicatedStorage.ServerSettings.TimeOfDay | |
local engine ={ | |
input.step; | |
char.step; | |
replication.step; | |
camera.step; | |
particle.step; | |
char.animstep; | |
tween.step; | |
hud.step; | |
menu.step; | |
notify.step; | |
} | |
local mainlogic ={ | |
{func=function() | |
if char.health and char.health>0 and gamelogic.currentgun then | |
network:send("pingcheck",p,char.rootpart.Position) | |
end | |
game.Lighting:SetMinutesAfterMidnight(daytime.Value) | |
end; | |
interval=0.5; | |
lasttime=run.time;}; | |
} | |
local fireonstep =event.new(run.onstep) | |
local fireonthink =event.new(run.onthink) | |
function run.wait() | |
wait(renderstepped) | |
end | |
renderstepped:connect(function() | |
local newtime=tick() | |
run.dt=newtime-run.time | |
run.time=newtime | |
run.framerate=0.95*run.framerate+0.05/run.dt | |
for i=1,#engine do | |
engine[i](run.dt) | |
end | |
for i=1,#mainlogic do | |
local v=mainlogic[i] | |
if run.time>v.lasttime+v.interval then | |
v.func(run.dt) | |
v.lasttime=v.lasttime+v.interval | |
end | |
end | |
fireonstep(run.dt) | |
end) | |
game:GetService("RunService").Stepped:connect(function() | |
fireonthink() | |
end) | |
end | |
--game logic module | |
--By litozinnamon | |
print("Loading game logic module") | |
do | |
local ffc =game.FindFirstChild | |
local rep =game.ReplicatedStorage | |
local player =game.Players.LocalPlayer | |
local pgui =player.PlayerGui | |
local gunlist ={} | |
local gunnumber =1 | |
local curknife,dived,jumping,aiming,equipping,prevgun,grenade,spotting | |
gamelogic.currentgun =nil | |
local function switch(z) | |
if not equipping and gamelogic.currentgun then | |
gunnumber=(gunnumber+z-1)%#gunlist+1 | |
if gunlist[gunnumber] then | |
gamelogic.currentgun=gunlist[gunnumber] | |
gamelogic.currentgun:setequipped(true) | |
equipping=true | |
wait(0.4) | |
equipping=false | |
end | |
end | |
end | |
function loadmodules(prim,side,knife) | |
gunlist={} | |
gunnumber=1 | |
local vprim=ffc(pgui.GModule,prim) | |
if vprim then | |
local v=vprim:Clone() | |
gunlist[1]=char:loadgun(require(v),pgui.GModel[prim]:Clone()) | |
end | |
local vside=ffc(pgui.GModule,side) | |
if vside then | |
local v=vside:Clone() | |
gunlist[2]=char:loadgun(require(v),pgui.GModel[side]:Clone()) | |
end | |
local knife=knife or "KNIFE" | |
local vknife=ffc(pgui.GModule,knife) | |
if vknife then | |
local v=vknife:Clone() | |
curknife=char:loadknife(require(v),pgui.GModel[knife]:Clone()) | |
end | |
gamelogic.currentgun=gunlist[gunnumber] | |
end | |
input.mouse.onbuttondown:connect(function(button) | |
if not gamelogic.currentgun then return end | |
if button=="left" and gamelogic.currentgun.shoot then | |
gamelogic.currentgun:shoot(true) | |
elseif button=="right" then | |
if gamelogic.currentgun.setaim then | |
aiming=true | |
gamelogic.currentgun:setaim(true) | |
end | |
end | |
end) | |
input.mouse.onscroll:connect(switch) | |
input.mouse.onbuttonup:connect(function(button) | |
if not gamelogic.currentgun then return end | |
if button=="left" and gamelogic.currentgun.shoot then | |
gamelogic.currentgun:shoot(false) | |
elseif button=="right" then | |
if gamelogic.currentgun.setaim then | |
aiming=false | |
gamelogic.currentgun:setaim(false) | |
end | |
end | |
end) | |
input.keyboard.onkeydown:connect(function(key) | |
if not gamelogic.currentgun then return end | |
if key=="space" and not jumping then | |
jumping=true | |
char:jump() | |
wait(1) | |
jumping=false | |
elseif key=="c" then | |
if char:sprinting() and not dived then | |
dived=true | |
char:setmovementmode("crouch",dived) | |
wait(1.5) | |
dived=false | |
else | |
char:setmovementmode(char.movementmode=="crouch" and "prone" or "crouch") | |
end | |
elseif key=="x" then | |
if input.keyboard.down["leftshift"] and not dived then | |
dived=true | |
char:setmovementmode("prone",dived) | |
wait(1.5) | |
dived=false | |
else | |
char:setmovementmode(char.movementmode=="crouch" and "stand" or "crouch") | |
end | |
elseif key=="leftcontrol" then | |
char:setmovementmode("prone") | |
elseif key=="z" then | |
if input.keyboard.down["leftshift"] and not dived then | |
dived=true | |
char:setmovementmode("prone",dived) | |
wait(1.5) | |
dived=false | |
else | |
char:setmovementmode("stand") | |
end | |
elseif key=="r" then | |
if gamelogic.currentgun.reload then | |
gamelogic.currentgun:reload() | |
end | |
elseif key=="e" then | |
if gamelogic.currentgun.playanimation and not spotting then | |
spotting=true | |
gamelogic.currentgun:playanimation("spot") | |
wait(2) | |
spotting=false | |
end | |
elseif key=="f" then | |
if curknife and gamelogic.currentgun~=curknife then | |
prevgun=gamelogic.currentgun | |
gamelogic.currentgun=curknife | |
elseif gamelogic.currentgun==curknife then | |
gamelogic.currentgun=prevgun | |
end | |
gamelogic.currentgun:setequipped(true) | |
equipping=true | |
wait(0.5) | |
equipping=false | |
elseif key=="g" then | |
if not char.grenadehold then | |
prevgun=gamelogic.currentgun | |
grenade=char:loadgrenade(require(pgui.GModule["FRAG"]),pgui.GModel["FRAG"]:Clone()) | |
grenade:setequipped(true) | |
equipping=true | |
wait(0.3) | |
equipping=false | |
grenade:pull() | |
end | |
elseif key=="h" then | |
if not char.grenadehold then | |
gamelogic.currentgun:playanimation("inspect") | |
end | |
elseif key=="leftshift" then | |
if aiming and gamelogic.currentgun.type=="Sniper" then | |
camera:setsway(0) | |
else | |
if dived then | |
char:setmovementmode("stand") | |
else | |
char:setsprint(true) | |
end | |
end | |
elseif key=="q" then | |
if gamelogic.currentgun.setaim then | |
aiming=not aiming | |
gamelogic.currentgun:setaim(aiming) | |
end | |
elseif key=="p" then | |
if input.mouse:visible() then | |
input.mouse:hide() | |
else | |
input.mouse:show() | |
end | |
elseif key=="o" then | |
if input.mouse:visible() then | |
input.mouse:hide() | |
input.mouse:lockcenter() | |
else | |
input.mouse:show() | |
input.mouse:free() | |
end | |
elseif key=="v" then | |
if gamelogic.currentgun.nextfiremode then | |
gamelogic.currentgun:nextfiremode() | |
end | |
elseif key=="one" then | |
switch(1) | |
elseif key=="two" then | |
switch(-1) | |
end | |
end) | |
input.keyboard.onkeyup:connect(function(key) | |
if not gamelogic.currentgun then return end | |
if key=="leftshift" then | |
if aiming and gamelogic.currentgun.type=="Sniper" then | |
camera:setsway(25) | |
else | |
char:setsprint(false) | |
end | |
end | |
end) | |
input.controller:map("a","space") | |
input.controller:map("x","r") | |
--input.controller:map("l1","leftshift") | |
input.controller:map("r1","g") | |
input.controller:map("up","h") | |
input.controller:map("r3","f") | |
input.controller:map("right","v") | |
input.controller:map("down","e") | |
input.controller.onbuttondown:connect(function(button) | |
if not gamelogic.currentgun then return end | |
if button=="b" then | |
if char.movementmode=="crouch" then | |
char:setmovementmode("prone") | |
else | |
if char:sprinting() and not dived then | |
dived=true | |
char:setmovementmode("crouch",dived) | |
wait(1.5) | |
dived=false | |
else | |
char:setmovementmode("crouch") | |
end | |
end | |
elseif button=="r2" and gamelogic.currentgun.shoot then | |
gamelogic.currentgun:shoot(true) | |
elseif button=="l2" and gamelogic.currentgun.setaim then | |
aiming=true | |
gamelogic.currentgun:setaim(true) | |
elseif button=="l3" then | |
if aiming and gamelogic.currentgun.type=="Sniper" then | |
camera:setsway(0) | |
elseif char.sprinting() and not dived then | |
dived=true | |
char:setmovementmode("prone",dived) | |
wait(1.5) | |
dived=false | |
else | |
gamelogic.currentgun:playanimation("spot") | |
end | |
elseif button=="y" then | |
switch(1) | |
elseif button=="left" then | |
switch(-1) | |
elseif button=="l1" then | |
char:setsprint(not char:sprinting()) | |
end | |
end) | |
input.controller.onbuttonup:connect(function(button) | |
if not gamelogic.currentgun then return end | |
if button=="r2" then | |
gamelogic.currentgun:shoot(false) | |
elseif button=="l2" and gamelogic.currentgun.setaim then | |
aiming=false | |
gamelogic.currentgun:setaim(false) | |
elseif button=="l3" then | |
if aiming and gamelogic.currentgun.type=="Sniper" then | |
camera:setsway(25) | |
end | |
end | |
end) | |
run.onstep:connect(function() | |
if not gamelogic.currentgun then return end | |
if input.controller.down.b and input.controller.down.b+0.5<tick() and char.movementmode~="prone" then | |
char:setmovementmode("prone") | |
end | |
end) | |
char.oncharacterspawn:connect(function() | |
menu:loadmenu() | |
end) | |
char.ondied:connect(function() | |
if gamelogic.currentgun then | |
gamelogic.currentgun:setequipped(false,true) | |
end | |
wait(5) | |
menu:loadmenu() | |
char:setmovementmode("stand") | |
end) | |
char:loadarms(rep.Character["Left Arm"],rep.Character["Right Arm"],"Arm","Arm") | |
hud:reloadhud() | |
menu:loadmenu() | |
end | |
----------------------------------- | |
--return {vector=vector,cframe=cframe,utility=utility,event=event,physics=physics,tween=tween,run=run} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local event={} | |
local network={} | |
local startergui={} | |
local playerstates={} | |
local vector={} | |
local environment={} | |
local roundsystem={} | |
--event module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading event module") | |
do | |
function event.new(eventtable) | |
local self=eventtable or {} | |
local removelist ={} | |
local functions ={} | |
local pendingdeletion =false | |
function self:connect(func) | |
functions[#functions+1]=func | |
return function() | |
removelist[func]=true | |
pendingdeletion=true | |
end | |
end | |
return function(...) | |
if pendingdeletion then | |
pendingdeletion=false | |
local j=1 | |
for i=1,#functions do | |
local f=functions[i] | |
functions[i]=nil | |
if removelist[f] then | |
removelist[f]=nil | |
else | |
f(...) | |
functions[j]=f | |
j=j+1 | |
end | |
end | |
else | |
for i=1,#functions do | |
functions[i](...) | |
end | |
end | |
end, | |
self | |
end | |
end | |
--network module | |
--by Axis Angle (Trey Reynolds) | |
print("Loading network module") | |
do | |
local type =type | |
local remove =table.remove | |
local bounceevent =game.ReplicatedStorage:WaitForChild("BounceEvent") | |
local remoteevent =game.ReplicatedStorage:WaitForChild("RemoteEvent") | |
local remotefunc =game.ReplicatedStorage:WaitForChild("RemoteFunction") | |
local fireclient =remoteevent.FireClient | |
local fireall =remoteevent.FireAllClients | |
local invokeclient =remotefunc.InvokeClient | |
local funcs ={} | |
local listeners ={} | |
local tickdiscs ={} | |
local pings ={} | |
local pingrate =1 | |
local lastping =tick() | |
local players =game.Players:GetPlayers() | |
network.players =players | |
function network:add(name,func) | |
funcs[name]=func | |
end | |
function network:listen(name,func) | |
listeners[name]=func | |
end | |
function network:send(player,name,...) | |
local listener=listeners[name] | |
if listener then | |
listener(...) | |
end | |
if type(player)=="table" then | |
for i=1,#player do | |
fireclient(remoteevent,player[i],name,...) | |
end | |
else | |
fireclient(remoteevent,player,name,...) | |
end | |
end | |
function network:bounce(name,...) | |
local listener=listeners[name] | |
if listener then | |
listener(...) | |
end | |
fireall(bounceevent,name,...) | |
end | |
function network:fetch(player,...) | |
if type(player)=="table" then | |
local returns={} | |
for i=1,#player do | |
local p=player[i] | |
returns[p]={invokeclient(remotefunc,p,...)} | |
end | |
return returns | |
else | |
return invokeclient(remotefunc,player,...) | |
end | |
end | |
local function getping(player) | |
return pings[player] or 0 | |
end | |
network.ping=getping | |
function network.toplayertick(player,tick) | |
return tick+(tickdiscs[player] or 0) | |
end | |
function network.fromplayertick(player,tick) | |
return tick-(tickdiscs[player] or 0) | |
end | |
local function call(player,name,...) | |
local func=funcs[name] | |
if func then | |
return func(...) | |
end | |
end | |
--good song https://www.youtube.com/watch?v=bHaFY4wjygM | |
bounceevent.OnServerEvent:connect(function(player,name,...) | |
local listener=listeners[name] | |
if listener then | |
listener(...) | |
end | |
for i=1,#players do | |
local otherplayer=players[i] | |
if otherplayer~=player then | |
fireclient(bounceevent,otherplayer,name,...) | |
end | |
end | |
end) | |
remoteevent.OnServerEvent:connect(call) | |
remotefunc.OnServerInvoke=call | |
network:add("ping",function(senttick,player,playertick) | |
local time=tick() | |
local curtickdisc=tickdiscs[player] | |
if curtickdisc then | |
tickdiscs[player]=0.9*curtickdisc+0.1*(playertick-(time+senttick)/2) | |
else | |
tickdiscs[player]=(playertick-(time+senttick)/2) | |
end | |
pings[player]=0.9*getping(player)+0.1*(time-senttick)/2 | |
end) | |
game:GetService("RunService").Stepped:connect(function() | |
local time=tick() | |
if 1/pingrate<time-lastping then | |
lastping=time | |
network:bounce("ping",time) | |
end | |
end) | |
game.Players.PlayerAdded:connect(function(player) | |
players[#players+1]=player | |
network:send(player,"ping",tick()) | |
end) | |
game.Players.PlayerRemoving:connect(function(player) | |
for i=1,#players do | |
if player==players[i] then | |
remove(players,i) | |
end | |
end | |
end) | |
end | |
--startergui module | |
--By litozinnamon | |
print("Loading startergui module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local ceil =math.ceil | |
local cf =CFrame.new | |
local v3 =Vector3.new | |
local color =Color3.new | |
local dot =Vector3.new().Dot | |
local workspace =workspace | |
local ray =Ray.new | |
local new =Instance.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local infolder =function(l,e) for i=1,#l do if l[i].Name==e then return l[i] end end end | |
local rtype =game.IsA | |
local debris =game.Debris | |
local playertag =game.ReplicatedStorage.Character.PlayerTag | |
local gui =game.StarterGui | |
local misc =game.ReplicatedStorage.Misc | |
local playerstat =misc.Player | |
local board =wfc(gui,"Leaderboard") | |
local main =wfc(board,"Main") | |
local global =wfc(board,"Global") | |
local ghost =wfc(main,"Ghosts") | |
local phantom =wfc(main,"Phantoms") | |
local ghostdata =wfc(wfc(ghost,"DataFrame"),"Data") | |
local phantomdata =wfc(wfc(phantom,"DataFrame"),"Data") | |
ghostdata:ClearAllChildren() | |
phantomdata:ClearAllChildren() | |
function organize() | |
local gd=ghostdata:GetChildren() | |
for i=1,#gd do | |
gd[i].Position=ud2(0,0,0,i*25) | |
end | |
ghostdata.Parent.CanvasSize=ud2(0,0,0,(#gd+1)*25) | |
local pd=phantomdata:GetChildren() | |
for i=1,#pd do | |
pd[i].Position=ud2(0,0,0,i*25) | |
end | |
phantomdata.Parent.CanvasSize=ud2(0,0,0,(#pd+1)*25) | |
end | |
function startergui:addplayer(guy) | |
local gbar=ffc(ghostdata,guy.Name) | |
local pbar=ffc(phantomdata,guy.Name) | |
if gbar or pbar then return end | |
local bar=playerstat:Clone() | |
bar.Name=guy.Name | |
bar.Username.Text=guy.Name | |
bar.Kills.Text=0 | |
bar.Deaths.Text=0 | |
bar.Streak.Text=0 | |
bar.Score.Text=0 | |
bar.Kdr.Text=0 | |
bar.Rank.Text=0 | |
bar.Parent=guy.TeamColor==game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
organize() | |
network:bounce("newplayer",guy) | |
end | |
function startergui:removeplayer(guy) | |
local gbar=ffc(ghostdata,guy.Name) | |
local pbar=ffc(phantomdata,guy.Name) | |
if gbar then gbar:Destroy() end | |
if pbar then pbar:Destroy() end | |
organize() | |
network:bounce("removeplayer",guy) | |
end | |
function startergui:updatestats(guy,data) | |
local rightparent=guy.TeamColor==game.Teams.Ghosts.TeamColor and ghostdata or phantomdata | |
local bar=ffc(rightparent,guy.Name) | |
if bar then | |
for i,v in next,data do | |
bar[i].Text=v | |
end | |
end | |
network:bounce("updatestats",guy,data) | |
end | |
game.Players.PlayerRemoving:connect(function(player) startergui:removeplayer(player) end) | |
end | |
--playerstates module | |
--by Axis Angle (Trey Reynolds) | |
print("Loading playerstates module") | |
do | |
local assert =assert | |
local cf =CFrame.new | |
local rtype =game.IsA | |
local repchar =game.ReplicatedStorage.Character | |
local ffc =game.FindFirstChild | |
local v3 =Vector3.new | |
local states ={} | |
local players =network.players | |
local deathcframe =cf(0,300,0) | |
playerstates.ondied ={} | |
playerstates.onhealthchanged={} | |
--health is calculated with a simple linear equation | |
--health0+(tick()-healtick0)*healrate | |
--And then is constrained between health0 and maxhealth | |
--Which means there are 4 constants which need to be resent everytime | |
--to form the equation. Oh well. | |
--healtick0 is a time. Must be converted to the other people's tick stuff before sending. | |
local fireondied=event.new(playerstates.ondied) | |
local fireonhealthchanged=event.new(playerstates.onhealthchanged) | |
local function getstate(player) | |
local state=states[player] | |
if not state then | |
state={} | |
states[player]=state | |
end | |
return state | |
end | |
local function setuphealth(player,maxhealth,healrate,healwait) | |
local state=getstate(player) | |
local healthstate=state.healthstate | |
if not healthstate then | |
healthstate={} | |
state.healthstate=healthstate | |
end | |
healthstate.maxhealth=maxhealth | |
healthstate.healrate=healrate | |
healthstate.healwait=healwait | |
healthstate.alive=false | |
end | |
local function setupstats(player) | |
local state=getstate(player) | |
local stats=state.stats | |
if not stats then | |
stats={} | |
state.stats=stats | |
end | |
---leaderboard stats | |
stats.kills=0 | |
stats.deaths=0 | |
stats.streak=0 | |
stats.score=0 | |
---player stats---oh god i need some sort of datastore module | |
stats.totalkills=0 | |
stats.totaldeaths=0 | |
stats.rank=0 | |
stats.experience=0 | |
--- | |
startergui:addplayer(player) | |
end | |
local function replicatehealthstate(player,actor) | |
local healthstate=getstate(player).healthstate | |
if healthstate then | |
local health0=healthstate.health0 | |
local healtick0=healthstate.healtick0 | |
local healrate=healthstate.healrate | |
local maxhealth=healthstate.maxhealth | |
local alive=healthstate.alive | |
network:send(player,"updatepersonalhealth",health0,network.toplayertick(player,healtick0),healrate,maxhealth,alive,actor) | |
--print("blah sfgheiruhgeirhgeiurhg",player) | |
for i=1,#players do | |
local otherplayer=players[i] | |
if player~=otherplayer then | |
network:send(otherplayer,"updateothershealth",player,health0,network.toplayertick(otherplayer,healtick0),healrate,maxhealth,alive) | |
end | |
end | |
else | |
print("lel stupid glitch") | |
end | |
end | |
local function spawn(player,position,health) | |
local state=getstate(player) | |
local healthstate=state.healthstate | |
local bodyparts=state.bodyparts | |
if healthstate and bodyparts and bodyparts.rootpart then | |
--print("spawning") | |
assert(position,"NEEDZ MOAR POSITION")--never used this before pls work | |
healthstate.health0=health or healthstate.maxhealth | |
healthstate.healtick0=tick() | |
healthstate.alive=true | |
local char=player.Character | |
local shet=char:GetChildren() | |
for i=1,#shet do | |
local v=shet[i] | |
if rtype(v,"Hat") or rtype(v,"CharacterMesh") or rtype(v,"Shirt") or rtype(v,"Pants") then v:Destroy() end | |
end | |
if player.TeamColor.Name=="Bright orange" then | |
repchar.GhostP:Clone().Parent=char | |
repchar.GhostS:Clone().Parent=char | |
else | |
repchar.PhantomsP:Clone().Parent=char | |
repchar.PhantomsS:Clone().Parent=char | |
end | |
replicatehealthstate(player) | |
end | |
end | |
local function despawn(player) | |
local state=getstate(player) | |
local healthstate=state.healthstate | |
local bodyparts=state.bodyparts | |
if healthstate and bodyparts and bodyparts.rootpart then | |
--print("despawning") | |
healthstate.health0=0--REDUNDANT!!! | |
healthstate.healtick0=0 | |
healthstate.alive=false | |
bodyparts.rootpart.CFrame=cf(workspace.Lobby.Spawn.Position+v3(math.random(-10,10),3,math.random(-10,10))) | |
replicatehealthstate(player) | |
end | |
end | |
function playerstates:autodespawn(p) | |
network:send(p,"autodespawn") | |
despawn(p) | |
end | |
local function gethealth(player) | |
local healthstate=getstate(player).healthstate | |
if healthstate then | |
if healthstate.alive then | |
local x=tick()-healthstate.healtick0 | |
if x<0 then | |
return healthstate.health0 | |
else | |
local maxhealth=healthstate.maxhealth | |
local health=healthstate.health0+x*healthstate.healrate | |
return health<maxhealth and health or maxhealth | |
end | |
else | |
return 0 | |
end | |
end | |
end | |
local function sethealth(player,health,actor,weapon,hit,firepos) | |
local actorstate=getstate(actor) | |
local strike=actorstate.strike | |
if strike and strike>15 then | |
actorstate.strike=strike+20 | |
print(actor.Name.. "'s ping is too high to give damage") | |
return | |
end | |
local healthstate=getstate(player).healthstate | |
if healthstate and healthstate.alive then | |
local curhealth=gethealth(player) | |
local maxhealth=healthstate.maxhealth | |
health=health<0 and 0 or health<maxhealth and health or maxhealth | |
local dhealth=health-curhealth | |
if 0<health then | |
if curhealth<health then | |
healthstate.health0=healthstate.health0+health-curhealth | |
else | |
healthstate.health0=health | |
healthstate.healtick0=tick()+healthstate.healwait | |
end | |
replicatehealthstate(player,actor) | |
else | |
healthstate.health0=0 | |
healthstate.healtick0=0--sure y not | |
healthstate.alive=false--aslmost 4got lel | |
fireondied(player,actor,weapon,hit,firepos) | |
despawn(player,actor) | |
end | |
fireonhealthchanged(player,healthstate.health0,dhealth,actor) | |
network:send(player,"shot",actor,firepos) | |
end | |
end | |
local function changehealth(player,dhealth,actor,weapon,hit,firepos) | |
local health=gethealth(player) | |
if health then | |
sethealth(player,health+dhealth,actor,weapon,hit,firepos) | |
end | |
end | |
local function handlekill(player,killer,weapon,hit,firepos,dist,head) | |
---handle awards | |
if killer~=player then | |
if dist>100 then | |
network:send(killer,"smallaward","long",dist<150 and 25 or dist<200 and 50 or dist<300 and 75 or dist<500 and 100 or 150) | |
end | |
if head then | |
network:send(killer,"smallaward","head") | |
end | |
network:send(killer,"bigaward","kill",player.Name,weapon) | |
local khead=ffc(killer.Character,"Head") | |
if khead then | |
network:send(player,"killed",killer,khead,getstate(player).bodyparts.rootpart.CFrame,weapon) | |
end | |
else | |
network:send(player,"killed",killer,nil,getstate(player).bodyparts.rootpart.CFrame) | |
end | |
network:bounce("killfeed",killer,player,dist,weapon,head) | |
---handle leaderboard | |
local pstate=getstate(player) | |
local pstat=pstate.stats | |
if pstat then | |
local ndata={} | |
pstat.deaths=pstat.deaths+1 | |
pstat.streak=0 | |
ndata.Deaths=pstat.deaths | |
ndata.Streak=pstat.streak | |
ndata.Kdr=pstat.deaths>0 and math.floor((pstat.kills/pstat.deaths)*100)/100 or pstat.kills | |
startergui:updatestats(player,ndata) | |
end | |
local kstate=getstate(killer) | |
local kstat=kstate.stats | |
if kstat then | |
local data={} | |
kstat.kills=kstat.kills+1 | |
kstat.streak=kstat.streak+1 | |
data.Kills=kstat.kills | |
data.Streak=kstat.streak | |
data.Kdr=kstat.deaths>0 and math.floor((kstat.kills/kstat.deaths)*100)/100 or kstat.kills | |
startergui:updatestats(killer,data) | |
end | |
---handle round score | |
roundsystem:killupdate(player,killer) | |
end | |
network:add("setuphealth",setuphealth) | |
network:add("setupstats",setupstats) | |
network:add("spawn",spawn) | |
network:add("despawn",despawn) | |
network:add("sethealth",sethealth) | |
network:add("changehealth",changehealth) | |
network:listen("stance",function(player,value) | |
getstate(player).stance=value | |
end) | |
network:listen("sprint",function(player,value) | |
getstate(player).sprint=value | |
end) | |
network:listen("aim",function(player,value) | |
getstate(player).aim=value | |
end) | |
network:listen("equip",function(player,gun) | |
getstate(player).weapon=gun | |
end) | |
network:listen("bodyparts",function(player,parts) | |
getstate(player).bodyparts=parts | |
end) | |
network:add("state",function(player) | |
return states[player] | |
end) | |
network:add("changeteam",function(player,team) | |
player.TeamColor=team.TeamColor | |
end) | |
network:add("chatted",function(chatter,msg,tag,teamchat) | |
--local message=pcall(function() return game.Chat:FilterStringForPlayerAsync(msg,chatter) end) | |
for i=1,#players do | |
delay(0,function() | |
local v=players[i] | |
local message=game.Chat:FilterStringForPlayerAsync(msg,v)--not message and msg or message | |
network:send(v,"chatted",chatter,message,tag,teamchat) | |
end) | |
end | |
end) | |
network:add("spotting",function(player,list) | |
local pp=game.Players:GetChildren() | |
for i=1,#pp do | |
local v=pp[i] | |
if v~=player and v.TeamColor==player.TeamColor and v.Character and ffc(v.Character,"Head") then | |
network:send(v,"spotted",list,player.Name) | |
end | |
end | |
end) | |
network:add("pingcheck",function(player,clientpos) | |
local state=getstate(player) | |
local bodyparts=state.bodyparts | |
if bodyparts and bodyparts.rootpart then | |
local diff=(clientpos-bodyparts.rootpart.Position).Magnitude | |
if diff>20 then | |
state.strike=state.strike and state.strike+1 or 1 | |
print("["..player.Name.."] strikes:"..state.strike.. " positional difference: " ..diff) | |
if diff==math.huge then | |
print("Respawned "..player.Name.." due to loop dying glitch - Rootpart position: ",bodyparts.rootpart.Position) | |
player:LoadCharacter() | |
--game.ReplicatedStorage.Emergency:FireClient(player) | |
end | |
if state.strike>15 and state.strike<200 then | |
print("High ping warning: "..player.Name.. " Kills disabled for this player") | |
elseif state.strike>200 then | |
print("High ping state left too long: "..player.Name.. " Forcing rejoin to resolve issue") | |
player:Kick("Disconnection by server: Client out of sync [PING]") | |
end | |
else | |
state.strike=(state.strike and state.strike>0) and state.strike-10 or 0 | |
end | |
end | |
end) | |
playerstates.ondied:connect(function(player,killer,weapon,hit,firepos) | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local deg =math.pi/180 | |
local v3 =Vector3.new | |
local new =Instance.new | |
local debris =game.Debris | |
local rand =math.random | |
local ceil =math.ceil | |
local ffc =game.FindFirstChild | |
local c =player.Character | |
local newbody =new("Model") | |
local humanoid =new("Humanoid") | |
local head | |
local torso | |
local larm | |
local rarm | |
local lleg | |
local rleg | |
local dist=hit and ceil((firepos-hit.Position).Magnitude) or 0 | |
local headshot=hit and hit.Name=="Head" | |
local parts =c:GetChildren() | |
for i=1,#parts do | |
local v=parts[i] | |
if v:IsA("Part") and v.Transparency==0 then | |
local newpart =new("Part") | |
newpart.formFactor ="Custom" | |
newpart.TopSurface =0 | |
newpart.BottomSurface =0 | |
newpart.Size =v.Size | |
newpart.BrickColor =v.BrickColor | |
newpart.Parent =newbody | |
newpart.Name =v.Name | |
newpart.CFrame =v.CFrame | |
local extra =v:GetChildren() | |
for x=1,#extra do | |
if extra[x]:IsA("SpecialMesh") or extra[x]:IsA("Decal") then | |
extra[x]:Clone().Parent=newpart | |
end | |
end | |
if v.Name=="Head" then head=newpart end | |
if v.Name=="Torso" then torso=newpart end | |
if v.Name=="Left Arm" then larm=newpart end | |
if v.Name=="Right Arm" then rarm=newpart end | |
if v.Name=="Left Leg" then lleg=newpart end | |
if v.Name=="Right Leg" then rleg=newpart end | |
newpart.Velocity=v3() | |
delay(5,function() newpart.Anchored=true end) | |
elseif v:IsA("Shirt") or v:IsA("Pants") then | |
v:Clone().Parent=newbody | |
end | |
end | |
local function weldball(part,c0) | |
local ball=new("Part",newbody) | |
ball.Shape="Ball" | |
ball.TopSurface=0 | |
ball.BottomSurface=0 | |
ball.formFactor="Custom" | |
ball.Size=v3(1,1,1) | |
ball.Transparency=1 | |
local w=new("Weld") | |
w.Part0=part | |
w.Part1=ball | |
w.C0=not c0 and cf(0,-0.5,0) or c0 | |
w.Parent=ball | |
end | |
local function weldtorso(part,setcf,c0,c1) | |
part.CFrame=torso.CFrame*setcf | |
local joint=new("Rotate") | |
joint.Part0=torso | |
joint.Part1=part | |
joint.C0=c0 | |
joint.C1=c1 | |
joint.Parent=torso | |
weldball(part) | |
end | |
if torso then | |
if head then | |
local neck=new("Weld") | |
neck.Part0=torso | |
neck.Part1=head | |
neck.C0=cf(0,1.5,0) | |
neck.Parent=torso | |
end | |
if rarm then | |
weldtorso(rarm,cf(1.5,0,0),cf(1.5,0.5,0,0,0,1,0,1,0,-1,0,0),cf(0,0.5,0,0,0,1,0,1,0,-1,0,0)) | |
end | |
if larm then | |
weldtorso(larm,cf(-1.5,0,0),cf(-1.5,0.5,0,0,0,-1,0,1,0,1,0,0),cf(0,0.5,0,0,0,-1,0,1,0,1,0,0)) | |
end | |
if rleg then | |
weldtorso(rleg,cf(0.5,-2,0),cf(0.5,-1,0,0,0,1,0,1,0,-1,0,0),cf(0,1,0,0,0,1,0,1,0,-1,0,0)) | |
end | |
if lleg then | |
weldtorso(lleg,cf(-0.5,-2,0),cf(-0.5,-1,0,0,0,-1,0,1,0,1,0,0),cf(0,1,0,0,0,-1,0,1,0,1,0,0)) | |
end | |
weldball(torso,cf(0,0.5,0)) | |
newbody.Name="Dead" | |
humanoid.Parent=newbody | |
humanoid.PlatformStand=true | |
humanoid.AutoRotate=false | |
humanoid.Name="Fakehumanoid" | |
humanoid.Health=100 | |
wait(1/60) | |
newbody.Parent=workspace.Ignore | |
torso.Velocity=v3(rand(-30,30),0,rand(-30,30)) | |
debris:AddItem(newbody,20) | |
end | |
print(killer,"killed",player) | |
handlekill(player,killer,weapon,hit,firepos,dist,headshot) | |
end) | |
end | |
--vector module | |
--By AxisAngle (Trey Reynolds) | |
print("Loading vector module") | |
do | |
local pi =math.pi | |
local cos =math.cos | |
local sin =math.sin | |
local acos =math.acos | |
local asin =math.asin | |
local atan2 =math.atan2 | |
local random =math.random | |
local v3 =Vector3.new | |
local nv =Vector3.new() | |
vector.identity=nv | |
vector.new=v3 | |
vector.lerp=nv.lerp | |
function vector.random(a,b) | |
local p =acos(1-2*random())/3 | |
local z =3^0.5*sin(p)-cos(p) | |
local r =((1-z*z)*random())^0.5 | |
local t =6.28318*random() | |
local x =r*cos(t) | |
local y =r*sin(t) | |
if a and b then | |
local m =(a+(b-a)*random())/(x*x+y*y+z*z)^0.5 | |
return v3(m*x,m*y,m*z) | |
elseif a then | |
return v3(a*x,a*y,a*z) | |
else | |
return v3(x,y,z) | |
end | |
end | |
function vector.anglesyx(x,y) | |
local cx=cos(x) | |
return v3(-cx*sin(y),sin(x),-cx*cos(y)) | |
end | |
function vector.toanglesyx(v) | |
local x,y,z=v.x,v.y,v.z | |
return asin(y/(x*x+y*y+z*z)^0.5),atan2(-x,-z) | |
end | |
function vector.slerp(v0,v1,t) | |
local x0,y0,z0 =v0.x,v0.y,v0.z | |
local x1,y1,z1 =v1.x,v1.y,v1.z | |
local m0 =(x0*x0+y0*y0+z0*z0)^0.5 | |
local m1 =(x1*x1+y1*y1+z1*z1)^0.5 | |
local co =(x0*x1+y0*y1+z0*z1)/(m0*m1) | |
if co<-0.99999 then | |
local px,py,pz =0,0,0 | |
local x2,y2,z2 =x0*x0,y0*y0,z0*z0 | |
if x2<y2 then | |
if x2<z2 then | |
px =1 | |
else | |
pz =1 | |
end | |
else | |
if y2<z2 then | |
py =1 | |
else | |
pz =1 | |
end | |
end | |
local th =acos((x0*px+y0*py+z0*pz)/m0) | |
local r =pi/th*t | |
local s =((1-t)*m0+t*m1)/sin(th) | |
local s0 =s/m0*sin((1-r)*th) | |
local s1 =s/m1*sin(r*th) | |
return v3( | |
s0*x0+s1*px, | |
s0*y0+s1*py, | |
s0*z0+s1*pz | |
) | |
elseif co<0.99999 then | |
local th =acos(co) | |
local s =((1-t)*m0+t*m1)/(1-co*co)^0.5 | |
local s0 =s/m0*sin((1-t)*th) | |
local s1 =s/m1*sin(t*th) | |
return v3( | |
s0*x0+s1*x1, | |
s0*y0+s1*y1, | |
s0*z0+s1*z1 | |
) | |
elseif 1e-5<m0 or 1e-5<m1 then | |
if m0<m1 then | |
return ((1-t)*m0/m1+t)*v1 | |
else | |
return ((1-t)+t*m1/m0)*v0 | |
end | |
else | |
return nv | |
end | |
end | |
end | |
--environment module | |
--by litozinnamon | |
print("Loading environment module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local v3 =Vector3.new | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local deg =math.pi/180 | |
local random =math.random | |
local color =Color3.new | |
local colorseq =ColorSequence.new | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local debris =game.Debris | |
local new =Instance.new | |
local repeffects =game.ReplicatedStorage.Effects | |
local blood =repeffects.Blood | |
local bloodsplat =repeffects.BloodSplat | |
local hole =repeffects.Hole | |
local ignore =workspace.Ignore | |
network:add("breakwindow",function(hit) | |
if not hit then return end | |
local shat=new("Sound",hit) | |
shat.SoundId="http://roblox.com/asset/?id=144884907" | |
shat.TimePosition = .1 | |
shat:Play() | |
local sx,sy,sz=hit.Size.x,hit.Size.y,hit.Size.z | |
for x=1,4 do | |
for y=1,4 do | |
local part=hit:Clone() | |
local position=v3(x-2.1,y-2.1,0)*v3(sx/4,sy/4,sz) | |
part.Size=v3(sx/4,sy/4,sz) | |
part.CFrame=hit.CFrame*(cf(part.Size/8)-hit.Size/8+position) | |
part.Velocity=v3(random(-10,10),random(-10,10),random(-10,10)) | |
part.Parent=ignore | |
part.Name="Shatter" | |
debris:AddItem(part,5) | |
part.Anchored=false | |
end | |
end | |
wait(1/30) | |
hit:Destroy() | |
end) | |
network:add("bloodhit",function(start,hit,pos,norm) | |
local ignorelist={ignore} | |
local pp=game.Players:GetChildren() | |
for i=1,#pp do | |
ignorelist[#ignorelist+1]=pp[i].Character | |
end | |
for i=1,3 do | |
local h,p,n=raycast(workspace,ray(pos,(pos-start).unit*10+vector.random(7)-v3(0,2,0)),ignorelist) | |
if h and h.Anchored and h.Transparency~=1 then | |
local b=blood:Clone() | |
b.CFrame=cf(p,p+n)*angles(90*deg,0,0) | |
b.Parent=ignore | |
spawn(function() | |
for i=1,random(7,15) do | |
b.Mesh.Scale=b.Mesh.Scale+v3(1,0,1) | |
wait(.02) | |
end | |
end) | |
debris:AddItem(b) | |
end | |
end | |
local bloodpart=hole:Clone() | |
bloodpart.Parent=ignore | |
bloodpart.CFrame=cf(pos) | |
bloodpart.Transparency=1 | |
bloodpart:ClearAllChildren() | |
local bd=bloodsplat:Clone() | |
bd.Parent=bloodpart | |
bd.Adornee=bloodpart | |
bd.Enabled=true | |
bd.ID.Size=ud2(1,0,1,0) | |
bd.ID.Position=ud2(-.25,0,-.25,0) | |
bd.ID.Rotation=random(0,360) | |
bd.ID:TweenSizeAndPosition(ud2(5,0,5,0),ud2(-2,0,-2,0),"Out","Quad",.4) | |
debris:AddItem(bloodpart,0.15) | |
end) | |
end | |
--roundsystem module | |
--by litozinnamon | |
print("Loading roundsystem module") | |
do | |
local wfc =game.WaitForChild | |
local ffc =game.FindFirstChild | |
local ud2 =UDim2.new | |
local v3 =Vector3.new | |
local cf =CFrame.new | |
local angles =CFrame.Angles | |
local deg =math.pi/180 | |
local random =math.random | |
local color =Color3.new | |
local ray =Ray.new | |
local raycast =workspace.FindPartOnRayWithIgnoreList | |
local debris =game.Debris | |
local new =Instance.new | |
local light =game.Lighting | |
local players =game.Players | |
local repstore =game.ReplicatedStorage | |
local settings =repstore.ServerSettings | |
local countdown =settings.Countdown | |
local winner =settings.Winner | |
local showresult =settings.ShowResults | |
local gamemode =settings.GameMode | |
local timer =settings.Timer | |
local maxscoredis =settings.MaxScore | |
local gscore =settings.GhostScore | |
local pscore =settings.PhantomScore | |
local setquote =settings.Quote | |
local allowspawn =settings.AllowSpawn | |
local tghost =game.Teams.Ghosts | |
local tphan =game.Teams.Phantoms | |
local roundtime =15 | |
local currentmode ="tdm" | |
local gamerunning =false | |
local maxscore =0 | |
--local gscore =0 | |
--local pscore =0 | |
local gamelist ={ | |
tdm={ | |
Name="Team Deathmatch", | |
Length=15, | |
Maxscore=250 | |
}, | |
} | |
local lightset ={ | |
Crane={ | |
Name="Crane", | |
Ambient={75, 73, 58}, | |
ColorShift_Bottom={97, 95, 74}, | |
ColorShift_Top={81, 79, 79}, | |
OutdoorAmbient={85, 84, 70} | |
}, | |
Highway={ | |
Name="Highway", | |
Ambient={75, 73, 58}, | |
ColorShift_Bottom={97, 95, 74}, | |
ColorShift_Top={81, 79, 79}, | |
OutdoorAmbient={85, 84, 70} | |
}, | |
Ravod={ | |
Name="Ravod", | |
Ambient={95, 84, 80}, | |
ColorShift_Bottom={154, 151, 105}, | |
ColorShift_Top={91, 90, 58}, | |
OutdoorAmbient={124, 125, 109} | |
}, | |
Apocalypse={ | |
Name="Apocalypse", | |
Ambient={75, 73, 58}, | |
ColorShift_Bottom={97, 95, 74}, | |
ColorShift_Top={81, 79, 79}, | |
OutdoorAmbient={85, 84, 70} | |
}, | |
} | |
local quotes ={ | |
"War does not determine who is right - only who is left.", | |
"When you do crazy things, expect crazy results", | |
"I dream of a better tomorrow, where chickens can cross the road and not be quested about their motives", | |
"No I didn't trip, the floor looked like it needed a hug", | |
"Better late than never, but never late is better", | |
"I was standing in the park wondering why frisbees got bigger as they get closer. Then it hit me.", | |
"When tempted to fight fire with fire, remember that the fire department generally uses water.", | |
"Some cause happiness wherever they go; others whenever they go.", | |
"Never underestimate the power of stupid people in large groups", | |
"A successful man is one who makes more money than his wife can spend. A successful woman is one who can find such a man.", | |
"Behind every great man is a woman rolling her eyes.", | |
"Perfection is not attainable, but if we chase perfection we can catch excellence.", | |
"An idea isn't responsible for the people who believe in it.", | |
"I would like to die on Mars. Just not on impact.", | |
"If women ran the world we wouldn't have wars, just intense negotiations every 28 days. [Robin Williams]", | |
"Between two evils, I always pick the one I never tried before.", | |
"If two wrongs don't make a right, try three.", | |
"Man cannot live by bread alone; he must have peanut butter.", | |
"A pessimist is a person who has had to listen to too many optimists.", | |
"All men are equal before fish.", | |
"I've never been married, but I tell people I'm divorced so they won't think something is wrong with me.", | |
"O Lord, help me to be pure, but not yet.", | |
"Any kid will run any errand for you, if you ask at bedtime.", | |
"We owe to the Middle Ages the two worst inventions of humanity - romantic love and gunpowder.", | |
"Guilt: the gift that keeps on giving.", | |
"The point of war is not to die for your country, but to make the noob on the other side die for his", | |
"Always borrow money from a pessimist. He won't expect it back.", | |
"Friendship is like peeing on yourself: everyone can see it, but only you get the warm feeling that it brings.", | |
"Dogs have masters. Cats have staff.", | |
"Knowledge is knowing a tomato is a fruit; wisdom is not putting it in a fruit salad.", | |
"Why do people say 'no offense' right before they're about to offend you?", | |
"By all means, marry. If you get a good wife, you'll become happy; if you get a bad one, you'll become a philosopher.", | |
"I asked God for a bike, but I know God doesn't work that way. So I stole a bike and asked for forgiveness.", | |
"The best way to lie is to tell the truth . . . carefully edited truth.", | |
"Do not argue with an idiot. He will drag you down to his level and beat you with experience.", | |
"The only mystery in life is why the kamikaze pilots wore helmets.", | |
"Going to church doesn't make you a Christian any more than standing in a garage makes you a car.", | |
"A bargain is something you don't need at a price you can't resist.", | |
"If you steal from one author, it's plagiarism; if you steal from many, it's research.", | |
"If you think nobody cares if you're alive, try missing a couple of car payments.", | |
"How is it one careless match can start a forest fire, but it takes a whole box to start a campfire?", | |
"God gave us our relatives; thank God we can choose our friends.", | |
"Children: You spend the first 2 years of their life teaching them to walk and talk. Then you spend the next 16 telling them to sit down and shut-up.", | |
"Nothing sucks more than that moment during an argument when you realize you're wrong.", | |
"By the time a man realizes that his father was right, he has a son who thinks he's wrong.", | |
"We've all heard that a million monkeys banging on a million typewriters will eventually reproduce the entire works of Shakespeare. Now, thanks to the Internet, we know this is not true.", | |
"Women who seek to be equal with men lack ambition.", | |
"When you go into court you are putting your fate into the hands of twelve people who weren't smart enough to get out of jury duty.", | |
"Those people who think they know everything are a great annoyance to those of us who do.", | |
"By working faithfully eight hours a day you may eventually get to be boss and work twelve hours a day.", | |
"When tempted to fight fire with fire, remember that the Fire Department usually uses water.", | |
"America is a country where half the money is spent buying food, and the other half is spent trying to lose weight.", | |
"A bank is a place that will lend you money, if you can prove that you don't need it.", | |
"The best time to give advice to your children is while they're still young enough to believe you know what you're talking about.", | |
"Tell a man there are 300 billion stars in the universe and he'll believe you. Tell him a bench has wet paint on it and he'll have to touch it to be sure.", | |
"The human brain is a wonderful thing. It starts working the moment you are born, and never stops until you stand up to speak in public.", | |
"At every party, there are two kinds of people'those who want to go home and those who don't. The trouble is, they are usually married to each other.", | |
"You love flowers, but you cut them. You love animals, but you eat them. You tell me you love me, so now I'm scared!", | |
"I don't need a hair stylist, my pillow gives me a new hairstyle every morning.", | |
"Don't worry if plan A fails, there are 25 more letters in the alphabet.", | |
"Studying means 10% reading and 90% complaining to your friends that you have to study.", | |
"If you want your wife to listen to you, then talk to another woman; she will be all ears.", | |
"You never realize how boring your life is until someone asks what you like to do for fun.", | |
"In the morning you beg to sleep more, in the afternoon you are dying to sleep, and at night you refuse to sleep.", | |
"When I said that I cleaned my room, I just meant I made a path from the doorway to my bed.", | |
"Life isn't measured by the number of breaths you take, but by the number of moments that take your breath away.", | |
"The great pleasure in life is doing what people say you cannot do.", | |
"If we were on a sinking ship, and there was only one life vest... I would miss you so much.", | |
"All my life I thought air was free, until I bought a bag of chips.", | |
"Long time ago I used to have a life, until someone told me to create a Facebook account.", | |
"Never take life seriously. Nobody gets out alive anyway.", | |
} | |
local function refresh() | |
local cur=ffc(workspace,"Map") | |
if cur then cur:Destroy() end | |
pscore.Value=0 | |
gscore.Value=0 | |
end | |
local function set_lighting(mapname) | |
local dolist={"Ambient","ColorShift_Bottom","ColorShift_Top","OutdoorAmbient"} | |
for i=1, #dolist do | |
light[dolist[i]]=color(lightset[mapname][dolist[i]][1]/255,lightset[mapname][dolist[i]][2]/255,lightset[mapname][dolist[i]][3]/255) | |
end | |
end | |
local function spawnplayers() | |
wait(2) | |
local map | |
timer=tick()+30 | |
repeat map=ffc(workspace,"Map") wait(0.1) until map | |
local ppl=players:GetChildren() | |
for i=1,#ppl do | |
if ppl[i].Character and ffc(workspace,ppl[i].Name) and ffc(ppl[i].Character,"Torso") then | |
network:send(ppl[i],"countdown",network:toplayertick(timer)) | |
end | |
end | |
end | |
--[[game.Players.PlayerAdded:connect(function(player) | |
if countdown.Value and tick()<timer then | |
network:send(player,"countdown",network:toplayertick(timer)) | |
end | |
end)]] | |
local function gameresult() | |
--[[if pscore>=maxscore or pscore>gscore then | |
winner.Value=tphan.TeamColor | |
elseif gscore>=maxscore or gscore>pscore then | |
winner.Value=tghost.TeamColor | |
elseif pscore==gscore then | |
winner.Value=BrickColor.new("Black") | |
end]] | |
if pscore.Value>=maxscore or pscore.Value>gscore.Value then | |
winner.Value=tphan.TeamColor | |
elseif gscore.Value>=maxscore or gscore.Value>pscore.Value then | |
winner.Value=tghost.TeamColor | |
elseif pscore.Value==gscore.Value then | |
winner.Value=BrickColor.new("Black") | |
end | |
setquote.Value=quotes[math.random(1,#quotes)] | |
wait(.1) | |
showresult.Value=true | |
wait(10) | |
showresult.Value=false | |
end | |
local function checkresult() | |
if gamerunning and pscore.Value>=maxscore or gscore.Value>=maxscore then | |
gamerunning=false | |
end | |
end | |
local function respawnall() | |
local ppl=players:GetChildren() | |
for i=1,#ppl do | |
playerstates:autodespawn(ppl[i]) | |
end | |
wait(2) | |
end | |
local function startmatch(mapname,mode) | |
currentmode=mode | |
roundtime=gamelist[currentmode].Length | |
maxscore=gamelist[currentmode].Maxscore | |
maxscoredis.Value=maxscore | |
gamemode.Value=gamelist[currentmode].Name | |
refresh() | |
local map=game.ServerStorage.Maps[mapname]:Clone() | |
map.Name="Map" | |
map.Parent=workspace | |
set_lighting(mapname) | |
network:bounce("emptytrash")--NEW BULLSHIT PROBABLY LAGS NEW BULLSHIT PROBABLY LAGS NEW BULLSHIT PROBABLY LAGS NEW BULLSHIT PROBABLY LAGS | |
wait(15) | |
allowspawn.Value=true | |
countdown.Value=true | |
for i = 20,0,-1 do | |
timer.Value=i | |
wait(1) | |
end | |
countdown.Value=false | |
gamerunning=true | |
for i=roundtime*60,0,-1 do | |
if gamerunning then | |
timer.Value=i | |
checkresult() | |
wait(1) | |
end | |
end | |
allowspawn.Value=false | |
gameresult() | |
respawnall() | |
end | |
function roundsystem:killupdate(victim,killer) | |
if victim~=killer then | |
if killer.TeamColor==tghost.TeamColor then | |
gscore.Value=gscore.Value+1 | |
elseif killer.TeamColor==tphan.TeamColor then | |
pscore.Value=pscore.Value+1 | |
end | |
end | |
end | |
while true do | |
--startmatch("Apocalypse","tdm") | |
startmatch("Highway","tdm") | |
startmatch("Crane","tdm") | |
startmatch("Ravod","tdm") | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment