Skip to content

Instantly share code, notes, and snippets.

@Elmuti
Created April 7, 2022 01:30
Show Gist options
  • Save Elmuti/cd31468d074f5e6c0a71eb3c71455ab7 to your computer and use it in GitHub Desktop.
Save Elmuti/cd31468d074f5e6c0a71eb3c71455ab7 to your computer and use it in GitHub Desktop.
pcall(function()
game:GetService("StarterGui"):SetCoreGuiEnabled(Enum.CoreGuiType.All, false)
game:GetService("StarterGui"):SetCore("TopbarEnabled", false)
end)
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
local plabel = game.Players.LocalPlayer:WaitForChild("PlayerGui"):WaitForChild("HUD"):WaitForChild("PingLabel")
local pingremote = game.ReplicatedStorage.Ping
local UseWeaponViewmodel = true
local ConsoleVisible = false
local hrpOffsetFromGround = 3
local MOUSE_MIN, MOUSE_MAX = math.rad(-80), math.rad(80) --down angle, up angle
local mouseAngles = Vector2.new()
local bobtimer = 0
local PlayerLatencies = {}
local PlayerData = {}
--contents really dont matter, list is replicated from server, its just nice to have this here on initialization if for some reason the replication does not happen before client cvar initialization
local ConVars = {
sv_cheats = {false, true, "Turns cheats on"};
sv_gravity = {196.200, true, "World gravity", {-math.huge, math.huge}};
sv_accelerate = {200, true, "Acceleration rate", {-math.huge, math.huge}};
sv_airaccelerate = {5, true, "Air acceleration rate", {-math.huge, math.huge}};
sv_max_velocity_ground = {200, true, "Maximum velocity on the ground", {-math.huge, math.huge}};
sv_max_velocity_air = {1350, true, "Maximum velocity in the air", {-math.huge, math.huge}};
sv_friction = {7.5, true, "Amount of friction on surfaces", {-math.huge, math.huge}};
sv_motd = {"", true, "Server message of the day"};
sv_currentmap = {"", true, ""};
mp_startingweapon = {"Machinegun", true, ""};
mp_damagemult = {1, true, "Global damage multiplier", {0, 1000}};
mp_gamemode = {"Deathmatch", true, "The current gamemode"};
mp_dm_fraglimit = {10, true, "The frag limit to win the game", {1, math.huge}};
mp_dm_timelimit = {300, true, "The time limit of the game", {1, math.huge}};
mp_ctf_capturelimit = {5, true, "Flag capture limit", {1, math.huge}};
cl_thirdperson = {false, true, "Third person camera toggle"};
cl_autoswitch = {true, false, "Toggles auto-switching to picked up weapons"};
cl_violence = {true, false, "Toggles blood and gore"};
cl_shellfadetime = {0.75, false, "", {0, 10}};
cl_chat_message_displaytime = {4.5, false, "Seconds to display a new chat message for", {0, 60}};
cl_chathistorylength = {5, false, "", {1, 20}};
cl_crosshairsize = {10, false, "", {-100, 100}};
cl_crosshairgap = {2.5, false, "", {-100, 100}};
cl_crosshairalpha = {255, false, "", {0, 255}};
cl_footsteps = {true, false, "Toggles footstep sounds"};
cl_drawping = {false, false, "Toggles ping counter"};
cl_muzzleflash = {true, false, ""};
cl_weaponbob_rate = {1, false, "Weapon bob animation frequency multiplier", {0, 2}};
cl_weaponbob_amt = {1, false, "Weapon bob animation range multiplier", {0, 2}};
cl_fov = {75, false, "", {20, 90}};
cl_zoomfov = {20, false, "", {20, 90}};
cl_sensitivity = {0.15, false, "Mouse sensitivity multiplier", {0, 100}};
cl_zoomsensitivity = {0.85, false, "Mouse sensitivity multiplier", {0, 100}};
cl_camera_orbit = {false, true, ""};
cl_camera_orbit_offset = {6, true, ""};
}
local Developers = {"StealthKing95", "Player1"}
function IsDeveloper(plr)
for _, dev in pairs(Developers) do
if plr == dev then
return true
end
end
return false
end
local StopTweens = false
local scoreboardCanBeToggled = true
local currentCmdIndex = 0
local thirdpersonangle = 0
local thirdpersonRotSpeed = 45
local thirdperson = false
local prevCamCF = CFrame.new()
local actualMouseHit = Vector3.new()
local accelDir = Vector3.new()
local playerVelocity = Vector3.new()
local prevVelocity = Vector3.new()
local pushVector = Vector3.new()
local movementKeysDown = {W = false; A = false; S = false; D = false; Space = false;}
local RAYMDL
local jumpedOnPrevFrame = false
local barrierUp = false
local charInvisible = false
local respawning = false
local events = game.ReplicatedStorage
local player = game.Players.LocalPlayer
local char = player.Character or player.CharacterAdded:wait()
local torso = char:WaitForChild("HumanoidRootPart")
local cam = workspace.CurrentCamera
local mouse = player:GetMouse()
mouse.Icon = "rbxassetid://810062788"--http://www.roblox.com/asset/?id=810062788
local pickups = workspace.ItemPickups:GetChildren()
local clouds
local latency = 0
local CurrentSituation = ""
local PrevSituation = ""
local Orakel = require(game.ReplicatedStorage.Orakel.Main)
local mathLib = Orakel.LoadModule("MathLib")
local sndLib = Orakel.LoadModule("SoundLib")
local assetLib = Orakel.LoadModule("AssetLib")
local npcLib = Orakel.LoadModule("NpcLib")
local tLib = Orakel.LoadModule("CFrameLib")
local weaponData = {}
local lastHurtSound = tick()
local ClientTime = 0
local canwalk = true
local VelOffset = Vector3.new()
local PlayerModels = {}
local canfire = true
local itemFloatHeight = 0.01
local equippedWeapon
local weaponCode
local firingWeapon = false
local lastShotFired = tick()
local chatlog = {}
local chatVisible = false
local AbilityIsInCooldown = false
local PlayerStats = {
Weapons = {
Machinegun = {Ammo = 150; MaxAmmo = 150; Owned = true;};
Shotgun = {Ammo = 25; MaxAmmo = 25; Owned = false;};
Grenade = {Ammo = 25; MaxAmmo = 25; Owned = false;};
RocketLauncher = {Ammo = 25; MaxAmmo = 25; Owned = false;};
LightningGun = {Ammo = 150; MaxAmmo = 150; Owned = false;};
Railgun = {Ammo = 25; MaxAmmo = 25; Owned = false;};
PlasmaGun = {Ammo = 150; MaxAmmo = 150; Owned = false;};
};
Health = 100;
MaxHealth = 100;
Armor = 15;
MaxArmor = 100;
}
local WeaponIndexes = {
"Machinegun";
"Shotgun";
"Grenade";
"RocketLauncher";
"LightningGun";
"Railgun";
"PlasmaGun";
}
local PreviousCmds = {}
local conMsg = {}
local conMsgYMax = 2
local conMsgY = 0
local Aliases = {
clr = "clear";
quti = "quit";
qq = "quit";
cls = "close";
exit = "close";
cleardecals = "r_cleardecals";
suicide = "kill";
memory = "memory_details";
getmem = "memory_details";
cl_mem = "memory_details";
}
local ConCmd = {
clear = {"Clears the console window", function()
player.PlayerGui.HUD.Console.Output:ClearAllChildren()
conMsgY = 0
conMsg = {}
end};
quit = {"Exits the game", function()
Orakel.Log("Please remind the developer to finish this command", "Warning")
end};
kill = {"Commit suicide", function()
TakeDamage(90000, "Server")
Orakel.Log(player.Name.. " killed by server.")
end};
close = {"Closes the console", function()
ConsoleVisible = false
player.PlayerGui.HUD.Console.Visible = false
end};
endgame = {"End the current round", function()
Orakel.Log("Not currently functional!")
end};
players = {"Lists current players", function()
for i, plr in pairs(game.Players:GetPlayers()) do
Orakel.Log("#"..i..": "..plr.Name.." "..plr.UserId)
end
end};
r_cleardecals = {"Clear world decals", function()
npcLib.ClearDecals()
end};
convars = {"Lists all convars", function()
for convar, data in pairs(ConVars) do
if data[3] ~= nil and data[3] ~= "" then
Orakel.Log(convar.." = "..tostring(data[1]).." -> "..data[3])
else
Orakel.Log(convar.." = "..tostring(data[1]))
end
end
end};
help = {"Gives you instructions", function()
Orakel.Log('To change ConVars(console variables) or call console commands, the syntax is as follows:\n\nChanging a ConVar:\n<convar> <value>\n\nCalling a command:\n<command> <value>\n^ where value might be optional depending on the command.\n\nTo get a list of ConVars, type "convars"\nTo get a list of commands, type "commands"\n\nTo get information about a specific ConVar or command,\njust type the name of the it.\nYou can write multiple commands in one go by separating them with a semicolon(;)')
end};
aliases = {"Lists all set aliases", function()
for alias, cmd in pairs(Aliases) do
Orakel.Log(alias .. " -> alias for " .. cmd)
end
end};
memory_details = {"Get detailed information on memory usage", function()
local memoryReportFormat = "\t%s - %.3f MBs"
for i,memoryTag in ipairs(Enum.DeveloperMemoryTag:GetEnumItems()) do
local consumption = game:GetService("Stats"):GetMemoryUsageMbForTag(memoryTag)
if consumption > 10 then
Orakel.Log(memoryReportFormat:format(memoryTag.Name, consumption), "Error")
else
Orakel.Log(memoryReportFormat:format(memoryTag.Name, consumption), "Warning")
end
end
end};
status = {"", function()
Orakel.Log("hostname : "..ConVars["sv_motd"][1])
Orakel.Log("version : "..Orakel.Configuration.Version)
Orakel.Log("type : ".."community_public")
Orakel.Log("map : "..ConVars["sv_currentmap"][1])
Orakel.Log("players : "..(#game.Players:GetPlayers()).." / "..game.Players.MaxPlayers.."\n\n")
Orakel.Log("# userid name ping state")
for i, plr in pairs(game.Players:GetPlayers()) do
Orakel.Log("# "..plr.UserId.." "..plr.Name.." "..PlayerLatencies[plr.UserId].."ms ".."active")
end
Orakel.Log("#end players")
end};
}
function IsConvar(str)
for cvar, data in pairs(ConVars) do
if cvar == str then
return true
end
end
return false
end
function IsCmd(str)
for cmd, data in pairs(ConCmd) do
if cmd == str then
return true
end
end
return false
end
function IsAlias(str)
for alias, cmd in pairs(Aliases) do
if str == alias then
return true
end
end
return false
end
function TweenCallback()
return StopTweens
end
function ParseConvar(cmd, val)
--Orakel.Log("Parsing convar '"..cmd.."' '"..val.."'")
if (ConVars[cmd] == nil) and (val == nil or val == "") then
Orakel.Log('Unknown command "'..cmd..'"', "Warning")
return
else
if ConVars[cmd] ~= nil then
--GAVE CONVAR BUT NO VALUE
if val == nil or val == "" then
--Specify range if defined
if ConVars[cmd][4] ~= nil then
Orakel.Log(cmd.." = '"..tostring(ConVars[cmd][1]).."' - "..ConVars[cmd][3]..', Usage: "'..cmd..' <'..type(ConVars[cmd][1])..'>", Range: ['..ConVars[cmd][4][1]..' - '..ConVars[cmd][4][2]..']')
else
Orakel.Log(cmd.." = '"..tostring(ConVars[cmd][1]).."' - "..ConVars[cmd][3]..', Usage: "'..cmd..' <'..type(ConVars[cmd][1])..'>"')
end
else
local isServerCvar = (cmd:sub(1, 2) == "sv") or (cmd:sub(1, 2) == "mp")
local valn = tonumber(val)
--VALUE IS BOOLEAN
if type(ConVars[cmd][1]) == "bool" and valn == 1 or valn == 0 then
if valn == 1 then
--Orakel.Log(">"..cmd.." "..valn)
if isServerCvar then
local wasValid = events.AttemptCommandServer:InvokeServer(cmd, 1)
if not wasValid then
Orakel.Log("Can't change replicated ConVar "..cmd.." from console of client, only server operator can change its value", "Warning")
end
else
ConVars[cmd][1] = true
end
elseif valn == 0 then
--Orakel.Log(">"..cmd.." "..valn)
if isServerCvar then
local wasValid = events.AttemptCommandServer:InvokeServer(cmd, 0)
if not wasValid then
Orakel.Log("Can't change replicated ConVar "..cmd.." from console of client, only server operator can change its value", "Warning")
end
else
ConVars[cmd][1] = false
end
else
Orakel.Log("'"..cmd.."' is not a boolean", "Error")
end
--VALUE IS STRING
elseif type(ConVars[cmd][1]) == "string" then
--Orakel.Log(">"..cmd.." "..val)
if isServerCvar then
local wasValid = events.AttemptCommandServer:InvokeServer(cmd, val)
if not wasValid then
Orakel.Log("Can't change replicated ConVar "..cmd.." from console of client, only server operator can change its value", "Warning")
end
else
ConVars[cmd][1] = val
end
--VALUE IS NUMBER
else
if valn ~= nil then
--Orakel.Log(">"..cmd.." "..valn)
if isServerCvar then
if ConVars[cmd][4] ~= nil then
valn = math.clamp(val, ConVars[cmd][4][1], ConVars[cmd][4][2])
end
local wasValid = events.AttemptCommandServer:InvokeServer(cmd, valn)
if not wasValid then
Orakel.Log("Can't change replicated ConVar "..cmd.." from console of client, only server operator can change its value", "Warning")
end
else
if ConVars[cmd][4] ~= nil then
val = math.clamp(valn, ConVars[cmd][4][1], ConVars[cmd][4][2])
end
ConVars[cmd][1] = valn
end
else
Orakel.Log("'"..tostring(val).."' is an invalid parameter for "..cmd, "Error")
end
end
end
else
--CONVAR DOESNT EXIST
Orakel.Log("Unknown convar '"..cmd.."'", "Warning")
end
end
end
function ParseCommandLine(line)
Orakel.Log(">"..line, "Deprecated")
local pattern = ""
local patternLine = '([%w%p]+)%s*;*(%-*%w*%.*%w*);*%s*'
local patternAlias = '([%w%p]+)%s*;*(%-*%w*%.*%w*);*%s*"*([%w%p]*)"*;*%s*'
local currentPattern = patternLine
if line:find("alias") then
currentPattern = patternAlias
end
for cmd, val, val2 in line:gmatch(currentPattern) do
if cmd == "alias" and type(val) == "string" and val ~= "" and val2 ~= nil then
local alias = val
local aliasCmd = val2
if IsConvar(aliasCmd) or IsCmd(aliasCmd) then
Orakel.Log("Created alias '"..alias.."' for '"..aliasCmd.."'", "Deprecated")
Aliases[alias] = aliasCmd
else
Orakel.Log("No such command or convar as '"..aliasCmd.."' exists!", "Warning")
end
return
elseif cmd == "alias" and (type(val) ~= "string" or val == "") then
Orakel.Log("Cannot create an alias for an invalid command/convar", "Warning")
return
end
--List commands
if cmd == "commands" then
for cmd, data in pairs(ConCmd) do
Orakel.Log(cmd.." = "..data[1])
end
return
--ConCmd
elseif IsCmd(cmd) then
ConCmd[cmd][2]()
return
--Alias
elseif IsAlias(cmd) then
local cmd = Aliases[cmd]
if IsCmd(cmd) then
ConCmd[cmd][2]()
return
--elseif IsConvar(cmd) then
--ParseConvar(cmd, val)
end
end
--ConVar
ParseConvar(cmd, val)
end
end
function GetNewlineAmt(str)
local _, count = str:gsub('\n', '\n')
return count
end
function GetOldestConMsg()
local oldest = conMsg[1]
local lasti = 0
if #conMsg > 1 then
for i = 2, #conMsg do
local current = conMsg[i]
if current.Time < oldest.Time then
oldest = current
lasti = i
end
end
end
return oldest, lasti
end
function AddConMessage(msg, color)
local m = Instance.new("TextLabel")
m.BackgroundTransparency = 1
m.TextColor3 = color
m.TextXAlignment = Enum.TextXAlignment.Left
m.TextYAlignment = Enum.TextYAlignment.Top
m.TextSize = 14
m.Font = Enum.Font.Code
m.Size = UDim2.new(1, 0, 0.015, 0)
m.Position = UDim2.new(0, 0, conMsgY, 0)
m.Text = msg
m.TextWrapped = true
--m.Rotation = 180
m.Parent = player.PlayerGui.HUD.Console.Output
table.insert(conMsg, {Label = m, Time = ClientTime})
while not m.TextFits do
m.Size = m.Size + UDim2.new(0, 0, 0.015, 0)
end
conMsgY = conMsgY + m.Size.Y.Scale
--print(msg.."\nconMsgY: "..conMsgY.." SizeY: "..m.Size.Y.Scale.."\n"..string.rep("-", 36))
end
function AddConMessaged(msg, color)
local m = Instance.new("TextLabel")
m.BackgroundTransparency = 1
m.TextColor3 = color
m.TextXAlignment = Enum.TextXAlignment.Left
m.TextYAlignment = Enum.TextYAlignment.Top
m.TextSize = 14
m.Font = Enum.Font.Code
m.Size = UDim2.new(1, 0, 0.015, 0)
m.Position = UDim2.new(0, 0, conMsgY, 0)
m.Text = msg
m.Parent = player.PlayerGui.HUD.Console.Output
table.insert(conMsg, {Label = m, Time = ClientTime})
local textSize = game:GetService("TextService"):GetTextSize(msg, m.TextSize, m.Font, m.AbsoluteSize)
local textWidth = textSize.X
local textHeight = textSize.Y
--The Y-axis message size multiplier, takes into account if text doesnt fit:
local numNewlines = (textWidth / (player.PlayerGui.HUD.Console.Output.AbsoluteSize.X - 10)) + GetNewlineAmt(msg) -- + (textHeight / m.TextSize)
print("textWidth: "..textWidth.." numNewlines: "..numNewlines.. " conMsgY: "..conMsgY)
if numNewlines >= 1 then
m.TextWrapped = true
--If this new message exceeds the Y-limit of the ScrollingFrame, cut old entries
if conMsgY + (0.015 * math.floor(numNewlines)) >= conMsgYMax then
print("new message exceeds the Y-limit of the ScrollingFrame, cutting old entries")
local overkill = (0.015 * math.floor(numNewlines))
--remove oldest messages by overkill
local overkillYAchieved = 0
while overkillYAchieved < overkill do
local oldest, index = GetOldestConMsg()
overkillYAchieved = overkillYAchieved + oldest.Label.AbsoluteSize.Y
end
--move all current messages up by overkillYAchieved
for i, msg in pairs(conMsg) do
msg.Label.Position = msg.Label.Position - UDim2.new(0, 0, 0, overkillYAchieved)
end
end
conMsgY = conMsgY + 0.015 * math.floor(numNewlines)
m.Size = UDim2.new(1, 0, conMsgY, 0)
else
conMsgY = conMsgY + 0.015
end
end
function DrawLineDebug(a, b)
local beam = Instance.new("Part")
beam.Name = "BEAM"
beam.BrickColor = BrickColor.new("Bright red")
beam.Material = Enum.Material.Neon
beam.Transparency = 0
beam.Anchored = true
beam.CanCollide = false
local distance = (a - b).magnitude
beam.Size = Vector3.new(0.3, 0.3, distance)
beam.CFrame = CFrame.new(a, b) * CFrame.new(0, 0, -distance / 2)
beam.Parent = workspace.Ignore
--game:GetService("Debris"):AddItem(beam, 0.08)
return beam
end
function GetWeaponIndex(wepname)
for i = 1, #WeaponIndexes do
if WeaponIndexes[i] == wepname then
return i
end
end
return 1
end
function GetWeaponName(index)
if index > 7 then
return "Machinegun"
elseif index < 1 then
return "PlasmaGun"
end
for i = 1, #WeaponIndexes do
if i == index then
return WeaponIndexes[i]
end
end
return "Machinegun"
end
local CooldownReduction = 0
function UseAbility()
local curAbility = "Ghostwalk"
local ability = require(game.ReplicatedStorage.Abilities[curAbility])
if not AbilityIsInCooldown then
AbilityIsInCooldown = true
local frame = player.PlayerGui.HUD.SpecialAbility
frame.AbilityFrame.Image = "http://www.roblox.com/asset/?id=847342696"
frame.SkillIcon.Visible = false
frame.AbilityUseLabel.Visible = false
spawn(function()
ability.FireClient(player, equippedWeapon, cam.CFrame.p, mouse.Hit.p)
events.FireAbilityServer:FireServer(player, equippedWeapon.Name, cam.CFrame.p, mouse.Hit.p, curAbility)
end)
if ability.Duration then
local t = ability.Duration
frame.AbilityTimer.Text = mathLib.Round(t)
frame.AbilityTimer.Visible = true
while t > 0 do
local dt = wait()
t = t - dt
frame.AbilityTimer.Text = mathLib.Round(t, 1)
end
end
local t = ability.Cooldown
frame.AbilityTimer.Text = mathLib.Round(t)
frame.AbilityTimer.Visible = true
while t > 0 do
local dt = wait()
t = t - dt - CooldownReduction
CooldownReduction = 0
if t < 10 then
frame.AbilityTimer.Text = mathLib.Round(t, 1)
else
frame.AbilityTimer.Text = mathLib.Round(t)
end
end
frame.AbilityFrame.Image = "rbxassetid://847342692"
frame.AbilityTimer.Visible = false
frame.SkillIcon.Visible = true
frame.AbilityUseLabel.Visible = true
AbilityIsInCooldown = false
CooldownReduction = 0
end
end
function OtherPlayerDied(plr, killerweapon)
if ConVars["cl_violence"][1] then
--if killerweapon == "Railgun" or killerweapon == "RocketLauncher" or killerweapon == "Grenade" or killerweapon == "PlasmaGun" then
local char = workspace.Characters:FindFirstChild(plr.Name)
if char then
npcLib.CreateGoryCorpse(char:GetPrimaryPartCFrame(), playerVelocity, {char, workspace.Ignore, workspace.PlayerSpawns, workspace.ItemPickups, workspace.ItemSpawns, workspace.Nodes})
end
--end
end
end
function UpdateJumpPadLogic(dt)
local vel = Vector3.new()
for _, pad in pairs(workspace.JumpPads:GetChildren()) do
if (pad.JumpPad.Position - char.PrimaryPart.Position).magnitude < 5 then
--playerVelocity = Vector3.new()
vel = pad.JumpPad.JumpVelocity.Value
sndLib.PlaySoundClient("global", "jumpPAD", "http://www.roblox.com/asset/?id=81116553", 0.3, 1, false, 1)
sndLib.PlaySoundOtherClients("3d", "jumpPAD", "http://www.roblox.com/asset/?id=81116553", 0.3, 1, false, pad.JumpPad)
end
end
VelOffset = vel
end
local lastFallDamage = tick()
local lastFallSound = tick()
function Grounded(dt)
local ray = Ray.new(char.PrimaryPart.Position, Vector3.new(0, -(math.max(hrpOffsetFromGround + 0.1, math.abs(playerVelocity.Y * dt))), 0))
local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, {char, workspace.Ignore, workspace.PlayerSpawns, workspace.ItemPickups, workspace.ItemSpawns, workspace.Nodes})
if hit then
char:SetPrimaryPartCFrame(CFrame.new(pos + Vector3.new(0, hrpOffsetFromGround, 0)))
--print(hit:GetFullName())
local downvel = math.abs(playerVelocity.Y)
--print(downvel)
if downvel >= 20 and math.abs(tick() - lastFallSound) > 0.5 then
sndLib.PlaySoundClient("global", "fall", "rbxassetid://821077662", 0.3, 1, false, 1)
lastFallSound = tick()
end
if downvel >= 60 and math.abs(tick() - lastFallDamage) > 1 then
local falldmg = (downvel - 60) * 1.5
TakeDamage(falldmg, "World")
if PlayerStats.Health <= 0 then
Orakel.Log(player.Name.. " got rekt by the cruel hard floor.")
end
lastFallDamage = tick()
end
return true
end
return false
end
function Accelerate(accelDir, prevVelocity, accelerate, max_velocity, dt, grounded)
local projVel = prevVelocity:Dot(accelDir)
local accelVel = accelerate * dt
--If necessary, truncate the accelerated velocity so the vector projection does not exceed max_velocity
if projVel + accelVel > max_velocity then
accelVel = max_velocity - projVel
end
return prevVelocity + accelDir * accelVel
end
function MoveGround(accelDir, prevVelocity, dt, grounded)
local speed = prevVelocity.magnitude
if speed ~= 0 then
local drop = speed * ConVars.sv_friction[1] * dt --calculate friction
prevVelocity = prevVelocity * math.max(speed - drop, 0) / speed --friction affects velocity
end
return Accelerate(accelDir, prevVelocity, ConVars.sv_accelerate[1], ConVars.sv_max_velocity_ground[1], dt, grounded)
end
function MoveAir(accelDir, prevVelocity, dt, grounded)
return Accelerate(accelDir, prevVelocity, ConVars.sv_airaccelerate[1], ConVars.sv_max_velocity_air[1], dt, grounded)
end
function SwitchWeapon(curwep, direction, indexOverride, playSound)
local playSound = playSound or true
if playSound then
sndLib.PlaySoundClient("global", "wep_switch", "rbxassetid://823816849", 0.15, 1, false, 2)
end
equippedWeapon:Destroy()
local curi = GetWeaponIndex(equippedWeapon.Name)
local newname = GetWeaponName(indexOverride or (curi + -(direction)))
local newGun = game.ReplicatedStorage.Models[newname]:Clone()
newGun.Parent = char
equippedWeapon = newGun
if weaponCode.StopFire ~= nil then
weaponCode.StopFire()
end
weaponCode.UnEquip()
weaponCode = weaponData[equippedWeapon.Name]
weaponCode.Equip()
for _, frame in pairs(player.PlayerGui.HUD.WeaponsFrame:GetChildren()) do
if frame.Name ~= newname then
frame.BackgroundTransparency = 1
end
end
player.PlayerGui.HUD.WeaponsFrame[newname].BackgroundTransparency = 0.45
end
function CreateViewmodel(char, mdl)
local mdl = mdl:Clone()
mdl.Name = "Viewmodel"
mdl.Parent = char
return mdl
end
function UpdatePlayerData(dt)
for _, plr in pairs(game.Players:GetPlayers()) do
spawn(function()
local s, e = pcall(function()
--local pos, mpos, yrot = events.GetPlayerLocation:InvokeServer(plr)
--local cwep = events.GetCurrentWeapon:InvokeServer(plr)
--local ghosting = events.GetPlayerGhosting:InvokeServer(plr)
--local bup = events.GetPlayerBarrier:InvokeServer(plr)
PlayerData[plr.Name] = events.GetPlayerData:InvokeServer(plr)
end)
if not s then
warn(e)
PlayerData[plr.Name] = {Position = Vector3.new(), MousePosition = Vector3.new(), YRot = CFrame.new(), Invisible = false, Barrier = false, CurrentWeapon = "Machinegun"}
end
end)
end
end
function CreatePlayerModel(originalPlayer)
local dir = workspace:FindFirstChild("Characters") or Instance.new("Model", workspace)
if dir.Name ~= "Characters" then dir.Name = "Characters" end
local char = game.ReplicatedStorage.Characters.PlayerModel:Clone()
char.Name = originalPlayer.Name
char["Left Arm"].Transparency = 1
char["Right Arm"].Transparency = 1
local charmdl = "Circuit"
for _, msh in pairs(game.ReplicatedStorage.Characters[charmdl]:GetChildren()) do
if msh.Name ~= "Head" then
local mc = msh:Clone()
mc.Parent = char
end
end
local arms = game.ReplicatedStorage.Characters.ArmsViewmodel:Clone()
arms.Parent = char
if player == originalPlayer then
for _, p in pairs(arms:GetChildren()) do
if p:IsA("BasePart") then
p.Transparency = 1
end
end
end
char.Parent = dir
char:MakeJoints()
return char
end
function UpdatePlayermodels(dt)
--debug.profilebegin("UpdatePlayermodels")
--create default values if InvokeServer fails for some reason
local pos, mpos, yrot, ghosting, bup = Vector3.new(156, 3.5, -115), Vector3.new(265, 3.5, -115), CFrame.new(), false, false
local cwep = "Machinegun"
local dir = workspace:FindFirstChild("Characters") or Instance.new("Model", workspace)
if dir.Name ~= "Characters" then dir.Name = "Characters" end
for _, plr in pairs(game.Players:GetPlayers()) do
spawn(function()
local mdl = dir:FindFirstChild(plr.Name) --Get the custom character of plr
if mdl and mdl.PrimaryPart ~= nil then
if mdl ~= nil and plr.Name ~= player.Name then
--pcall(function()
local pd = PlayerData[plr.Name]
if pd ~= nil then
pos = pd.Position
mpos = pd.MousePosition
yrot = pd.YRot
ghosting = pd.Invisible
bup = pd.Barrier
cwep = pd.CurrentWeapon
end
--pos, mpos, yrot = events.GetPlayerLocation:InvokeServer(plr)
--cwep = events.GetCurrentWeapon:InvokeServer(plr)
--ghosting = events.GetPlayerGhosting:InvokeServer(plr)
--bup = events.GetPlayerBarrier:InvokeServer(plr)
--end)
if mdl.PrimaryPart ~= nil then
local plrcf = CFrame.new(pos) * yrot --set player CFrame
--mdl:SetPrimaryPartCFrame(plrcf)
tLib.TweenModelLinearAsync(mdl, plrcf, dt, TweenCallback)
end
local wmdl = mdl:FindFirstChild(cwep)
if not wmdl then --3rd person weapon model doesnt exist, create one
wmdl = game.ReplicatedStorage.Models[cwep]:Clone()
wmdl.Parent = mdl
wmdl:MakeJoints()
end
local weaponCode = weaponData[cwep]
--Delete any weapon viewmodels that arent the currently selected weapon
for _, wm in pairs(mdl:GetChildren()) do
if wm.ClassName == "Model" then
for _, wname in pairs(WeaponIndexes) do
if wm.Name == wname and wm.Name ~= cwep then
wm:Destroy()
end
end
end
end
--Set 3rd person weapon model's CFrame
local wmdlcf = CFrame.new(pos, mpos)
* CFrame.new(weaponCode.ViewModel_3rdPerson.Offset.X or 0.4, weaponCode.ViewModel_3rdPerson.Offset.Y or 0.7, weaponCode.ViewModel_3rdPerson.Offset.Z or -2.15)
* CFrame.Angles(math.rad(weaponCode.ViewModel.Angle.X), math.rad(weaponCode.ViewModel.Angle.Y), math.rad(weaponCode.ViewModel.Angle.Z))
--wmdl:SetPrimaryPartCFrame(wmdlcf)
if wmdl.PrimaryPart ~= nil then
tLib.TweenModelLinearAsync(wmdl, wmdlcf, dt, TweenCallback)
end
local armsCf = CFrame.new(pos, mpos) * CFrame.new(0.4, 0.7, -2.15)
if mdl:FindFirstChild("ArmsViewmodel") then
--mdl.ArmsViewmodel:SetPrimaryPartCFrame(armsCf)
if mdl.ArmsViewmodel.PrimaryPart ~= nil then
tLib.TweenModelLinearAsync(mdl.ArmsViewmodel, armsCf, dt, TweenCallback)
end
end
local arms = mdl:FindFirstChild("ArmsViewmodel")
if ghosting then
Orakel.RecursiveSearch(mdl.Head, function(obj) return (obj.ClassName == "Decal") end, function(obj) obj.Transparency = 1 end)
Orakel.ToggleVisible(mdl, 1, false)
Orakel.ToggleVisible(arms, 1, false, {"Part"})
if not equippedWeapon.Name == "Machinegun" then
Orakel.ToggleVisible(wmdl, 1, false, {"Muzzle", "Barrel"})
else
Orakel.ToggleVisible(wmdl, 1, false, {"Muzzle"})
end
else
Orakel.RecursiveSearch(mdl.Head, function(obj) return (obj.ClassName == "Decal") end, function(obj) obj.Transparency = 0 end)
Orakel.ToggleVisible(mdl, 0, false)
Orakel.ToggleVisible(arms, 0, false, {"Part"})
Orakel.ToggleVisible(wmdl, 0, false, {"Muzzle", "Barrel"})
end
if bup and not mdl:FindFirstChild("Barrier") then
local barrier = game.ReplicatedStorage.Particles.Barrier:Clone()
barrier.Parent = mdl
elseif not bup then
local barrier = mdl:FindFirstChild("Barrier")
if barrier then
barrier:Destroy()
end
end
local barrier = mdl:FindFirstChild("Barrier")
if barrier then
barrier:SetPrimaryPartCFrame(CFrame.new(mdl:GetPrimaryPartCFrame().p, mpos))
end
elseif mdl == nil and plr.Name ~= player.Name then --Character model doesnt exist, create one
PlayerModels[plr.Name] = CreatePlayerModel(plr)
end
else
--print("playermodel doesnt exist or hrp died")
if PlayerModels[plr.Name] then
PlayerModels[plr.Name]:Destroy()
end
PlayerModels[plr.Name] = CreatePlayerModel(plr)
end
end)
end
--debug.profileend()
end
function SendCurrentBody()
if string.len(player.PlayerGui.HUD.Chat.InputFrame.TextBox.Text) > 0 then
events.SendMessage:FireServer(player.PlayerGui.HUD.Chat.InputFrame.TextBox.Text)
--print("sending: "..player.PlayerGui.HUD.Chat.InputFrame.TextBox.Text)
end
end
function GetOldestMessage()
local messages = player.PlayerGui.HUD.Chat.Messages:GetChildren()
local oldest
for i = 1, #messages do
local curmsg = messages[i]
if curmsg.Name == "ChatMessage" or curmsg.Name == "SystemChatMessage" then
if oldest == nil then
oldest = curmsg
else
if curmsg.Time.Value < oldest.Time.Value then
oldest = curmsg
end
end
end
end
return oldest
end
function ToggleChatWindow()
chatVisible = not chatVisible
player.PlayerGui.HUD.Chat.HelpFrame.Visible = not player.PlayerGui.HUD.Chat.HelpFrame.Visible
player.PlayerGui.HUD.Chat.InputFrame.Visible = not player.PlayerGui.HUD.Chat.InputFrame.Visible
if chatVisible then
player.PlayerGui.HUD.Chat.InputFrame.TextBox:CaptureFocus()
else
--player.PlayerGui.HUD.Chat.InputFrame.TextBox:ReleaseFocus()
player.PlayerGui.HUD.Chat.InputFrame.TextBox.Text = ""
end
end
function ToggleScoreboard()
if scoreboardCanBeToggled then
player.PlayerGui.HUD.Scoreboard.Visible = not player.PlayerGui.HUD.Scoreboard.Visible
end
end
function GetMyPlacing(sortedNames)
for i = 1, #sortedNames do
if sortedNames[i] == player.Name then
return i
end
end
end
function UpdateScoreboard(dt)
spawn(function()
--debug.profilebegin("UpdateScoreboard")
local playerframes = player.PlayerGui.HUD.Scoreboard.Main.PlayerList:GetChildren()
local scoreboard = {}
pcall(function()
scoreboard = events.GetPlayerScores:InvokeServer()
end)
local sortedNames = mathLib.SortScoreboardBy(scoreboard, "Score")
local p1, p2
PrevSituation = CurrentSituation
--print("prev sit: "..PrevSituation.." cur sit: "..CurrentSituation)
if sortedNames ~= nil then
p1 = sortedNames[1] or "Player1"
p2 = sortedNames[2] or "Player2"
if #sortedNames > 1 then
if p1 == player.Name and not (scoreboard[p1].Score == scoreboard[p2].Score) then
CurrentSituation = "LEAD"
elseif p1 ~= player.Name and not (p2 == player.Name and scoreboard[p1].Score == scoreboard[p2].Score) then
CurrentSituation = "NOT_LEADING_OR_TIED"
elseif scoreboard[p1].Score == scoreboard[p2].Score and (p1 == player.Name or p2 == player.Name) then
CurrentSituation = "TIED"
end
else
CurrentSituation = "LEAD"
end
if CurrentSituation ~= PrevSituation then
if CurrentSituation == "TIED" then
sndLib.PlaySoundClient("global", "tied_for_the_lead", "rbxassetid://822279510", 0.3, 1, false, 4)
elseif CurrentSituation == "LEAD" then
sndLib.PlaySoundClient("global", "taken_the_lead", "rbxassetid://822279334", 0.3, 1, false, 4)
elseif CurrentSituation == "NOT_LEADING_OR_TIED" then
sndLib.PlaySoundClient("global", "lost_the_lead", "rbxassetid://822279169", 0.3, 1, false, 4)
end
end
end
if sortedNames ~= nil then
for i, plrname in pairs(sortedNames) do
local scores = scoreboard[plrname]
local plr = game.Players:FindFirstChild(plrname)
if plr then
spawn(function()
local f = player.PlayerGui.HUD.Scoreboard.Main.PlayerList:FindFirstChild(plr.Name)
if not f then
f = game.ReplicatedStorage.PlayerFrame:Clone()
f.Size = UDim2.new(1, 0, 0.1, 0)
f.Name = plr.Name
f.Position = UDim2.new(0, 0, 0.1 * i, 0)
f.BackgroundTransparency = 1
f.Parent = player.PlayerGui.HUD.Scoreboard.Main.PlayerList
f.Icon.Image = game:GetService("Players"):GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size48x48)
end
player.PlayerGui.HUD.Scoreboard.Placing.Text = mathLib.IntegerToNumeral(GetMyPlacing(sortedNames))
if CurrentSituation == "TIED" then
player.PlayerGui.HUD.Scoreboard.PlacingFrags.Text = " place with "..tostring(scores.Kills).." (TIED)"
else
player.PlayerGui.HUD.Scoreboard.PlacingFrags.Text = " place with "..tostring(scores.Kills)
end
f.Position = UDim2.new(0, 0, 0.1 * i, 0)
local suffix = ""
if IsDeveloper(plr.Name) then
suffix = " (DEV)"
end
f.PlayerName.Text = plr.Name .. suffix
f.Score.Text = scores.Score
f.Time.Text = mathLib.SecondsToTimerFormat(ClientTime)
f.Ping.Text = (PlayerLatencies[plr.UserId] or 0).."ms"
f.KD.Text = scores.Kills.." / "..scores.Deaths
f.DMG.Text = scores.Damage
end)
end
end
end
--debug.profileend()
end)
end
function CreateChatMessage(sender, msg, ypos, isSystemMessage)
local f = game.ReplicatedStorage.ChatMessage:Clone()
local suffix = ""
if IsDeveloper(sender) then
suffix = " (DEV)"
f.Sender.TextColor3 = Color3.new(0.8, 0.05, 0.05)
end
f.Sender.Text = sender..suffix..":"
f.Body.Text = msg
if isSystemMessage then
f:Destroy()
f = game.ReplicatedStorage.SystemChatMessage:Clone()
f.Body.Text = msg
f.Sender.Text = ""
end
print(f.Sender.Text .. f.Body.Text)
for _, msg in pairs(player.PlayerGui.HUD.Chat.Messages:GetChildren()) do
if msg.Name == "ChatMessage" or msg.Name == "SystemChatMessage" then
msg.Position = UDim2.new(msg.Position.X.Scale, msg.Position.X.Offset, msg.Position.Y.Scale - 0.1, 0)
end
end
if #player.PlayerGui.HUD.Chat.Messages:GetChildren() >= 7 then
local o = GetOldestMessage()
o:Destroy()
end
f.Position = UDim2.new(0, 0, 0.7, 0)
local x = game:GetService("TextService"):GetTextSize(f.Sender.Text, f.Sender.TextSize, f.Sender.Font, f.Sender.AbsoluteSize).X
f.Body.Position = UDim2.new(0, x + 18, 0, 0)
f.Parent = player.PlayerGui.HUD.Chat.Messages
sndLib.PlaySoundClient("global", "chatnotification", "rbxassetid://821076180", 0.4, 1, false, 2)
f.Time.Value = ClientTime
end
function UpdateChat(dt)
spawn(function()
--debug.profilebegin("UpdateChat")
local newchatlog = {}
pcall(function()
newchatlog = events.GetServerChat:InvokeServer()
end)
if #newchatlog > #chatlog then
--print("new messages found")
local numNewMessages = #newchatlog - #chatlog
--print(numNewMessages.." new messages")
if numNewMessages > 0 then
for i = #newchatlog, 1, -1 do
if i <= #newchatlog - numNewMessages then
break
end
--print("working on message #"..i)
local msg = newchatlog[i]
if msg.GameInfo == true then
CreateChatMessage(msg.Sender, msg.Body, 0.7 - (0.1 * #newchatlog), true)
else
--print("creating the message")
CreateChatMessage(msg.Sender, msg.Body, 0.7 - (0.1 * #newchatlog), false)
end
end
--print("done fetching")
chatlog = newchatlog
--local msg = newchatlog[#newchatlog]
--CreateChatMessage(msg.Sender, msg.Body, 0.7 - (0.1 * #newchatlog))
--chatlog = newchatlog
end
end
for _, msg in pairs(player.PlayerGui.HUD.Chat.Messages:GetChildren()) do
if msg.Name == "ChatMessage" or msg.Name == "SystemChatMessage" then
if math.abs(ClientTime - msg.Time.Value) > ConVars["cl_chat_message_displaytime"][1] and chatVisible then
msg.Body.TextTransparency = 0
msg.Sender.TextTransparency = 0
elseif math.abs(ClientTime - msg.Time.Value) > ConVars["cl_chat_message_displaytime"][1] and not chatVisible then
msg.Body.TextTransparency = 1
msg.Sender.TextTransparency = 1
else
msg.Body.TextTransparency = 0
msg.Sender.TextTransparency = 0
end
end
end
--debug.profileend()
end)
end
function UpdateCamera(dt)
--debug.profilebegin("UpdateCamera")
if thirdperson then
cam.CFrame = CFrame.new(char:GetPrimaryPartCFrame().p) * CFrame.Angles(0, thirdpersonangle, 0) * CFrame.new(0, 0, 5)
thirdpersonangle = thirdpersonangle + math.rad(thirdpersonRotSpeed * dt)
else
do
if char.PrimaryPart ~= nil and PlayerStats.Health > 0 then
local xRot = CFrame.Angles(-mouseAngles.Y, 0, 0)
local yRot = CFrame.Angles(0, -mouseAngles.X, 0)
local pos = char.PrimaryPart.Position + Vector3.new(0, 2, 0)
cam.CFrame = CFrame.new(pos) * yRot * xRot
cam.Focus = cam.CFrame
prevCamCF = cam.CFrame
else
cam.CFrame = prevCamCF
cam.Focus = cam.CFrame
end
end
end
--debug.profileend()
end
local grounded = true
local timeGrounded = 0
function GetWeaponBob()
local a = (math.sin(bobtimer) / 7.5) * ConVars["cl_weaponbob_amt"][1]
local b = (math.sin(2 * bobtimer) / 7.5) * ConVars["cl_weaponbob_amt"][1]
if movementKeysDown.W or movementKeysDown.A or movementKeysDown.S or movementKeysDown.D then
return weaponCode.ViewModel_Bob(a, b)
else
return CFrame.new()
end
end
function UpdateRender(dt)
--debug.profilebegin("UpdateRender")
UpdateCamera(dt)
bobtimer = bobtimer + (5 * dt * ConVars["cl_weaponbob_rate"][1])
local chars = workspace.Characters:GetChildren()
for _, mdl in pairs(chars) do
local rarm = mdl:FindFirstChild("Right Arm")
local larm = mdl:FindFirstChild("Left Arm")
local hrp = mdl:FindFirstChild("HumanoidRootPart")
local arms = mdl:FindFirstChild("ArmsViewmodel")
if rarm and larm then
rarm.Transparency = 1
larm.Transparency = 1
rarm.LocalTransparencyModifier = 1
larm.LocalTransparencyModifier = 1
end
if arms then
for _, p in pairs(arms:GetChildren()) do
p.Transparency = 1
p.LocalTransparencyModifier = 1
end
end
if hrp then
hrp.Transparency = 1
hrp.LocalTransparencyModifier = 1
end
end
local actualMouseRay = Ray.new(mouse.UnitRay.Origin, mouse.UnitRay.Direction * 999)
local hit, pos, norm = workspace:FindPartOnRayWithWhitelist(actualMouseRay, {})
actualMouseHit = pos
local hitwall = false
for _, p in pairs(char:GetChildren()) do
if p:IsA("BasePart") then
p.Transparency = 1
end
end
if RAYMDL ~= nil then
RAYMDL:Destroy()
end
--RAYMDL = DrawLineDebug(char:GetPrimaryPartCFrame().p, char:GetPrimaryPartCFrame().p + char:GetPrimaryPartCFrame().lookVector * 5)
if grounded then
timeGrounded = timeGrounded + dt
else
timeGrounded = 0
end
grounded = Grounded(dt)
accelDir = Vector3.new()
if PlayerStats.Health > 0 and not player.PlayerGui.HUD.Chat.InputFrame.Visible and canwalk then
if movementKeysDown.W then
accelDir = accelDir + CFrame.Angles(0, math.rad(0), 0) * (cam.CFrame.lookVector * Vector3.new(1,0,1)).unit
end
if movementKeysDown.S then
accelDir = accelDir + CFrame.Angles(0, math.rad(-180), 0) * (cam.CFrame.lookVector * Vector3.new(1,0,1)).unit
end
if movementKeysDown.A then
accelDir = accelDir + CFrame.Angles(0, math.rad(90), 0) * (cam.CFrame.lookVector * Vector3.new(1,0,1)).unit
end
if movementKeysDown.D then
accelDir = accelDir + CFrame.Angles(0, math.rad(-90), 0) * (cam.CFrame.lookVector * Vector3.new(1,0,1)).unit
end
end
if (grounded and timeGrounded > 0.15) and not jumping then
player.PlayerGui.HUD.SpeedTypeLabel.Text = "MoveGround"
playerVelocity = MoveGround(accelDir, playerVelocity, dt, grounded) + VelOffset + pushVector
else
if jumpedOnPrevFrame then
jumpedOnPrevFrame = false
end
player.PlayerGui.HUD.SpeedTypeLabel.Text = "MoveAir"
playerVelocity = MoveAir(accelDir, playerVelocity, dt, grounded)
playerVelocity = playerVelocity + (Vector3.new(0, -workspace.Gravity / 2, 0) * dt) + pushVector
end
if movementKeysDown.Space and not jumping and PlayerStats.Health > 0 and grounded and not player.PlayerGui.HUD.Chat.InputFrame.Visible then
jumpedOnPrevFrame = true
jumping = true
sndLib.PlaySoundClient("global", "jump", "rbxassetid://821077345", 0.3, 1, false, 1)
spawn(function()
while true do
local dt = game:GetService("RunService").RenderStepped:wait()
local grounded = Grounded(dt)
if grounded then
break
end
end
wait()
jumping = false
end)
playerVelocity = playerVelocity + Vector3.new(0, 32.5, 0)
end
player.PlayerGui.HUD.SpeedLabel.Text = math.abs(math.floor(playerVelocity.magnitude))
prevVelocity = playerVelocity
--print(playerVelocity)
local function raycast(orig, dir)
return workspace:FindPartOnRayWithIgnoreList(Ray.new(orig, dir), {char, workspace.Ignore, workspace.PlayerSpawns, workspace.ItemPickups, workspace.ItemSpawns, workspace.Nodes})
end
-- Radius of player's hitbox:
local playerRadius = 2.95
-- STEP 1: cast forward into movement direction to find initial collision with wall:
-- (i.e. so you dont teleport the player into wall to begin with)
local origin = char:GetPrimaryPartCFrame().p -- player's current position
local movement = playerVelocity * dt -- player's movement vector
local movement_xz_unit = (playerVelocity * Vector3.new(1,0,1)).unit
local hitboxadjust = movement_xz_unit * playerRadius -- offset to be applied to take into account hitbox as well
-- Check for hit within movement vector:
local hit, hitpos = raycast(origin, movement)
if hit then
-- Hit found, so move to the wall position and move back from wall by hitboxadjust:
hitwall = true
origin = hitpos - hitboxadjust
playerVelocity = Vector3.new(0, playerVelocity.Y, 0)
else
-- No hit, simply move to the position:
origin = origin + movement
end
-- STEP 2: cast in a fan to check for collisions:
-- (i.e. making sure a player is approximately playerRadius away from any objects in any direction)
-- Precalculate direction vectors for angle-pairs:
local directionVector = {}
for i = -180, -0.1, 22.5 do
directionVector[i] = CFrame.Angles(0,math.rad(i),0) * hitboxadjust
end
-- Which angle-pairs have been done:
local done = {}
-- Do 8 rounds of correction (one for each angle-pair):
for _ = 1,8 do
-- Running variables:
local m = .001 -- Magnitude of maximum displacement
local n = nil -- Maximum displacement
local o = nil -- Angle of maximum displacement
-- Loop over all angle-pairs:
for i = -180, -0.1, 22.5 do
-- If we have corrected at this angle-pair already then we won't correct again this frame:
if not done[i] then
-- Raycast positive/negative angle (these rays are opposite):
local hit1, pos1 = raycast(origin, directionVector[i])
local hit2, pos2 = raycast(origin, -directionVector[i])
-- Determine offset in this angle-pair:
local off = Vector3.new(0,0,0)
if hit1 then
-- For negative angle:
hitwall = true
off = (directionVector[i] - (pos1 - origin))
end
if hit2 then
-- For positive angle:
hitwall = true
off = off + (-directionVector[i] - (pos2 - origin))
end
-- Check if displacement is greater than the tracked displacement:
if off.magnitude > m then
-- It's bigger, so update running variables:
m = off.magnitude
n = off
o = i
end
end
end
-- Check if a maximum displacement was found:
if o then
-- Apply the displacement for angle-pair 'o':
origin = origin - n
-- This angle-pair is now done:
done[o] = true
else
-- No displacement in any direction, so just stop:
break
end
end
char:SetPrimaryPartCFrame(CFrame.new(origin) * CFrame.Angles(0, -mouseAngles.X, 0))
if hitwall and not grounded then
--playerVelocity = Vector3.new(0, playerVelocity.Y, 0)
end
if char.PrimaryPart.Position.Y < -900 and not falldeath then
TakeDamage(9000, "World")
Orakel.Log(player.Name.. " could not fly.")
falldeath = true
playerVelocity = Vector3.new()
spawn(function()
wait(4)
falldeath = false
end)
elseif char.PrimaryPart.Position.Y < -900 and falldeath then
playerVelocity = Vector3.new()
end
pushVector = Vector3.new()
clouds.CFrame = CFrame.new(char.Torso.Position.X, 67, char.Torso.Position.Z) * CFrame.Angles(math.rad(180), 0, 0)
for _, tex in pairs(clouds.SurfaceGui:GetChildren()) do
tex.Position = tex.Position + UDim2.new(0.05 * dt, 0, 0, 0)
if tex.Position.X.Scale > 2 then
tex.Position = UDim2.new(-2, 0, 0, 0)
end
end
if equippedWeapon then
--if UseWeaponViewmodel then
local a = (math.sin(bobtimer) / 7.5) * ConVars["cl_weaponbob_amt"][1]
local b = (math.sin(2 * bobtimer) / 7.5) * ConVars["cl_weaponbob_amt"][1]
--if weaponCode.ViewModel_Bob then
equippedWeapon:SetPrimaryPartCFrame(
CFrame.new(cam.CFrame.p, mouse.Hit.p)
* CFrame.new(weaponCode.ViewModel.Offset.X, weaponCode.ViewModel.Offset.Y, weaponCode.ViewModel.Offset.Z)
* CFrame.Angles(math.rad(weaponCode.ViewModel.Angle.X), math.rad(weaponCode.ViewModel.Angle.Y), math.rad(weaponCode.ViewModel.Angle.Z))
* GetWeaponBob() --CFrame.new(a, b, 0)
)
--end
--else
--equippedWeapon:SetPrimaryPartCFrame(
--CFrame.new(cam.CFrame.p, mouse.Hit.p)
--* CFrame.new(script.Offset.Value.X, script.Offset.Value.Y, script.Offset.Value.Z)
--* CFrame.Angles(math.rad(script.Angle.Value.X), math.rad(script.Angle.Value.Y), math.rad(script.Angle.Value.Z))
--)
--end
end
if barrierUp and not workspace.Ignore:FindFirstChild("Barrier") then
local barrier = game.ReplicatedStorage.Particles.Barrier:Clone()
barrier.Parent = workspace.Ignore
elseif not barrierUp then
local barrier = workspace.Ignore:FindFirstChild("Barrier")
if barrier then
barrier:Destroy()
end
end
local barrier = workspace.Ignore:FindFirstChild("Barrier")
if barrier then
--barrier:SetPrimaryPartCFrame(equippedWeapon:GetPrimaryPartCFrame() * CFrame.Angles(math.rad(script.Angle.Value.X), math.rad(script.Angle.Value.Y), math.rad(script.Angle.Value.Z)))
barrier:SetPrimaryPartCFrame(CFrame.new(char:GetPrimaryPartCFrame().p, actualMouseHit))
end
--debug.profileend()
end
local falldeath = false
function TakeDamage(damage, damageGiver)
if not falldeath then
local dmg = damage
if PlayerStats.Armor > 0 then
local armourCanAbsorb = math.min(math.floor(dmg*(2/3)), PlayerStats.Armor)
dmg = dmg - armourCanAbsorb
PlayerStats.Armor = math.clamp(PlayerStats.Armor - armourCanAbsorb, 0, 9000)
end
PlayerStats.Health = math.clamp(PlayerStats.Health - dmg, 0, 9000)
--spawn blood on screen
if ConVars["cl_violence"][1] then
local blood = Instance.new("ImageLabel")
blood.BackgroundTransparency = 1
blood.Size = UDim2.new(0.259, 0, 0.5, 0)
blood.Position = UDim2.new(math.random(), 0, math.random(), 0)
blood.Image = "rbxassetid://313082863"
blood.Rotation = math.random() * 360
blood.Parent = player.PlayerGui.HUD.HurtFrame
spawn(function()
wait(3)
local t = 0
while t <= 2 do
local dt = game:GetService("RunService").RenderStepped:wait()
t = t + dt
blood.ImageTransparency = blood.ImageTransparency + (dt * 2)
end
blood:Destroy()
end)
end
--hurt sounds
if PlayerStats.Health <= 0 then
--death sound
sndLib.PlaySoundClient("global", "die", Orakel.TRand(assetLib.HurtSounds.DieHuman), 0.4, 1, false, 2)
lastHurtSound = tick() + 20
player.PlayerGui.HUD.Scoreboard.Visible = true
player.PlayerGui.HUD.Scoreboard.Fraggedby.Text = "Fragged by "..tostring(damageGiver)
player.PlayerGui.HUD.Scoreboard.Fraggedby.Visible = true
elseif PlayerStats.Health > 0 and math.abs(tick() - lastHurtSound) > 1 then
--hurt sound
sndLib.PlaySoundClient("global", "hurt", Orakel.TRand(assetLib.HurtSounds.HurtHuman), 0.4, 1, false, 2)
lastHurtSound = tick()
end
end
end
local jumping = false
function UpdateHeartbeat(dt)
--debug.profilebegin("UpdateHeartbeat")
ClientTime = ClientTime + dt
for _, plr in pairs(game.Players:GetPlayers()) do
local mdl = workspace.Characters:FindFirstChild(plr.Name)
if mdl then
local hrp = mdl:FindFirstChild("HumanoidRootPart")
if hrp then
if hrp.Position.Y <= -30 then
--print("HRP FALLIN OUT OF MAP")
end
end
end
end
--Update ui health labels and health bars
player.PlayerGui.HUD.VitalsFrame.Health.TextLabel.Text = math.ceil(PlayerStats.Health).."/"..PlayerStats.MaxHealth
player.PlayerGui.HUD.VitalsFrame.Health.Bar.Filler.Size = UDim2.new(PlayerStats.Health / PlayerStats.MaxHealth, 0, 1, 0)
player.PlayerGui.HUD.VitalsFrame.Armor.TextLabel.Text = math.ceil(PlayerStats.Armor).."/"..PlayerStats.MaxArmor
player.PlayerGui.HUD.VitalsFrame.Armor.Bar.Filler.Size = UDim2.new(PlayerStats.Armor / PlayerStats.MaxArmor, 0, 1, 0)
--adjust ui health bar colours
if PlayerStats.Health > PlayerStats.MaxHealth then
player.PlayerGui.HUD.VitalsFrame.Health.Bar.Filler.BackgroundColor3 = Color3.new(0, 243/255, 1)
else
player.PlayerGui.HUD.VitalsFrame.Health.Bar.Filler.BackgroundColor3 = Color3.new(0, 1, 93/255)
end
if PlayerStats.Armor > PlayerStats.MaxArmor then
player.PlayerGui.HUD.VitalsFrame.Armor.Bar.Filler.BackgroundColor3 = Color3.new(0, 243/255, 1)
else
player.PlayerGui.HUD.VitalsFrame.Armor.Bar.Filler.BackgroundColor3 = Color3.new(0, 1, 93/255)
end
--Update ammo values and weapon icons on UI
for _, frame in pairs(player.PlayerGui.HUD.WeaponsFrame:GetChildren()) do
frame.Ammo.Text = tostring(PlayerStats.Weapons[frame.Name].Ammo)
end
player.PlayerGui.HUD.AmmoFrame.ImageLabel.Image = player.PlayerGui.HUD.WeaponsFrame[equippedWeapon.Name].Icon.Image
player.PlayerGui.HUD.AmmoFrame.TextLabel.Text = tostring(PlayerStats.Weapons[equippedWeapon.Name].Ammo)
--Lose health and armor constantly if n > 100
if PlayerStats.Health > PlayerStats.MaxHealth then
PlayerStats.Health = PlayerStats.Health - 0.6 * dt
end
if PlayerStats.Armor > PlayerStats.MaxArmor then
PlayerStats.Armor = PlayerStats.Armor - 0.6 * dt
end
--Die in roblox
if PlayerStats.Health <= 0 and not respawning then
respawning = true
spawn(function()
canfire = false
local dspawns = workspace.PlayerDebugSpawns:GetChildren()
local dspawn = dspawns[math.random(1, #dspawns)]
char:SetPrimaryPartCFrame(dspawn.CFrame)
wait(4)
playerVelocity = Vector3.new()
SwitchWeapon(equippedWeapon, 1, 1, false)
canfire = true
char.Humanoid.WalkSpeed = 32
player.PlayerGui.HUD.Scoreboard.Visible = false
player.PlayerGui.HUD.Scoreboard.Fraggedby.Visible = false
--char.Humanoid.Health = 0
PlayerStats.Health = 100
PlayerStats.Armor = 15
PlayerStats.Weapons.Machinegun.Ammo = 100
local spawns = workspace.PlayerSpawns:GetChildren()
local cspawn = spawns[math.random(1, #spawns)]
char:SetPrimaryPartCFrame(cspawn.CFrame)
respawning = false
end)
end
--Fire weapon, TODO: implement single-fire instead of always-auto?
if m1down and PlayerStats.Weapons[equippedWeapon.Name].Ammo > 0 then
local ps = weaponCode.RateOfFire / 60
local rof = 1 / ps
if tick() - lastShotFired >= rof and canfire then
game.ReplicatedStorage.WeaponFiredClient:Fire()
PlayerStats.Weapons[equippedWeapon.Name].Ammo = PlayerStats.Weapons[equippedWeapon.Name].Ammo - 1
weaponCode.Fire(player, equippedWeapon, cam.CFrame.p, mouse.Hit.p, char)
events.FireWeaponServer:FireServer(player, equippedWeapon.Name, cam.CFrame.p, mouse.Hit.p)
if weaponCode.Fired ~= nil then
if not weaponCode.Fired then
weaponCode.FireOnce(player)
weaponCode.Fired = true
end
end
lastShotFired = tick()
end
weaponCode.Update(dt, equippedWeapon, true)
else
weaponCode.Update(dt, equippedWeapon, false) --only necessary for the machinegun's barrel spin
if weaponCode.StopFire ~= nil then
weaponCode.StopFire()
end
end
for _, item in pairs(pickups) do
if item.ClassName == "Model" then
item:SetPrimaryPartCFrame(item:GetPrimaryPartCFrame() * CFrame.new(0, 0, itemFloatHeight * math.sin(tick() % 10000)) * CFrame.Angles(0, 0, math.rad(180 * dt)))
else
--item.CFrame = item.CFrame * CFrame.Angles(0, 0, math.rad(180 * dt))
item.CFrame = item.CFrame * CFrame.new(0, 0, itemFloatHeight * math.sin(tick() % 10000)) * CFrame.Angles(0, 0, math.rad(180 * dt))
--local ypos = itemFloatHeight * math.sin(tick() % 10000)
end
end
local arms = char:FindFirstChild("ArmsViewmodel")
if charInvisible then
Orakel.RecursiveSearch(char.Head, function(obj) return (obj.ClassName == "Decal") end, function(obj) obj.Transparency = 1 end)
Orakel.ToggleVisible(char, 1, false)
Orakel.ToggleVisible(arms, 1, false, {"Part"})
if not equippedWeapon.Name == "Machinegun" then
Orakel.ToggleVisible(equippedWeapon, 1, false, {"Muzzle", "Barrel"})
else
Orakel.ToggleVisible(equippedWeapon, 1, false, {"Muzzle"})
end
else
Orakel.RecursiveSearch(char.Head, function(obj) return (obj.ClassName == "Decal") end, function(obj) obj.Transparency = 0 end)
Orakel.ToggleVisible(char, 0, false)
Orakel.ToggleVisible(arms, 0, false, {"Part"})
Orakel.ToggleVisible(equippedWeapon, 0, false, {"Muzzle", "Barrel"})
end
player.PlayerGui.HUD.ScoreFrame.RoundTimer.Text = mathLib.SecondsToTimerFormat(game.ReplicatedStorage.GetServerRoundTime:InvokeServer())
--debug.profileend()
end
function InputBegan(io)
if io.UserInputType == Enum.UserInputType.MouseButton1 then
if not ConsoleVisible then
m1down = true
end
--elseif io.UserInputType == Enum.UserInputType.MouseWheel then
--print("mwheel")
--SwitchWeapon(equippedWeapon, io.Position.Z)
elseif io.UserInputType == Enum.UserInputType.MouseButton2 then
cam.FieldOfView = ConVars["cl_zoomfov"][1]
elseif io.UserInputType == Enum.UserInputType.Keyboard then
if not ConsoleVisible then
for key,_ in pairs(movementKeysDown) do
if key == io.KeyCode.Name then
movementKeysDown[key] = true
end
end
end
if ConsoleInputFocused then
if io.KeyCode == Enum.KeyCode.Up then
currentCmdIndex = math.clamp(currentCmdIndex - 1, 0, #PreviousCmds)
if currentCmdIndex ~= nil then
player.PlayerGui.HUD.Console.InputBox.Text = PreviousCmds[currentCmdIndex]
end
elseif io.KeyCode == Enum.KeyCode.Down then
currentCmdIndex = math.clamp(currentCmdIndex + 1, 0, #PreviousCmds)
if currentCmdIndex ~= nil then
player.PlayerGui.HUD.Console.InputBox.Text = PreviousCmds[currentCmdIndex]
end
end
end
--print(io.KeyCode.Name)
if io.KeyCode == Enum.KeyCode.T and not chatVisible and not ConsoleVisible then
ToggleChatWindow()
end
if io.KeyCode == Enum.KeyCode.Backquote or io.KeyCode == Enum.KeyCode.Tilde and not chatVisible and not ConsoleVisible then
player.PlayerGui.HUD.Console.InputBox:CaptureFocus()
player.PlayerGui.HUD.Console.InputBox.Text = ""
player.PlayerGui.HUD.Console.Visible = true
ConsoleVisible = true
elseif io.KeyCode == Enum.KeyCode.Backquote or io.KeyCode == Enum.KeyCode.Tilde and ConsoleVisible then
player.PlayerGui.HUD.Console.InputBox.Text = ""
player.PlayerGui.HUD.Console.Visible = false
ConsoleVisible = false
end
if io.KeyCode == Enum.KeyCode.F and PlayerStats.Health > 0 and not ConsoleVisible then
UseAbility()
end
if io.KeyCode == Enum.KeyCode.Return and chatVisible then
SendCurrentBody()
ToggleChatWindow()
end
if io.KeyCode == Enum.KeyCode.Tab and PlayerStats.Health > 0 then
ToggleScoreboard()
end
elseif io.UserInputType == Enum.UserInputType.MouseMovement then
local SENSITIVITY = Vector3.new(ConVars["cl_sensitivity"][1], ConVars["cl_sensitivity"][1], 0) --horizontal, vertical, zoom?
local delta = math.rad(1) * io.Delta * SENSITIVITY
local clampedY = math.clamp(mouseAngles.Y + delta.Y, MOUSE_MIN, MOUSE_MAX)
mouseAngles = Vector2.new(mouseAngles.X + delta.X, clampedY)
end
end
function InputChanged(io)
if io.UserInputType == Enum.UserInputType.MouseWheel and not ConsoleVisible then
SwitchWeapon(equippedWeapon, io.Position.Z)
end
if io.UserInputType == Enum.UserInputType.MouseMovement then
local SENSITIVITY = Vector3.new(ConVars["cl_sensitivity"][1], ConVars["cl_sensitivity"][1], 0) --horizontal, vertical, zoom?
local delta = math.rad(1) * io.Delta * SENSITIVITY
local clampedY = math.clamp(mouseAngles.Y + delta.Y, MOUSE_MIN, MOUSE_MAX)
--print(math.deg(clampedY))
mouseAngles = Vector2.new(mouseAngles.X + delta.X, clampedY)
end
end
function InputEnded(io)
if io.UserInputType == Enum.UserInputType.MouseButton1 then
m1down = false
elseif io.UserInputType == Enum.UserInputType.MouseButton2 then
cam.FieldOfView = ConVars["cl_fov"][1]
elseif io.UserInputType == Enum.UserInputType.Keyboard then
for key,_ in pairs(movementKeysDown) do
if key == io.KeyCode.Name then
movementKeysDown[key] = false
end
end
if io.KeyCode == Enum.KeyCode.Tab and PlayerStats.Health > 0 then
ToggleScoreboard()
end
elseif io.UserInputType == Enum.UserInputType.MouseMovement then
local SENSITIVITY = Vector3.new(ConVars["cl_sensitivity"][1], ConVars["cl_sensitivity"][1], 0) --horizontal, vertical, zoom?
local delta = math.rad(1) * io.Delta * SENSITIVITY
local clampedY = math.clamp(mouseAngles.Y + delta.Y, MOUSE_MIN, MOUSE_MAX)
mouseAngles = Vector2.new(mouseAngles.X + delta.X, clampedY)
end
end
function ToggleGameUI(enabled)
player.PlayerGui.HUD.PingLabel.Visible = enabled
player.PlayerGui.HUD.SpeedLabel.Visible = enabled
player.PlayerGui.HUD.SpeedTypeLabel.Visible = enabled
player.PlayerGui.HUD.WeaponsFrame.Visible = enabled
player.PlayerGui.HUD.VitalsFrame.Visible = enabled
player.PlayerGui.HUD.Killfeed.Visible = enabled
player.PlayerGui.HUD.AmmoFrame.Visible = enabled
player.PlayerGui.HUD.HurtFrame.Visible = enabled
player.PlayerGui.HUD.SpecialAbility.Visible = enabled
end
function Init()
for _, plr in pairs(game.Players:GetPlayers()) do
PlayerLatencies[plr.UserId] = 0
end
UpdatePlayerData(0)
local hud = player.PlayerGui:WaitForChild("HUD")
local con = hud:WaitForChild("Console")
local ibox = con:WaitForChild("InputBox")
local btn = con:WaitForChild("Button")
local ebtn = con:WaitForChild("ExitButton")
ebtn.MouseButton1Click:connect(function()
ConsoleInputFocused = false
con.Visible = false
ConsoleVisible = false
end)
btn.MouseButton1Click:connect(function()
local txt = ibox.Text
table.insert(PreviousCmds, txt)
ParseCommandLine(txt)
ibox.Text = ""
end)
ibox.FocusLost:connect(function(enterpressed, input)
ConsoleInputFocused = false
if enterpressed then
local txt = ibox.Text
table.insert(PreviousCmds, txt)
ParseCommandLine(txt)
ibox.Text = ""
player.PlayerGui.HUD.Console.InputBox:CaptureFocus()
end
end)
ibox.Focused:connect(function(enterpressed, input)
ConsoleInputFocused = true
end)
Orakel.Log("initializing client...")
wait(.5)
mouse.TargetFilter = workspace.Ignore
cam.CameraType = Enum.CameraType.Scriptable
game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
wait()
for _, wmodule in pairs(game.ReplicatedStorage.Weapons:GetChildren()) do
weaponData[wmodule.Name] = require(wmodule)
end
local dir = workspace:FindFirstChild("Characters") or Instance.new("Model", workspace)
if dir.Name ~= "Characters" then dir.Name = "Characters" end
dir.ChildAdded:connect(function(c)
c.ChildRemoved:connect(function(c)
--print(tostring(c))
end)
end)
local mychar = CreatePlayerModel(player)
char = mychar
PlayerModels[player.Name] = mychar
wait()
player.PlayerGui:WaitForChild("Music"):Play()
clouds = game.ReplicatedStorage.Clouds:Clone()
clouds.CFrame = CFrame.new(char.Torso.Position.X, 67, char.Torso.Position.Z)
clouds.Parent = workspace.Ignore
local wna = ConVars["mp_startingweapon"][1]
local mg = game.ReplicatedStorage.Models[wna]:Clone()
mg.Parent = char
equippedWeapon = mg
weaponCode = require(game.ReplicatedStorage.Weapons[equippedWeapon.Name])
weaponCode.Equip()
--[[
local la = mg:FindFirstChild("Left Arm")
local ra = mg:FindFirstChild("Right Arm")
if la and ra then
la.Transparency = 1
ra.Transparency = 1
end]]
game:GetService("RunService").Heartbeat:connect(UpdateHeartbeat)
game:GetService("RunService").RenderStepped:connect(UpdateRender)
--game:GetService("RunService").RenderStepped:connect(UpdateCamera)
game:GetService("UserInputService").InputBegan:connect(InputBegan)
game:GetService("UserInputService").InputEnded:connect(InputEnded)
game:GetService("UserInputService").InputChanged:connect(InputChanged)
game.ReplicatedStorage.PlaySoundClient.OnClientEvent:connect(sndLib.PlaySoundClient)
game.ReplicatedStorage.TakeDamage.OnClientEvent:connect(TakeDamage)
game.ReplicatedStorage.GiveAmmo.OnClientEvent:connect(function(wname, amt)
--print("taking "..amt.." ammo for "..wname)
PlayerStats.Weapons[wname].Ammo = math.clamp(PlayerStats.Weapons[wname].Ammo + amt, 0, PlayerStats.Weapons[wname].MaxAmmo)
end)
game.ReplicatedStorage.GiveHealth.OnClientEvent:connect(function(amt)
--print("taking "..amt.." health")
if amt >= 100 then
PlayerStats.Health = math.clamp(PlayerStats.Health + amt, 0, 200)
else
if PlayerStats.Health + amt < 100 then
PlayerStats.Health = math.clamp(PlayerStats.Health + amt, 0, PlayerStats.MaxHealth)
else
PlayerStats.Health = math.clamp(PlayerStats.Health + amt, 0, 200)
end
end
end)
game.ReplicatedStorage.GiveArmor.OnClientEvent:connect(function(amt)
--print("taking "..amt.." armor")
if amt >= 100 then
PlayerStats.Armor = math.clamp(PlayerStats.Armor + amt, 0, 200)
else
if PlayerStats.Armor + amt < 100 then
PlayerStats.Armor = math.clamp(PlayerStats.Armor + amt, 0, PlayerStats.MaxArmor)
else
PlayerStats.Armor = math.clamp(PlayerStats.Armor + amt, 0, 200)
end
end
end)
game.ReplicatedStorage.GiveTime.OnClientEvent:connect(function(amt)
CooldownReduction = CooldownReduction + amt
end)
game.ReplicatedStorage.PlayerRemoving.OnClientEvent:connect(function(plrname)
print(plrname.. "left the game")
PlayerModels[plrname]:Destroy()
for _, frame in pairs(player.PlayerGui.HUD.Scoreboard.Main.PlayerList:GetChildren()) do
if frame.Name == plrname then
frame:Destroy()
end
end
end)
game.ReplicatedStorage.PlayerAdded.OnClientEvent:connect(function(plr)
if plr ~= nil then
if plr.Name ~= player.Name then
PlayerModels[plr.Name] = CreatePlayerModel(plr)
end
end
end)
game.ReplicatedStorage.SetPlayerLocation.OnClientEvent:connect(function(cframe)
local cf = CFrame.new(cframe.p + Vector3.new(0, 3.5, 0))
playerVelocity = Vector3.new()
StopTweens = true
char:SetPrimaryPartCFrame(cf)
StopTweens = false
playerVelocity = Vector3.new()
end)
game.ReplicatedStorage.CreateKillfeedEntry.OnClientEvent:connect(function(killer, weapon, victim)
print(killer.." killed "..victim.." with "..weapon)
Orakel.Log(killer.." killed "..victim.." with "..weapon)
local kf = game.ReplicatedStorage.Killframe:Clone()
kf.Icon.Image = player.PlayerGui.HUD.WeaponsFrame[weapon].Icon.Image
kf.Killer.Text = killer
kf.Victim.Text = victim
local existingEntries = player.PlayerGui.HUD.Killfeed:GetChildren()
kf.Position = kf.Position + UDim2.new(0, 0, 0.15 * #existingEntries, 0)
spawn(function()
wait(3.5)
local t = 0
while t <= 1 do
local dt = game:GetService("RunService").RenderStepped:wait()
t = t + dt
kf.Killer.TextTransparency = kf.Killer.TextTransparency + dt
kf.Victim.TextTransparency = kf.Victim.TextTransparency + dt
kf.Icon.ImageTransparency = kf.Icon.ImageTransparency + dt
kf.Icon.BackgroundTransparency = kf.Icon.BackgroundTransparency + dt
end
kf:Destroy()
end)
kf.Parent = player.PlayerGui.HUD.Killfeed
end)
game.ReplicatedStorage.AwardFrag.OnClientEvent:connect(function(killedplayer)
--print("awarded frag of "..killedplayer)
player.PlayerGui.HUD.FragLabel.Text = "You Fragged "..killedplayer
player.PlayerGui.HUD.FragLabel.Visible = true
wait(3)
player.PlayerGui.HUD.FragLabel.Visible = false
end)
game.ReplicatedStorage.FireWeaponClient.OnClientEvent:connect(function(shooter, wname, campos, mpos, runserverfire)
local w = weaponData[wname]
local pm = workspace.Characters:FindFirstChild(shooter.Name)
local wm = pm:FindFirstChild(wname)
if w and pm and wm then
if w.ShootEffect ~= nil and shooter.Name ~= player.Name then
w.ShootEffect(wm, mpos)
end
if w.FireServer ~= nil then
w.FireServer(shooter, wm, campos, mpos, player)
end
end
end)
game.ReplicatedStorage.AddConMessage.Event:connect(AddConMessage)
game.ReplicatedStorage.FireAbilityClient.OnClientEvent:connect(function(shooter, wname, campos, mpos, ability)
local ab = require(game.ReplicatedStorage.Abilities[ability])
ab.FireServer(shooter, wname, campos, mpos, player)
end)
game.ReplicatedStorage.Push.OnClientEvent:connect(function(pushorigin, pushforce)
pushVector = (char.PrimaryPart.Position - pushorigin).unit * pushforce
end)
game.ReplicatedStorage.ToggleInvisibilityClient.Event:connect(function(enabled)
charInvisible = enabled
end)
game.ReplicatedStorage.ToggleBarrierClient.Event:connect(function(enabled)
barrierUp = enabled
end)
game.ReplicatedStorage.PlayerDied.OnClientEvent:connect(OtherPlayerDied)
game.ReplicatedStorage.ClearDecals.OnClientEvent:connect(function()
npcLib.ClearDecals()
end)
game.ReplicatedStorage.GameEnded.OnClientEvent:connect(function(scoreboardShowtime, winner)
local endMusic
canfire = false
canwalk = false
charInvisible = true
scoreboardCanBeToggled = false
thirdperson = true
player.PlayerGui.HUD.WinLabel.Visible = true
player.PlayerGui.HUD.Scoreboard.Visible = true
ToggleGameUI(false)
if winner then
sndLib.PlaySoundClient("global", "winspeech", "rbxassetid://1058507658", 1, 1, false, 4)
wait(0.5)
endMusic = sndLib.PlaySoundClient("global", "winmusic", "rbxassetid://1040473875", 0.5, 1, true, -1)
player.PlayerGui.HUD.WinLabel.Text = "Victory"
else
endMusic = sndLib.PlaySoundClient("global", "lossmusic", "rbxassetid://1040474024", 0.5, 1, true, -1)
player.PlayerGui.HUD.WinLabel.Text = "Defeat"
end
wait(scoreboardShowtime)
charInvisible = false
canfire = true
canwalk = true
endMusic:Stop()
endMusic:Destroy()
thirdperson = false
ToggleGameUI(true)
scoreboardCanBeToggled = true
player.PlayerGui.HUD.WinLabel.Visible = false
player.PlayerGui.HUD.Scoreboard.Visible = false
end)
events.ToggleConsole.OnClientEvent:connect(function()
player.PlayerGui.HUD.Console.Visible = true
ConsoleVisible = true
player.PlayerGui.HUD.Console.InputBox:CaptureFocus()
player.PlayerGui.HUD.Console.InputBox.Text = ""
end)
Orakel.Log("done initializing client")
end
function events.GetCurrentWeapon.OnClientInvoke(player, playerToGetFrom)
if equippedWeapon ~= nil then
return equippedWeapon.Name
end
return "Machinegun"
end
function events.GetPlayerHealth.OnClientInvoke()
return PlayerStats.Health
end
function events.GetMouseHit.OnClientInvoke(player, playerToGetFrom)
return mouse.Hit.p
end
function events.GetClientPing.OnClientInvoke()
return latency
end
function events.GetPlayerLocation.OnClientInvoke()
return char.Torso.Position, actualMouseHit, CFrame.Angles(0, -mouseAngles.X, 0)
end
function events.GetPlayerGhosting.OnClientInvoke()
return charInvisible
end
function events.GetPlayerBarrier.OnClientInvoke()
return barrierUp
end
Init()
spawn(function()
while true do
local dt = wait(1/2)
local now = ClientTime
--Only update SERVER convars
local cvars = events.GetSCVars:InvokeServer()
for cvar, data in pairs(cvars) do
if cvar:sub(1,2) == "sv" or cvar:sub(1,2) == "mp" then
ConVars[cvar] = data
end
end
latency = math.abs(mathLib.Round((now - ClientTime) * 1000, 0))
plabel.Visible = ConVars["cl_drawping"][1]
plabel.Text = "Ping: "..latency.."ms"
if latency >= 110 then
plabel.TextColor3 = Color3.new(1, 0, 0)
else
plabel.TextColor3 = Color3.new(1, 1, 1)
end
UpdateChat(dt)
for _, plr in pairs(game.Players:GetPlayers()) do
if plr ~= player then
local s,e = pcall(function()
PlayerLatencies[plr.UserId] = events.GetClientPing:InvokeServer(plr)
end)
if not s then
Orakel.Log("Failed to ping "..tostring(plr.Name).." "..tostring(plr.UserId), "Error")
end
else
PlayerLatencies[plr.UserId] = latency
end
end
end
end)
while true do
local dt = wait(1/20)
--ClientTime = ClientTime + dt
--UpdateChat(dt)
events.SendPlayerData:FireServer(char.Torso.Position, actualMouseHit, CFrame.Angles(0, -mouseAngles.X, 0), charInvisible, barrierUp, equippedWeapon.Name)
UpdateScoreboard(dt)
UpdateJumpPadLogic(dt)
UpdatePlayerData(dt)
UpdatePlayermodels(dt)
end
Orakel.Log("FATAL WARNING: CLIENT HAS EXITED MAIN LOOP !!!!!!!!!", "Error")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment