Untitled diff

Created Diff never expires
43 removals
Lines
Total
Removed
Words
Total
Removed
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
354 lines
21 additions
Lines
Total
Added
Words
Total
Added
To continue using this feature, upgrade to
Diffchecker logo
Diffchecker Pro
330 lines

---- VGUI panel version of the scoreboard, based on TEAM GARRY's sandbox mode
---- VGUI panel version of the scoreboard, based on TEAM GARRY's sandbox mode
---- scoreboard.
---- scoreboard.


local surface = surface
local surface = surface
local draw = draw
local draw = draw
local math = math
local math = math
local string = string
local string = string
local vgui = vgui
local vgui = vgui


local GetTranslation = LANG.GetTranslation
local GetTranslation = LANG.GetTranslation
local GetPTranslation = LANG.GetParamTranslation
local GetPTranslation = LANG.GetParamTranslation


include("sb_team.lua")
include("sb_team.lua")


surface.CreateFont("cool_small", {font = "coolvetica",
surface.CreateFont("cool_small", {font = "coolvetica",
size = 20,
size = 20,
weight = 400})
weight = 400})
surface.CreateFont("cool_large", {font = "coolvetica",
surface.CreateFont("cool_large", {font = "coolvetica",
size = 24,
size = 24,
weight = 400})
weight = 400})
surface.CreateFont("treb_small", {font = "Trebuchet18",
surface.CreateFont("treb_small", {font = "Trebuchet18",
size = 14,
size = 14,
weight = 700})
weight = 700})


local logo = surface.GetTextureID("vgui/ttt/score_logo")
local logo = surface.GetTextureID("VGUI/ttt/score_logo")


local PANEL = {}
local PANEL = {}


local max = math.max
local max = math.max
local floor = math.floor
local floor = math.floor
local function UntilMapChange()
local function UntilMapChange()
local rounds_left = max(0, GetGlobalInt("ttt_rounds_left", 6))
local rounds_left = max(0, GetGlobalInt("ttt_rounds_left", 6))
local time_left = floor(max(0, ((GetGlobalInt("ttt_time_limit_minutes") or 60) * 60) - CurTime()))
local time_left = floor(max(0, ((GetGlobalInt("ttt_time_limit_minutes") or 60) * 60) - CurTime()))


local h = floor(time_left / 3600)
local h = floor(time_left / 3600)
time_left = time_left - floor(h * 3600)
time_left = time_left - floor(h * 3600)
local m = floor(time_left / 60)
local m = floor(time_left / 60)
time_left = time_left - floor(m * 60)
time_left = time_left - floor(m * 60)
local s = floor(time_left)
local s = floor(time_left)


return rounds_left, string.format("%02i:%02i:%02i", h, m, s)
return rounds_left, string.format("%02i:%02i:%02i", h, m, s)
end
end




GROUP_TERROR = 1
GROUP_TERROR = 1
GROUP_NOTFOUND = 2
GROUP_NOTFOUND = 2
GROUP_FOUND = 3
GROUP_FOUND = 3
GROUP_SPEC = 4
GROUP_SPEC = 4


GROUP_COUNT = 4
GROUP_COUNT = 4


function AddScoreGroup(name) -- Utility function to register a score group
if _G["GROUP_"..name] then error("Group of name '"..name.."' already exists!") return end
GROUP_COUNT = GROUP_COUNT + 1
_G["GROUP_"..name] = GROUP_COUNT
end

function ScoreGroup(p)
function ScoreGroup(p)
if not IsValid(p) then return -1 end -- will not match any group panel
if not IsValid(p) then return -1 end -- will not match any group panel

local group = hook.Call( "TTTScoreGroup", nil, p )

if group then -- If that hook gave us a group, use it
return group
end

if DetectiveMode() then
if DetectiveMode() then
if p:IsSpec() and (not p:Alive()) then
if (p:IsSpec() and (not p:Alive())) or p:GetNWBool("is_pretending") then
if p:GetNWBool("body_found", false) then
if p:GetNWBool("body_found", false) then
return GROUP_FOUND
return GROUP_FOUND
else
else
local client = LocalPlayer()
local client = LocalPlayer()
-- To terrorists, missing players show as alive
-- To terrorists, missing players show as alive
if client:IsSpec() or
if client:IsSpec() or
client:IsActiveTraitor() or
client:IsActiveTraitor() or
((GAMEMODE.round_state != ROUND_ACTIVE) and client:IsTerror()) then
((GAMEMODE.round_state != ROUND_ACTIVE) and client:IsTerror()) then
return GROUP_NOTFOUND
return GROUP_NOTFOUND
else
else
return GROUP_TERROR
return GROUP_TERROR
end
end
end
end
end
end
end
end


return p:IsTerror() and GROUP_TERROR or GROUP_SPEC
return p:IsTerror() and GROUP_TERROR or GROUP_SPEC
end
end


function PANEL:Init()
function PANEL:Init()


self.hostdesc = vgui.Create("DLabel", self)
self.hostdesc = vgui.Create("DLabel", self)
self.hostdesc:SetText(GetTranslation("sb_playing"))
self.hostdesc:SetText(GetTranslation("sb_playing"))
self.hostdesc:SetContentAlignment(9)
self.hostdesc:SetContentAlignment(9)


self.hostname = vgui.Create( "DLabel", self )
self.hostname = vgui.Create( "DLabel", self )
self.hostname:SetText( GetHostName() )
self.hostname:SetText( GetHostName() )
self.hostname:SetContentAlignment(6)
self.hostname:SetContentAlignment(6)


self.mapchange = vgui.Create("DLabel", self)
self.mapchange = vgui.Create("DLabel", self)
self.mapchange:SetText("Map changes in 00 rounds or in 00:00:00")
self.mapchange:SetText("Map changes in 00 rounds or in 00:00:00")
self.mapchange:SetContentAlignment(9)
self.mapchange:SetContentAlignment(9)


self.mapchange.Think = function (sf)
self.mapchange.Think = function (sf)
local r, t = UntilMapChange()
local r, t = UntilMapChange()


sf:SetText(GetPTranslation("sb_mapchange",
sf:SetText(GetPTranslation("sb_mapchange",
{num = r, time = t}))
{num = r, time = t}))
sf:SizeToContents()
sf:SizeToContents()
end
end




self.ply_frame = vgui.Create( "TTTPlayerFrame", self )
self.ply_frame = vgui.Create( "TTTPlayerFrame", self )


self.ply_groups = {}
self.ply_groups = {}


local t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
local t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t:SetGroupInfo(GetTranslation("terrorists"), Color(0,200,0,100), GROUP_TERROR)
t:SetGroupInfo(GetTranslation("terrorists"), Color(0,200,0,100), GROUP_TERROR)
self.ply_groups[GROUP_TERROR] = t
self.ply_groups[GROUP_TERROR] = t


t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t:SetGroupInfo(GetTranslation("spectators"), Color(200, 200, 0, 100), GROUP_SPEC)
t:SetGroupInfo(GetTranslation("spectators"), Color(200, 200, 0, 100), GROUP_SPEC)
self.ply_groups[GROUP_SPEC] = t
self.ply_groups[GROUP_SPEC] = t


if DetectiveMode() then
if DetectiveMode() then
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t:SetGroupInfo(GetTranslation("sb_mia"), Color(130, 190, 130, 100), GROUP_NOTFOUND)
t:SetGroupInfo(GetTranslation("sb_mia"), Color(130, 190, 130, 100), GROUP_NOTFOUND)
self.ply_groups[GROUP_NOTFOUND] = t
self.ply_groups[GROUP_NOTFOUND] = t


t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
t:SetGroupInfo(GetTranslation("sb_confirmed"), Color(130, 170, 10, 100), GROUP_FOUND)
t:SetGroupInfo(GetTranslation("sb_confirmed"), Color(130, 170, 10, 100), GROUP_FOUND)
self.ply_groups[GROUP_FOUND] = t
self.ply_groups[GROUP_FOUND] = t
end
end


hook.Call( "TTTScoreGroups", nil, self.ply_frame:GetCanvas(), self.ply_groups )

-- the various score column headers
-- the various score column headers
self.cols = {}
self.cols = {}
self:AddColumn( GetTranslation("sb_ping") )
self.cols[1] = vgui.Create( "DLabel", self )
self:AddColumn( GetTranslation("sb_deaths") )
self.cols[1]:SetText( GetTranslation("sb_ping") )
self:AddColumn( GetTranslation("sb_score") )

self.cols[2] = vgui.Create( "DLabel", self )
self.cols[2]:SetText( GetTranslation("sb_deaths") )

self.cols[3] = vgui.Create( "DLabel", self )
self.cols[3]:SetText( GetTranslation("sb_score") )


if KARMA.IsEnabled() then
if KARMA.IsEnabled() then
self:AddColumn( GetTranslation("sb_karma") )
self.cols[4] = vgui.Create("DLabel", self)
self.cols[4]:SetText(GetTranslation("sb_karma"))
end
end


-- Let hooks add their column headers (via AddColumn())
hook.Call( "TTTScoreboardColumns", nil, self )

self:UpdateScoreboard()
self:UpdateScoreboard()
self:StartUpdateTimer()
self:StartUpdateTimer()
end
end


-- For headings only the label parameter is relevant, func is included for
-- parity with sb_row
function PANEL:AddColumn( label, func, width )
local lbl = vgui.Create( "DLabel", self )
lbl:SetText( label )
lbl.IsHeading = true
lbl.Width = width or 50 -- Retain compatibility with existing code

table.insert( self.cols, lbl )
return lbl
end

function PANEL:StartUpdateTimer()
function PANEL:StartUpdateTimer()
if not timer.Exists("TTTScoreboardUpdater") then
if not timer.Exists("TTTScoreboardUpdater") then
timer.Create( "TTTScoreboardUpdater", 0.3, 0,
timer.Create( "TTTScoreboardUpdater", 0.3, 0,
function()
function()
local pnl = GAMEMODE:GetScoreboardPanel()
local pnl = GAMEMODE:GetScoreboardPanel()
if IsValid(pnl) then
if IsValid(pnl) then
pnl:UpdateScoreboard()
pnl:UpdateScoreboard()
end
end
end)
end)
end
end
end
end


local colors = {
local colors = {
bg = Color(30,30,30, 235),
bg = Color(30,30,30, 235),
bar = Color(220,180,0,255)
bar = Color(220,180,0,255)
};
};


local y_logo_off = 72
local y_logo_off = 72


function PANEL:Paint()
function PANEL:Paint()
-- Logo sticks out, so always offset bg
-- Logo sticks out, so always offset bg
draw.RoundedBox( 8, 0, y_logo_off, self:GetWide(), self:GetTall() - y_logo_off, colors.bg)
draw.RoundedBox( 8, 0, y_logo_off, self:GetWide(), self:GetTall() - y_logo_off, colors.bg)


-- Server name is outlined by orange/gold area
-- Server name is outlined by orange/gold area
draw.RoundedBox( 8, 0, y_logo_off + 25, self:GetWide(), 32, colors.bar)
draw.RoundedBox( 8, 0, y_logo_off + 25, self:GetWide(), 32, colors.bar)


-- TTT Logo
-- TTT Logo
surface.SetTexture( logo )
surface.SetTexture( logo )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.SetDrawColor( 255, 255, 255, 255 )
surface.DrawTexturedRect( 5, 0, 256, 256 )
surface.DrawTexturedRect( 5, 0, 256, 256 )


end
end


function PANEL:PerformLayout()
function PANEL:PerformLayout()
-- position groups and find their total size
-- position groups and find their total size
local gy = 0
local gy = 0
-- can't just use pairs (undefined ordering) or ipairs (group 2 and 3 might not exist)
-- can't just use pairs (undefined ordering) or ipairs (group 2 and 3 might not exist)
for i=1, GROUP_COUNT do
for i=1, GROUP_COUNT do
local group = self.ply_groups[i]
local group = self.ply_groups[i]
if IsValid(group) then
if ValidPanel(group) then
if group:HasRows() then
if group:HasRows() then
group:SetVisible(true)
group:SetVisible(true)
group:SetPos(0, gy)
group:SetPos(0, gy)
group:SetSize(self.ply_frame:GetWide(), group:GetTall())
group:SetSize(self.ply_frame:GetWide(), group:GetTall())
group:InvalidateLayout()
group:InvalidateLayout()
gy = gy + group:GetTall() + 5
gy = gy + group:GetTall() + 5
else
else
group:SetVisible(false)
group:SetVisible(false)
end
end
end
end
end
end


self.ply_frame:GetCanvas():SetSize(self.ply_frame:GetCanvas():GetWide(), gy)
self.ply_frame:GetCanvas():SetSize(self.ply_frame:GetCanvas():GetWide(), gy)


local h = y_logo_off + 110 + self.ply_frame:GetCanvas():GetTall()
local h = y_logo_off + 110 + self.ply_frame:GetCanvas():GetTall()


-- if we will have to clamp our height, enable the mouse so player can scroll
-- if we will have to clamp our height, enable the mouse so player can scroll
local scrolling = h > ScrH() * 0.95
local scrolling = h > ScrH() * 0.95
-- gui.EnableScreenClicker(scrolling)
-- gui.EnableScreenClicker(scrolling)
self.ply_frame:SetScroll(scrolling)
self.ply_frame:SetScroll(scrolling)


h = math.Clamp(h, 110 + y_logo_off, ScrH() * 0.95)
h = math.Clamp(h, 110 + y_logo_off, ScrH() * 0.95)


local w = math.max(ScrW() * 0.6, 640)
local w = math.max(ScrW() * 0.6, 640)


self:SetSize(w, h)
self:SetSize(w, h)
self:SetPos( (ScrW() - w) / 2, math.min(72, (ScrH() - h) / 4))
self:SetPos( (ScrW() - w) / 2, math.min(72, (ScrH() - h) / 4))


self.ply_frame:SetPos(8, y_logo_off + 109)
self.ply_frame:SetPos(8, y_logo_off + 109)
self.ply_frame:SetSize(self:GetWide() - 16, self:GetTall() - 109 - y_logo_off - 5)
self.ply_frame:SetSize(self:GetWide() - 16, self:GetTall() - 109 - y_logo_off - 5)


-- server stuff
-- server stuff
self.hostdesc:SizeToContents()
self.hostdesc:SizeToContents()
self.hostdesc:SetPos(w - self.hostdesc:GetWide() - 8, y_logo_off + 5)
self.hostdesc:SetPos(w - self.hostdesc:GetWide() - 8, y_logo_off + 5)


local hw = w - 180 - 8
local hw = w - 180 - 8
self.hostname:SetSize(hw, 32)
self.hostname:SetSize(hw, 32)
self.hostname:SetPos(w - self.hostname:GetWide() - 8, y_logo_off + 27)
self.hostname:SetPos(w - self.hostname:GetWide() - 8, y_logo_off + 27)


surface.SetFont("cool_large")
surface.SetFont("cool_large")
local hname = self.hostname:GetValue()
local hname = self.hostname:GetValue()
local tw, _ = surface.GetTextSize(hname)
local tw, _ = surface.GetTextSize(hname)
while tw > hw do
while tw > hw do
hname = string.sub(hname, 1, -6) .. "..."
hname = string.sub(hname, 1, -6) .. "..."
tw, th = surface.GetTextSize(hname)
tw, th = surface.GetTextSize(hname)
end
end


self.hostname:SetText(hname)
self.hostname:SetText(hname)


self.mapchange:SizeToContents()
self.mapchange:SizeToContents()
self.mapchange:SetPos(w - self.mapchange:GetWide() - 8, y_logo_off + 60)
self.mapchange:SetPos(w - self.mapchange:GetWide() - 8, y_logo_off + 60)


-- score columns
-- score columns
local cy = y_logo_off + 90
local cy = y_logo_off + 90
local cx = w - 8 -(scrolling and 16 or 0)
for k,v in ipairs(self.cols) do
for k,v in ipairs(self.cols) do
v:SizeToContents()
v:SizeToContents()
cx = cx - v.Width
v:SetPos( w - (50*k) - v:GetWide()/2 - 8, cy)
v:SetPos(cx - v:GetWide()/2, cy)
end
end
end
end


function PANEL:ApplySchemeSettings()
function PANEL:ApplySchemeSettings()
self.hostdesc:SetFont("cool_small")
self.hostdesc:SetFont("cool_small")
self.hostname:SetFont("cool_large")
self.hostname:SetFont("cool_large")
self.mapchange:SetFont("treb_small")
self.mapchange:SetFont("treb_small")


self.hostdesc:SetTextColor(COLOR_WHITE)
self.hostdesc:SetTextColor(COLOR_WHITE)
self.hostname:SetTextColor(COLOR_BLACK)
self.hostname:SetTextColor(COLOR_BLACK)
self.mapchange:SetTextColor(COLOR_WHITE)
self.mapchange:SetTextColor(COLOR_WHITE)


for k,v in pairs(self.cols) do
for k,v in pairs(self.cols) do
v:SetFont("treb_small")
v:SetFont("treb_small")
v:SetTextColor(COLOR_WHITE)
v:SetTextColor(COLOR_WHITE)
end
end
end
end


function PANEL:UpdateScoreboard( force )
function PANEL:UpdateScoreboard( force )
if not force and not self:IsVisible() then return end
if not force and not self:IsVisible() then return end


local layout = false
local layout = false


-- Put players where they belong. Groups will dump them as soon as they don't
-- Put players where they belong. Groups will dump them as soon as they don't
-- anymore.
-- anymore.
for k, p in pairs(player.GetAll()) do
for k, p in pairs(player.GetAll()) do
if IsValid(p) then
if IsValid(p) then
local group = ScoreGroup(p)
local group = ScoreGroup(p)
if self.ply_groups[group] and not self.ply_groups[group]:HasPlayerRow(p) then
if self.ply_groups[group] and not self.ply_groups[group]:HasPlayerRow(p) then
self.ply_groups[group]:AddPlayerRow(p)
self.ply_groups[group]:AddPlayerRow(p)
layout = true
layout = true
end
end
end
end
end
end


for k, group in pairs(self.ply_groups) do
for k, group in pairs(self.ply_groups) do
if IsValid(group) then
if ValidPanel(group) then
group:SetVisible( group:HasRows() )
group:SetVisible( group:HasRows() )
group:UpdatePlayerData()
group:UpdatePlayerData()
end
end
end
end


if layout then
if layout then
self:PerformLayout()
self:PerformLayout()
else
else
self:InvalidateLayout()
self:InvalidateLayout()
end
end
end
end


vgui.Register( "TTTScoreboard", PANEL, "Panel" )
vgui.Register( "TTTScoreboard", PANEL, "Panel" )


---- PlayerFrame is defined in sandbox and is basically a little scrolling
---- PlayerFrame is defined in sandbox and is basically a little scrolling
---- hack. Just putting it here (slightly modified) because it's tiny.
---- hack. Just putting it here (slightly modified) because it's tiny.


local PANEL = {}
local PANEL = {}
function PANEL:Init()
function PANEL:Init()
self.pnlCanvas = vgui.Create( "Panel", self )
self.pnlCanvas = vgui.Create( "Panel", self )
self.YOffset = 0
self.YOffset = 0


self.scroll = vgui.Create("DVScrollBar", self)
self.scroll = vgui.Create("DVScrollBar", self)
end
end


function PANEL:GetCanvas() return self.pnlCanvas end
function PANEL:GetCanvas() return self.pnlCanvas end


function PANEL:OnMouseWheeled( dlta )
function PANEL:OnMouseWheeled( dlta )
self.scroll:AddScroll(dlta * -2)
self.scroll:AddScroll(dlta * -2)


self:InvalidateLayout()
self:InvalidateLayout()
end
end


function PANEL:SetScroll(st)
function PANEL:SetScroll(st)
self.scroll:SetEnabled(st)
self.scroll:SetEnabled(st)
end
end


function PANEL:PerformLayout()
function PANEL:PerformLayout()
self.pnlCanvas:SetVisible(self:IsVisible())
self.pnlCanvas:SetVisible(self:IsVisible())


-- scrollbar
-- scrollbar
self.scroll:SetPos(self:GetWide() - 16, 0)
self.scroll:SetPos(self:GetWide() - 16, 0)
self.scroll:SetSize(16, self:GetTall())
self.scroll:SetSize(16, self:GetTall())


local was_on = self.scroll.Enabled
local was_on = self.scroll.Enabled
self.scroll:SetUp(self:GetTall(), self.pnlCanvas:GetTall())
self.scroll:SetUp(self:GetTall(), self.pnlCanvas:GetTall())
self.scroll:SetEnabled(was_on) -- setup mangles enabled state
self.scroll:SetEnabled(was_on) -- setup mangles enabled state


self.YOffset = self.scroll:GetOffset()
self.YOffset = self.scroll:GetOffset()


self.pnlCanvas:SetPos( 0, self.YOffset )
self.pnlCanvas:SetPos( 0, self.YOffset )
self.pnlCanvas:SetSize( self:GetWide() - (self.scroll.Enabled and 16 or 0), self.pnlCanvas:GetTall() )
self.pnlCanvas:SetSize( self:GetWide() - (self.scroll.Enabled and 16 or 0), self.pnlCanvas:GetTall() )
end
end
vgui.Register( "TTTPlayerFrame", PANEL, "Panel" )
vgui.Register( "TTTPlayerFrame", PANEL, "Panel" )