// ViewAll by RabidToaster. if SERVER then return end local VA = {} do local hooks = {} local created = {} local function CallHook(self, name, args) if !hooks[name] then return end for funcName, _ in pairs(hooks[name]) do local func = self[funcName] if func then local ok, err = pcall(func, self, unpack(args or {})) if !ok then ErrorNoHalt(err .. "\n") elseif err then return err end end end end local function AddHook(self, name, funcName) // If we haven't got a hook for this yet, make one with a random name and store it. // This is so anti-cheats can't detect by hook name, and so we can remove them later. if !created[name] then local random = "" for i = 1, math.random(4, 10) do local c = math.random(65, 116) if c >= 91 && c <= 96 then c = c + 6 end random = random .. string.char(c) end hook.Add(name, random, function(...) CallHook(self, name, {...}) end) created[name] = random end hooks[name] = hooks[name] or {} hooks[name][funcName] = true end // Don't let other scripts remove our hooks. local oldRemove = hook.Remove function hook.Remove(name, unique) if created[name] == unique then return end oldRemove(name, unique) end // Removes all hooks, useful if reloading the script. local function RemoveHooks() for hookName, unique in pairs(created) do oldRemove(hookName, unique) end end // Add copies the script can access. VA.AddHook = AddHook VA.CallHook = CallHook VA.RemoveHooks = RemoveHooks end concommand.Add("va_reload", function() VA:CallHook("Shutdown") print("Removing hooks...") VA:RemoveHooks() local info = debug.getinfo(1, "S") if info && info.short_src then print("Reloading (" .. info.short_src .. ")...") include(info.short_src) else print("Cannot find ViewAll file, reload manually.") end end) print("ViewAll loaded.") do local settings = {} local function SettingVar(self, name) return (self.SettingPrefix or "") .. string.lower(name) end local function RandomName() local random = "" for i = 1, math.random(4, 10) do local c = math.random(65, 116) if c >= 91 && c <= 96 then c = c + 6 end random = random .. string.char(c) end return random end local function SetSetting(name, _, new) if !settings[name] then return end local info = settings[name] if info.Type == "number" then new = tonumber(new) elseif info.Type == "boolean" then new = (tonumber(new) or 0) > 0 end info.Value = new end local function CreateSetting(self, name, desc, default, misc) local cvar = SettingVar(self, name) local info = {Name = name, Desc = desc, CVar = cvar, Type = type(default), Value = default} for k, v in pairs(misc or {}) do if !info[k] then info[k] = v end end // Convert default from boolean to number. if type(default) == "boolean" then default = default and 1 or 0 end if !settings[cvar] then local tab = cvars.GetConVarCallbacks(cvar) if !tab then cvars.AddChangeCallback(cvar, function() end) tab = cvars.GetConVarCallbacks(cvar) end while true do local name = RandomName() if !tab[name] then tab[name] = SetSetting info.Callback = name break end end end settings[cvar] = info settings[#settings + 1] = info // Create the convar. CreateClientConVar(cvar, default, (info.Save != false), false) SetSetting(cvar, _, GetConVarString(cvar)) end local function GetSetting(self, name) local cvar = SettingVar(self, name) if !settings[cvar] then return end return settings[cvar].Value end local function Shutdown() print("Removing settings callbacks...") for _, info in ipairs(settings) do if info.CVar && info.Callback then local tab = cvars.GetConVarCallbacks(info.CVar) if tab then tab[info.Callback] = nil end end end end local function SettingsList() return table.Copy(settings) end local function BuildMenu(self, panel) for _, info in ipairs(settings) do if info.Show != false then if info.MultiChoice then local m = panel:MultiChoice(info.Desc or info.CVar, info.CVar) for k, v in pairs(info.MultiChoice) do m:AddChoice(k, v) end elseif info.Type == "number" then panel:NumSlider(info.Desc or info.CVar, info.CVar, info.Min or -1, info.Max or -1, info.Places or 0) elseif info.Type == "boolean" then panel:CheckBox(info.Desc or info.CVar, info.CVar) elseif info.Type == "string" then panel:TextEntry(info.Desc or info.CVar, info.CVar) end end end end VA.SettingPrefix = "va_" VA.CreateSetting = CreateSetting VA.Setting = GetSetting VA.SettingsList = SettingsList VA.BuildMenu = BuildMenu VA.SettingsShutdown = Shutdown VA:AddHook("Shutdown", "SettingsShutdown") end VA:CreateSetting("updatedelay", "Target update delay", 1, {Min = 0, Max = 5}) VA:CreateSetting("enabled", "Enabled", true) VA:CreateSetting("fullbright", "Fullbright", true) VA:CreateSetting("nodraw", "NoDraw entities to increase performance", false) VA:CreateSetting("showfriendlies", "Draw members of your own team", true) VA:CreateSetting("heldweapons", "Draw held weapons", true) VA:CreateSetting("weapons", "Draw dropped weapons", true) VA:CreateSetting("items", "Draw items", true) VA:CreateSetting("ragdolls", "Draw ragdolls", true) VA:CreateSetting("dangerous", "Draw dangerous items", true) // ################################################## // Targeting // ################################################## VA.DeathSequences = { ["models/barnacle.mdl"] = {4, 15}; ["models/antlion_guard.mdl"] = {44}; ["models/hunter.mdl"] = {124, 125, 126, 127, 128}; } VA.DangerousItems = { ["npc_grenade_frag"] = true; // Normal grenades. ["npc_satchel"] = true; // SLAM mines. ["npc_tripmine"] = true; // SLAM tripwires. ["rpg_missile"] = true; // RPG rockets. ["crossbow_bolt"] = true; // Crossbow bolts... ["grenade_ar2"] = true; // SMG grenades. } VA.EnemyNPCs = { ["npc_headcrab"] = true; ["npc_antlionguard"] = true; ["npc_zombie"] = true; ["npc_zombine"] = true; ["npc_antlion_worker"] = true; ["npc_metropolice"] = true; ["npc_fastzombie_torso"] = true; ["npc_combine_s"] = true; ["npc_zombie_torso"] = true; ["npc_rollermine"] = true; ["npc_turret_floor"] = true; ["npc_barnacle"] = true; ["npc_poisonzombie"] = true; ["npc_manhack"] = true; ["npc_antlion"] = true; ["npc_headcrab_black"] = true; ["npc_headcrab_poison"] = true; ["npc_fastzombie"] = true; ["npc_combine_s"] = true; ["npc_hunter"] = true; ["npc_headcrab_fast"] = true; ["npc_combine_s"] = true; ["npc_cscanner"] = true; ["npc_strider"] = true; } function VA:TargetInfo(ent) if !ValidEntity(ent) then return end local ply = LocalPlayer() if !ValidEntity(ply) then return end local class = ent:GetClass() if ent:IsPlayer() then if ent:Alive() == false then return end if ply:Team() == ent:Team() && !self:Setting("showfriendlies") then return end local col = team.GetColor(ent:Team()) local name = team.GetName(ent:Team()) if name == "Spectator" then col.a = 64 end return true, col end if ent:IsNPC() then if ent:GetMoveType() == MOVETYPE_NONE then return end if ent.IsDead then return end local model = string.lower(ent:GetModel() or "") if self.DeathSequences[model] then if table.HasValue(self.DeathSequences[model], ent:GetSequence()) then return end end if self.EnemyNPCs[class] then return true, Color(255, 0, 0) else return true, Color(0, 255, 0) end end if ent:IsWeapon() then if ValidEntity(ent:GetOwner()) then if self:Setting("heldweapons") then return self:TargetInfo(ent:GetOwner()), nil end else return self:Setting("weapons"), nil, true end return true end if self:Setting("items") then if string.find(class, "item") then return true end end if self:Setting("ragdolls") then if class == "prop_ragdoll" || class == "class C_ClientRagdoll" then return true, Color(255, 255, 0) end end if self:Setting("dangerous") then if self.DangerousItems[class] then return true, Color(255, 0, 0) end end end function VA:TargetCreated(ent) if !ValidEntity(ent) then return end local pass, colour, prop = self:TargetInfo(ent) if pass == true then self:AddTarget(ent, colour, prop) elseif self:IsNoDraw(ent:GetOwner()) then self:SetNoDraw(ent, false) end if ent:GetClass() == "raggib" then local owner = ent:GetOwner() if ValidEntity(owner) && owner:GetModel() != "models/zombie/classic_torso.mdl" then // They're a torso, not dead. owner.IsDead = true end end end VA:AddHook("OnEntityCreated", "TargetCreated") VA.Targets = {} VA.LastFindTargets = 0 local targets function VA:FindTargets() if !self:Enabled() then return end if CurTime() < self.LastFindTargets + self:Setting("updatedelay") then return end self.LastFindTargets = CurTime() targets = {} for _, ent in pairs(ents.GetAll()) do local pass, colour, prop = self:TargetInfo(ent) if pass == true then targets[ent] = {colour or Color(255, 255, 255), prop == true} end end for targ, _ in pairs(self.Targets) do if ValidEntity(targ) && !targets[targ] then self:RemoveTarget(ent) end end self.Targets = targets end VA:AddHook("Think", "FindTargets") function VA:AddTarget(ent, colour, prop) self.Targets[ent] = {colour or Color(255, 255, 255), prop == true} end function VA:RemoveTarget(ent) if !ent then return end if self:UseNoDraw() then self:SetNoDraw(ent, false) end self.Targets[ent] = nil end function VA:GetTargets() return self.Targets end // ################################################## // Materials // ################################################## VA.Materials = {} VA.MaterialNames = {} VA:CreateSetting("material", "Material", "wireframe", {MultiChoice = VA.MaterialNames}) function VA:GetMaterial() local name = string.lower(self:Setting("material")) return self.Materials[name] end function VA:AddMaterial(name, base, shader) if !shader then shader = "VertexLitGeneric" end name = string.lower(name) local mat = CreateMaterial("viewall_" .. name, shader, { ["$basetexture"] = base, ["$ignorez"] = 1 }) self.Materials[name] = mat self.MaterialNames[name] = name end function VA:GetMaterialList() return self.Materials end VA:AddMaterial("solid", "models/debug/debugwhite") VA:AddMaterial("wireframe", "models/wireframe", "Wireframe") // ################################################## // Rendering // ################################################## local targets, colour, Draw function VA:RenderTargets() if !self:Enabled() then return end targets = self:GetTargets() //if #targets == 0 then return end local mat = self:GetMaterial(matName) // NoDraw to save drawing, and weed out invalid entities. local pass for ent, info in pairs(targets) do pass = self:TargetInfo(ent) if pass then if self:UseNoDraw() then self:SetNoDraw(ent, true) end else self:RemoveTarget(ent) end end local fullbright = self:Setting("fullbright") if fullbright then render.SuppressEngineLighting(true) end function Draw(ent, r, g, b, a, prop) render.SetColorModulation(r / 255, g / 255, b / 255) render.SetBlend(a / 255) if prop && ValidEntity(self.Prop) then self.Prop:SetModel("models/error.mdl") self.Prop:SetModel(ent:GetModel()) self.Prop:SetPos(ent:GetPos()) self.Prop:SetAngles(ent:GetAngles()) self.Prop:DrawModel() else ent:DrawModel() end end cam.Start3D(EyePos(), EyeAngles()) pcall(function() if mat != nil then SetMaterialOverride(mat) for ent, info in pairs(targets) do Draw(ent, info[1]["r"], info[1]["g"], info[1]["b"], info[1]["a"], info[2]) end SetMaterialOverride(nil) end local r, g, b for ent, info in pairs(targets) do r, g, b = ent:GetColor() Draw(ent, r, g, b, info[1]["a"], info[2]) end end) cam.End3D() render.SetBlend(1) if fullbright then render.SuppressEngineLighting(false) end end VA:AddHook("RenderScreenspaceEffects", "RenderTargets") function VA:CreateProp() if !ValidEntity(self.Prop) then self.Prop = ents.Create("prop_physics") self.Prop:SetNoDraw(true) self.Prop:Spawn() end end VA:AddHook("Think", "CreateProp") function VA:Enabled() return self:Setting("enabled") end VA.NoDraw = {} function VA:SetNoDraw(ent, bool) if !ValidEntity(ent) then return end if bool then ent:SetRenderMode(RENDERMODE_NONE) self.NoDraw[ent] = true else ent:SetRenderMode(RENDERMODE_NORMAL) self.NoDraw[ent] = nil end end function VA:IsNoDraw(ent) return self.NoDraw[ent] == true end function VA:UseNoDraw() return self:Setting("nodraw") end function VA:OpenMenu() local w, h = ScrW() / 3, ScrH() / 2 local menu = vgui.Create("DFrame") menu:SetTitle("VA") menu:SetSize(w, h) menu:Center() menu:MakePopup() local scroll = vgui.Create("DPanelList", menu) scroll:SetPos(5, 25) scroll:SetSize(w - 10, h - 30) scroll:EnableVerticalScrollbar() local form = vgui.Create("DForm", menu) form:SetName("") form.Paint = function() end scroll:AddItem(form) self:BuildMenu(form) if VA.Menu then VA.Menu:Remove() end VA.Menu = menu end concommand.Add("va_menu", function() VA:OpenMenu() end) function VA:RegisterMenu() spawnmenu.AddToolMenuOption("Options", "Hacks", "VA", "VA", "", "", function(p) self:BuildMenu(p) end) end VA:AddHook("PopulateToolMenu", "RegisterMenu")