--@name --@author --@client --[[ TODO: Clean this up TODO: Add keybind for teleport --]] if player() == owner() then do net.start("LSFT-Get-Config") net.writeString("LSFT-Get-Freecam-Binds") net.writeTable({"spectate","speed"}) net.writeTable({"spectate","multiplier"}) net.writeTable({"core","controls","forward"}) net.writeTable({"core","controls","backward"}) net.writeTable({"core","controls","left"}) net.writeTable({"core","controls","right"}) net.writeTable({"core","controls","up"}) net.writeTable({"core","controls","down"}) net.writeTable({"core","controls","run"}) net.writeTable({}) net.send() local SPEED, MULTIPLIER local KEY_FORWARD, KEY_BACKWARD, KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, KEY_RUN net.receive("LSFT-Get-Freecam-Binds", function() SPEED = unpack(net.readTable()) MULTIPLER = unpack(net.readTable()) KEY_FORWARD = unpack(net.readTable()) KEY_BACKWARD = unpack(net.readTable()) KEY_LEFT = unpack(net.readTable()) KEY_RIGHT = unpack(net.readTable()) KEY_UP = unpack(net.readTable()) KEY_DOWN = unpack(net.readTable()) KEY_RUN = unpack(net.readTable()) end) function bool_to_number(input) return input and 1 or 0 end net.receive("LSFT-Start-Spectate", function() local target = nil xpcall(function() target = net.readEntity() end, function() target = nil end) if input.canLockControls() then input.lockControls(true) else --printHud(Color(250,150,50), "Cannot lock controls, exiting!") net.start("LSFT-Stop-Spectate") net.send() return end -- Spectate if target:isValid() and target:isPlayer() then hook.add("calcview", "freecam", function(posin, angin, fovin, znearin, zfarin) if not input.isControlLocked() or not target:isValid() or not target:isPlayer() then --printHud(Color(250,150,50), "Controls are no longer locked, exiting!") hook.remove("calcview", "freecam") net.start("LSFT-Stop-Spectate") net.send() return end if input.isKeyDown(KEY.R) then input.lockControls(false) net.start("LSFT-Teleport-Spectate") net.writeVector(target:getEyePos()) net.send() hook.remove("calcview", "freecam") return end return { origin = target:getEyePos(), angles = target:getEyeAngles(), fov = fovin, znear = znearin, zfar = zfarin } end) else --Freecam local position = eyePos() local lastSentPosition = eyePos() timer.create("updateholo", 0.25, 0, function() if position:getDistance(lastSentPosition) > 10 then net.start("LSFT-LoadHolo-Update") net.writeVector(position) net.send() lastSentPosition = position end end) hook.add("calcview", "freecam", function(posin, angin, fovin, znearin, zfarin) if not input.isControlLocked() then --printHud(Color(250,150,50), "Controls are no longer locked, exiting!") hook.remove("calcview", "freecam") hook.remove("think", "updatepos") timer.remove("updateholo") net.start("LSFT-Stop-Spectate") net.send() return end if input.isKeyDown(KEY.R) then input.lockControls(false) net.start("LSFT-Teleport-Spectate") net.writeVector(position) net.send() hook.remove("calcview", "freecam") hook.remove("think", "updatepos") timer.remove("updateholo") return end return { origin = position, angles = eyeAngles(), fov = fovin, znear = znearin, zfar = zfarin } end) hook.add("think", "updatepos", function() local elevation = eyeAngles().p local bearing = eyeAngles().y local forward = bool_to_number(input.isKeyDown(KEY_FORWARD)) - bool_to_number(input.isKeyDown(KEY_BACKWARD)) local left = bool_to_number(input.isKeyDown(KEY_LEFT)) - bool_to_number(input.isKeyDown(KEY_RIGHT)) local up = bool_to_number(input.isKeyDown(KEY_UP)) - bool_to_number(input.isKeyDown(KEY_DOWN)) local thing = Vector(forward, left, 0) position = position + thing:getRotated(Angle(elevation, bearing, 0)) * SPEED * (input.isKeyDown(KEY_RUN) and MULTIPLER or 1) * (timer.frametime()/(1/(200/3))) position = position + up * Vector(0,0,SPEED) * (input.isKeyDown(KEY_RUN) and MULTIPLER or 1) * (timer.frametime()/(1/(200/3))) end) end end) end end