Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local battlecam = {}
- -- utilities
- local HOOK = function(event) hook.Add(event, "battlecam", battlecam[event]) end
- local UNHOOK = function(event) hook.Remove(event, "battlecam") end
- function battlecam.LimitAngles(pos, dir, fov, prevpos)
- local a1 = dir:Angle()
- local a2 = (pos - prevpos):Angle()
- fov = fov / 3
- dir = a2:Forward() *-1
- a1.p = a2.p + math.Clamp(math.AngleDifference(a1.p, a2.p), -fov, fov)
- fov = fov / (ScrH()/ScrW())
- a1.y = a2.y + math.Clamp(math.AngleDifference(a1.y, a2.y), -fov, fov)
- a1.p = math.NormalizeAngle(a1.p)
- a1.y = math.NormalizeAngle(a1.y)
- return LerpVector(math.Clamp(Angle(0, a1.y, 0):Forward():DotProduct(dir), 0, 1), a1:Forward(), dir * -1)
- end
- function battlecam.LimitPos(pos, dir, ply)
- local vehicle = ply:GetVehicle()
- local trace_forward = util.TraceHull({
- start = ply:EyePos(),
- endpos = pos,
- mins = ply:OBBMins() / 2,
- maxs = ply:OBBMaxs() / 2,
- filter = ents.FindInSphere(pos, 300),
- mask = MASK_SOLID_BRUSHONLY,
- })
- if trace_forward.Hit and trace_forward.Entity ~= ply and not trace_forward.Entity:IsPlayer() and not trace_forward.Entity:IsVehicle() then
- return trace_forward.HitPos + trace_forward.HitNormal * 1
- end
- return pos
- end
- function battlecam.FindHeadPos(ent)
- if not ent.bc_head or ent.bc_last_mdl ~= ent:GetModel() then
- for i = 0, ent:GetBoneCount() do
- local name = ent:GetBoneName(i):lower()
- if name:find("head") then
- ent.bc_head = i
- ent.bc_last_mdl = ent:GetModel()
- break
- end
- end
- end
- local pos, ang = ent.bc_head and ent:GetBonePosition(ent.bc_head)
- return pos or ent:EyePos(), ang or ent:EyeAngles()
- end
- function battlecam.CreateCrosshair()
- for k,v in pairs(ents.GetAll()) do
- if v.battlecam_crosshair then
- SafeRemoveEntity(v)
- end
- end
- local ent = ClientsideModel("models/hunter/misc/cone1x05.mdl")
- ent:SetMaterial("models/shiny")
- local mat = Matrix()
- mat:SetAngles(Angle(-90,0,0))
- mat:Scale(Vector(1,1,2) * 0.25)
- mat:Translate(Vector(0,0,-25))
- ent:EnableMatrix("RenderMultiply", mat)
- ent.RenderOverride = function(ent)
- local c = Vector(GetConVarString("cl_weaponcolor")) * 1.5
- render.SetColorModulation(c.r ^ 10, c.g ^ 10, c.b ^ 10)
- render.SetBlend(0.75)
- ent:DrawModel()
- render.SetBlend(1)
- render.SetColorModulation(1, 1, 1)
- end
- ent.battlecam_crosshair = true
- battlecam.crosshair_ent = ent
- end
- -- common
- local ply = NULL
- local aim_pos = Vector()
- local aim_dir = Vector()
- battlecam.enabled = false
- for k,v in pairs(ents.GetAll()) do
- if v.battlecam_crosshair then
- SafeRemoveEntity(v)
- end
- end
- battlecam.crosshair_ent = NULL
- function battlecam.Enable()
- HOOK("CalcView")
- HOOK("CreateMove")
- HOOK("HUDShouldDraw")
- HOOK("ShouldDrawLocalPlayer")
- HOOK("InputMouseApply")
- battlecam.enabled = true
- ply = LocalPlayer()
- battlecam.CreateCrosshair()
- end
- function battlecam.Disable()
- UNHOOK("CalcView")
- UNHOOK("CreateMove")
- UNHOOK("HUDShouldDraw")
- UNHOOK("ShouldDrawLocalPlayer")
- UNHOOK("InputMouseApply")
- battlecam.enabled = false
- SafeRemoveEntity(battlecam.crosshair_ent)
- end
- function battlecam.IsEnabled()
- return battlecam.enabled
- end
- -- hooks
- do -- view
- battlecam.cam_speed = 10
- local smooth_pos = Vector()
- local smooth_dir = Vector()
- local smooth_roll = 0
- local smooth_fov = 0
- local last_pos = Vector()
- function battlecam.CalcView()
- aim_pos = ply:GetShootPos()
- aim_dir = ply:GetAimVector()
- if not battlecam.crosshair_ent:IsValid() then
- battlecam.CreateCrosshair()
- end
- battlecam.SetupCrosshair(battlecam.crosshair_ent)
- battlecam.CalcEnemySelect()
- local delta = FrameTime()
- local target_pos = aim_pos * 1
- local target_dir = aim_dir * 1
- local target_fov = 60
- target_dir.z = 0
- -- roll
- local target_roll = 0--math.Clamp(-smooth_dir:Angle():Right():Dot(last_pos - smooth_pos) * delta * 40, -30, 30)
- last_pos = smooth_pos
- -- do a more usefull and less cinematic view if we're holding ctrl
- if ply:KeyDown(IN_DUCK) then
- target_dir = aim_dir * 1
- target_pos = target_pos + aim_dir * - 50
- target_fov = 90
- delta = delta * 2
- else
- local ent = battlecam.selected_enemy
- if ent:IsValid() then
- local size = ent:BoundingRadius() * ent:GetModelScale()
- size = size / 2
- target_dir = (ent:EyePos() - target_pos):GetNormalized()
- target_dir.z = target_dir.z / 10
- target_pos = target_pos + target_dir * -(200 + size)
- target_fov = target_fov - 10
- else
- target_dir = battlecam.LimitAngles(target_pos, target_dir, target_fov, smooth_pos)
- target_pos = target_pos + target_dir * -200
- target_fov = 60
- end
- end
- -- move the camera right a little bit
- target_pos = target_pos + target_dir:Angle():Right() * -30
- -- smoothing
- smooth_pos = smooth_pos + ((target_pos - smooth_pos) * delta * battlecam.cam_speed)
- smooth_dir = smooth_dir + ((target_dir - smooth_dir) * delta * battlecam.cam_speed)
- smooth_fov = smooth_fov + ((target_fov - smooth_fov) * delta * battlecam.cam_speed)
- smooth_roll = smooth_roll + ((target_roll - smooth_roll) * delta * battlecam.cam_speed)
- -- trace block
- smooth_pos = battlecam.LimitPos(smooth_pos, smooth_dir, ply)
- -- return
- local params = {}
- params.origin = smooth_pos
- params.angles = smooth_dir:Angle()
- params.angles.r = smooth_roll
- params.fov = smooth_fov
- return params
- end
- end
- function battlecam.SetupCrosshair(ent)
- local enemy = battlecam.selected_enemy
- if enemy:IsValid() then
- ent:SetPos(enemy:EyePos() + enemy:GetUp() * (15 + math.sin(RealTime() * 20)))
- ent:SetAngles(Angle(-90,0,0))
- else
- local trace_res = util.QuickTrace(aim_pos, aim_dir * 2500, {ply, ply:GetVehicle()})
- ent:SetPos(trace_res.HitPos + Vector(0, 0, math.sin(RealTime() * 10)))
- ent:SetAngles(trace_res.HitNormal:Angle())
- end
- end
- do -- selection
- battlecam.selected_enemy = NULL
- local last_use = 0
- function battlecam.CalcEnemySelect()
- if ply:KeyDown(IN_USE) and last_use < RealTime() then
- local end_pos = aim_pos + aim_dir * 2000
- local data = util.TraceHull({
- start = aim_pos,
- endpos = end_pos,
- mins = ply:OBBMins()*2,
- maxs = ply:OBBMaxs()*2,
- filter = ents.FindInSphere(end_pos, 100),
- })
- local ent = data.Entity
- if ent:IsValid() and (ent:IsPlayer() or ent:IsNPC()) and battlecam.selected_enemy ~= ent then
- battlecam.selected_enemy = ent
- else
- battlecam.selected_enemy = NULL
- end
- last_use = RealTime() + 0.25
- end
- end
- end
- function battlecam.InputMouseApply(ucmd)
- local ent = battlecam.selected_enemy
- if ent:IsValid() then
- if ent:IsPlayer() and (not ent:Alive() or not ply:Alive()) then
- battlecam.selected_enemy = NULL
- end
- local head_pos = battlecam.FindHeadPos(ent)
- local aim_ang = (head_pos - ply:EyePos()):Angle()
- aim_ang.p = math.NormalizeAngle(aim_ang.p)
- aim_ang.y = math.NormalizeAngle(aim_ang.y)
- aim_ang.r = 0
- ucmd:SetViewAngles(aim_ang)
- end
- end
- function battlecam.CreateMove(ucmd)
- end
- function battlecam.HUDShouldDraw(hud_type)
- if hud_type == "CHudCrosshair" then
- return false
- end
- end
- function battlecam.ShouldDrawLocalPlayer()
- return true
- end
- CreateClientConVar("battle_cam", 0, true, true)
- cvars.AddChangeCallback("battle_cam", function(_, old, new)
- if new =="1" then
- battlecam.Enable()
- end
- if new == "0" then
- battlecam.Disable()
- end
- end)
- if _G.battlecam and _G.battlecam.IsEnabled() then
- battlecam.Disable()
- battlecam.Enable()
- end
- _G.battlecam =
- {
- Enable = battlecam.Enable,
- Disable = battlecam.Disable,
- IsEnabled = battlecam.IsEnabled,
- }
- do return end
- local ugh = Vector(-9731.6884765625, 12257.26953125, -13243.96875)
- timer.Create("jrpg_enable", 0, 0, function()
- do return end
- local v = LocalPlayer()
- if v:GetPos():Distance(ugh) < 7000 then
- if not battlecam.IsEnabled() then
- battlecam.Enable(true)
- end
- else
- if battlecam.IsEnabled() then
- battlecam.Disable(false)
- end
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement