Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Traitor radar rendering
- local render = render
- local surface = surface
- local string = string
- local player = player
- local math = math
- RADAR = {}
- RADAR.targets = {}
- RADAR.enable = false
- RADAR.duration = 30
- RADAR.endtime = 0
- RADAR.bombs = {}
- RADAR.bombs_count = 0
- RADAR.repeating = true
- RADAR.samples = {}
- RADAR.samples_count = 0
- RADAR.called_corpses = {}
- function RADAR:EndScan()
- self.enable = false
- self.endtime = CurTime()
- end
- function RADAR:Clear()
- self:EndScan()
- self.bombs = {}
- self.samples = {}
- self.bombs_count = 0
- self.samples_count = 0
- end
- function RADAR:Timeout()
- self:EndScan()
- if self.repeating and LocalPlayer() and (LocalPlayer():IsActiveTraitor() or LocalPlayer():IsActiveDetective()) then
- RunConsoleCommand("ttt_radar_scan")
- end
- end
- -- cache stuff we'll be drawing
- function RADAR.CacheEnts()
- -- also do some corpse cleanup here
- for k, corpse in pairs(RADAR.called_corpses) do
- if (corpse.called + 45) < CurTime() then
- RADAR.called_corpses[k] = nil -- will make # inaccurate, no big deal
- end
- end
- if RADAR.bombs_count == 0 then return end
- -- Update bomb positions for those we know about
- for idx, b in pairs(RADAR.bombs) do
- local ent = Entity(idx)
- if IsValid(ent) then
- b.pos = ent:GetPos()
- end
- end
- end
- local function DrawTarget(tgt, size, offset, no_shrink)
- local scrpos = tgt.pos:ToScreen() -- sweet
- local sz = (IsOffScreen(scrpos) and (not no_shrink)) and size/2 or size
- scrpos.x = math.Clamp(scrpos.x, sz, ScrW() - sz)
- scrpos.y = math.Clamp(scrpos.y, sz, ScrH() - sz)
- surface.DrawTexturedRect(scrpos.x - sz, scrpos.y - sz, sz * 2, sz * 2)
- -- Drawing full size?
- if sz == size then
- local text = math.ceil(LocalPlayer():GetPos():Distance(tgt.pos))
- local w, h = surface.GetTextSize(text)
- -- Show range to target
- surface.SetTextPos(scrpos.x - w/2, scrpos.y + (offset * sz) - h/2)
- surface.DrawText(text)
- if tgt.t then
- -- Show time
- text = string.FormattedTime(tgt.t - CurTime(), "%02i:%02i")
- w, h = surface.GetTextSize(text)
- surface.SetTextPos(scrpos.x - w / 2, scrpos.y + sz / 2)
- surface.DrawText(text)
- elseif tgt.nick then
- -- Show nickname
- text = tgt.nick
- w, h = surface.GetTextSize(text)
- surface.SetTextPos(scrpos.x - w / 2, scrpos.y + sz / 2)
- surface.DrawText(text)
- end
- end
- end
- local indicator = surface.GetTextureID("effects/select_ring")
- local c4warn = surface.GetTextureID("VGUI/ttt/icon_c4warn")
- local sample_scan = surface.GetTextureID("VGUI/ttt/sample_scan")
- local det_beacon = surface.GetTextureID("VGUI/ttt/det_beacon")
- local GetPTranslation = LANG.GetParamTranslation
- local FormatTime = string.FormattedTime
- local near_cursor_dist = 180
- function RADAR:Draw(client)
- if not client then return end
- surface.SetFont("HudSelectionText")
- -- C4 warnings
- if self.bombs_count != 0 and client:IsActiveTraitor() then
- surface.SetTexture(c4warn)
- surface.SetTextColor(200, 55, 55, 220)
- surface.SetDrawColor(255, 255, 255, 200)
- for k, bomb in pairs(self.bombs) do
- DrawTarget(bomb, 24, 0, true)
- end
- end
- -- Corpse calls
- if client:IsActiveDetective() and #self.called_corpses then
- surface.SetTexture(det_beacon)
- surface.SetTextColor(255, 255, 255, 240)
- surface.SetDrawColor(255, 255, 255, 230)
- for k, corpse in pairs(self.called_corpses) do
- DrawTarget(corpse, 16, 0.5)
- end
- end
- -- Samples
- if self.samples_count != 0 then
- surface.SetTexture(sample_scan)
- surface.SetTextColor(200, 50, 50, 255)
- surface.SetDrawColor(255, 255, 255, 240)
- for k, sample in pairs(self.samples) do
- DrawTarget(sample, 16, 0.5, true)
- end
- end
- -- Player radar
- if (not self.enable) or (not client:IsActiveSpecial()) then return end
- surface.SetTexture(indicator)
- local remaining = math.max(0, RADAR.endtime - CurTime())
- local alpha_base = 50 + 180 * (remaining / RADAR.duration)
- local mpos = Vector(ScrW() / 2, ScrH() / 2, 0)
- local role, alpha, scrpos, md
- for k, tgt in pairs(RADAR.targets) do
- alpha = alpha_base
- scrpos = tgt.pos:ToScreen()
- md = mpos:Distance(Vector(scrpos.x, scrpos.y, 0))
- if md < near_cursor_dist then
- alpha = math.Clamp(alpha * (md / near_cursor_dist), 40, 230)
- end
- role = tgt.role or ROLE_INNOCENT
- if role == ROLE_TRAITOR then
- surface.SetDrawColor(255, 0, 0, alpha)
- surface.SetTextColor(255, 0, 0, alpha)
- elseif role == ROLE_DETECTIVE then
- surface.SetDrawColor(0, 0, 255, alpha)
- surface.SetTextColor(0, 0, 255, alpha)
- elseif role == -1 then -- decoys
- surface.SetDrawColor(150, 150, 150, alpha)
- surface.SetTextColor(150, 150, 150, alpha)
- else
- surface.SetDrawColor(0, 255, 0, alpha)
- surface.SetTextColor(0, 255, 0, alpha)
- end
- DrawTarget(tgt, 24, 0)
- end
- -- Time until next scan
- surface.SetFont("TabLarge")
- surface.SetTextColor(255, 0, 0, 230)
- local text = GetPTranslation("radar_hud", {time = FormatTime(remaining, "%02i:%02i")})
- local w, h = surface.GetTextSize(text)
- surface.SetTextPos(36, ScrH() - 140 - h)
- surface.DrawText(text)
- end
- local function ReceiveC4Warn(um)
- local idx = um:ReadShort()
- local armed = um:ReadBool()
- if armed then
- local pos = um:ReadVector()
- local etime = um:ReadFloat()
- RADAR.bombs[idx] = {pos=pos, t=etime}
- else
- RADAR.bombs[idx] = nil
- end
- RADAR.bombs_count = table.Count(RADAR.bombs)
- end
- usermessage.Hook("c4_warn", ReceiveC4Warn)
- local function ReceiveCorpseCall(um)
- local pos = um:ReadVector()
- table.insert(RADAR.called_corpses, {pos = pos, called = CurTime()})
- end
- usermessage.Hook("corpse_call", ReceiveCorpseCall)
- local function ReceiveRadarScan(um)
- local num_targets = um:ReadChar()
- RADAR.targets = {}
- for i=1, num_targets do
- local r = um:ReadChar()
- local pos = Vector()
- pos.x = um:ReadShort()
- pos.y = um:ReadShort()
- pos.z = um:ReadShort()
- table.insert(RADAR.targets, {role=r, pos=pos})
- end
- RADAR.enable = true
- RADAR.endtime = CurTime() + RADAR.duration
- timer.Create("radartimeout", RADAR.duration + 1, 1, RADAR.Timeout, RADAR)
- end
- usermessage.Hook("radar", ReceiveRadarScan)
- local GetTranslation = LANG.GetTranslation
- function RADAR.CreateMenu(parent, frame)
- local w, h = parent:GetSize()
- local dform = vgui.Create("DForm", parent)
- dform:SetName(GetTranslation("radar_menutitle"))
- dform:StretchToParent(0,0,0,0)
- dform:SetAutoSize(false)
- local owned = LocalPlayer():HasEquipmentItem(EQUIP_RADAR)
- if not owned then
- dform:Help(GetTranslation("radar_not_owned"))
- return dform
- end
- local bw, bh = 100, 25
- local dscan = vgui.Create("DButton", dform)
- dscan:SetSize(bw, bh)
- dscan:SetText(GetTranslation("radar_scan"))
- dscan.DoClick = function(s)
- s:SetDisabled(true)
- RunConsoleCommand("ttt_radar_scan")
- frame:Close()
- end
- dform:AddItem(dscan)
- local dlabel = vgui.Create("DLabel", dform)
- dlabel:SetText(GetPTranslation("radar_help", {num = RADAR.duration}))
- dlabel:SetWrap(true)
- dlabel:SetTall(50)
- dform:AddItem(dlabel)
- local dcheck = vgui.Create("DCheckBoxLabel", dform)
- dcheck:SetText(GetTranslation("radar_auto"))
- dcheck:SetIndent(5)
- dcheck:SetValue(RADAR.repeating)
- dcheck.OnChange = function(s, val)
- RADAR.repeating = val
- end
- dform:AddItem(dcheck)
- dform.Think = function(s)
- if RADAR.enable or not owned then
- dscan:SetDisabled(true)
- else
- dscan:SetDisabled(false)
- end
- end
- dform:SetVisible(true)
- return dform
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement