mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 13:53:45 +03:00
Upload
This commit is contained in:
32
gamemodes/terrortown/gamemode/vgui/coloredbox.lua
Normal file
32
gamemodes/terrortown/gamemode/vgui/coloredbox.lua
Normal file
@@ -0,0 +1,32 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
-- Removed in GM13, still need it
|
||||
local PANEL = {}
|
||||
AccessorFunc( PANEL, "m_bBorder", "Border" )
|
||||
AccessorFunc( PANEL, "m_Color", "Color" )
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetBorder( true )
|
||||
self:SetColor( Color( 0, 255, 0, 255 ) )
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, 255 )
|
||||
self:DrawFilledRect()
|
||||
end
|
||||
|
||||
function PANEL:PaintOver()
|
||||
if not self.m_bBorder then return end
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 255 )
|
||||
self:DrawOutlinedRect()
|
||||
end
|
||||
derma.DefineControl( "ColoredBox", "", PANEL, "DPanel" )
|
||||
101
gamemodes/terrortown/gamemode/vgui/progressbar.lua
Normal file
101
gamemodes/terrortown/gamemode/vgui/progressbar.lua
Normal file
@@ -0,0 +1,101 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
-- Version of DProgressBar I can mess around with
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
AccessorFunc( PANEL, "m_iMin", "Min" )
|
||||
AccessorFunc( PANEL, "m_iMax", "Max" )
|
||||
AccessorFunc( PANEL, "m_iValue", "Value" )
|
||||
AccessorFunc( PANEL, "m_Color", "Color" )
|
||||
|
||||
function PANEL:Init()
|
||||
self.Label = vgui.Create( "DLabel", self )
|
||||
self.Label:SetFont( "DefaultSmall" )
|
||||
self.Label:SetColor( Color( 0, 0, 0 ) )
|
||||
|
||||
self:SetMin( 0 )
|
||||
self:SetMax( 1000 )
|
||||
self:SetValue( 253 )
|
||||
self:SetColor( Color( 50, 205, 255, 255 ) )
|
||||
end
|
||||
|
||||
function PANEL:LabelAsPercentage()
|
||||
self.m_bLabelAsPercentage = true
|
||||
self:UpdateText()
|
||||
end
|
||||
|
||||
function PANEL:SetMin( i )
|
||||
self.m_iMin = i
|
||||
self:UpdateText()
|
||||
end
|
||||
|
||||
function PANEL:SetMax( i )
|
||||
self.m_iMax = i
|
||||
self:UpdateText()
|
||||
end
|
||||
|
||||
function PANEL:SetValue( i )
|
||||
self.m_iValue = i
|
||||
self:UpdateText()
|
||||
end
|
||||
|
||||
function PANEL:UpdateText()
|
||||
if ( !self.m_iMax ) then return end
|
||||
if ( !self.m_iMin ) then return end
|
||||
if ( !self.m_iValue ) then return end
|
||||
|
||||
local fDelta = 0;
|
||||
|
||||
if ( self.m_iMax-self.m_iMin != 0 ) then
|
||||
fDelta = ( self.m_iValue - self.m_iMin ) / (self.m_iMax-self.m_iMin)
|
||||
end
|
||||
|
||||
if ( self.m_bLabelAsPercentage ) then
|
||||
self.Label:SetText( Format( "%.2f%%", fDelta * 100 ) )
|
||||
return
|
||||
end
|
||||
|
||||
if ( self.m_iMin == 0 ) then
|
||||
|
||||
self.Label:SetText( Format( "%i / %i", self.m_iValue, self.m_iMax ) )
|
||||
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.Label:SizeToContents()
|
||||
self.Label:AlignRight( 5 )
|
||||
self.Label:CenterVertical()
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
|
||||
local fDelta = 0;
|
||||
|
||||
if ( self.m_iMax-self.m_iMin != 0 ) then
|
||||
fDelta = ( self.m_iValue - self.m_iMin ) / (self.m_iMax-self.m_iMin)
|
||||
end
|
||||
|
||||
local Width = self:GetWide()
|
||||
|
||||
surface.SetDrawColor( 0, 0, 0, 170 )
|
||||
surface.DrawRect( 0, 0, Width, self:GetTall() )
|
||||
|
||||
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, self.m_Color.a * 0.5 )
|
||||
surface.DrawRect( 2, 2, Width - 4, self:GetTall() - 4 )
|
||||
surface.SetDrawColor( self.m_Color.r, self.m_Color.g, self.m_Color.b, self.m_Color.a )
|
||||
surface.DrawRect( 2, 2, Width * fDelta - 4, self:GetTall() - 4 )
|
||||
|
||||
end
|
||||
|
||||
vgui.Register( "TTTProgressBar", PANEL, "DPanel" )
|
||||
273
gamemodes/terrortown/gamemode/vgui/sb_info.lua
Normal file
273
gamemodes/terrortown/gamemode/vgui/sb_info.lua
Normal file
@@ -0,0 +1,273 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
---- Player info panel, based on sandbox scoreboard's infocard
|
||||
|
||||
local vgui = vgui
|
||||
|
||||
local GetTranslation = LANG.GetTranslation
|
||||
local GetPTranslation = LANG.GetParamTranslation
|
||||
|
||||
|
||||
--- Base stuff
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.Player = nil
|
||||
|
||||
--self:SetMouseInputEnabled(false)
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.Player = ply
|
||||
self:UpdatePlayerData()
|
||||
end
|
||||
|
||||
function PANEL:UpdatePlayerData()
|
||||
-- override me
|
||||
end
|
||||
|
||||
function PANEL:Paint()
|
||||
return true
|
||||
end
|
||||
|
||||
vgui.Register("TTTScorePlayerInfoBase", PANEL, "Panel")
|
||||
|
||||
--- Dead player search results
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.List = vgui.Create("DPanelSelect", self)
|
||||
self.List:EnableHorizontal(true)
|
||||
|
||||
if self.List.VBar then
|
||||
self.List.VBar:Remove()
|
||||
self.List.VBar = nil
|
||||
end
|
||||
|
||||
self.Scroll = vgui.Create("DHorizontalScroller", self.List)
|
||||
|
||||
self.Help = vgui.Create("DLabel", self)
|
||||
self.Help:SetText(GetTranslation("sb_info_help"))
|
||||
self.Help:SetFont("treb_small")
|
||||
self.Help:SetVisible(false)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self:SetSize(self:GetWide(), 75)
|
||||
|
||||
self.List:SetPos(0, 0)
|
||||
self.List:SetSize(self:GetWide(), 70)
|
||||
self.List:SetSpacing(1)
|
||||
self.List:SetPadding(2)
|
||||
self.List:SetPaintBackground(false)
|
||||
|
||||
self.Scroll:StretchToParent(3,3,3,3)
|
||||
|
||||
self.Help:SizeToContents()
|
||||
self.Help:SetPos(5, 5)
|
||||
end
|
||||
|
||||
function PANEL:UpdatePlayerData()
|
||||
if not IsValid(self.Player) then return end
|
||||
if not self.Player.search_result then
|
||||
self.Help:SetVisible(true)
|
||||
return
|
||||
end
|
||||
|
||||
self.Help:SetVisible(false)
|
||||
|
||||
if self.Search == self.Player.search_result then return end
|
||||
|
||||
self.List:Clear(true)
|
||||
self.Scroll.Panels = {}
|
||||
|
||||
local search_raw = self.Player.search_result
|
||||
|
||||
-- standard search result preproc
|
||||
local search = PreprocSearch(search_raw)
|
||||
|
||||
-- wipe some stuff we don't need, like id
|
||||
search.nick = nil
|
||||
|
||||
-- Create table of SimpleIcons, each standing for a piece of search
|
||||
-- information.
|
||||
for t, info in SortedPairsByMemberValue(search, "p") do
|
||||
local ic = nil
|
||||
|
||||
-- Certain items need a special icon conveying additional information
|
||||
if t == "lastid" then
|
||||
ic = vgui.Create("SimpleIconAvatar", self.List)
|
||||
ic:SetPlayer(info.ply)
|
||||
ic:SetAvatarSize(24)
|
||||
elseif t == "dtime" then
|
||||
ic = vgui.Create("SimpleIconLabelled", self.List)
|
||||
ic:SetIconText(info.text_icon)
|
||||
else
|
||||
ic = vgui.Create("SimpleIcon", self.List)
|
||||
end
|
||||
|
||||
ic:SetIconSize(64)
|
||||
ic:SetIcon(info.img)
|
||||
|
||||
ic:SetTooltip(info.text)
|
||||
|
||||
ic.info_type = t
|
||||
|
||||
self.List:AddPanel(ic)
|
||||
self.Scroll:AddPanel(ic)
|
||||
end
|
||||
|
||||
self.Search = search_raw
|
||||
|
||||
self.List:InvalidateLayout()
|
||||
self.Scroll:InvalidateLayout()
|
||||
|
||||
self:PerformLayout()
|
||||
end
|
||||
|
||||
|
||||
vgui.Register("TTTScorePlayerInfoSearch", PANEL, "TTTScorePlayerInfoBase")
|
||||
|
||||
--- Living player, tags etc
|
||||
|
||||
local tags = {
|
||||
{txt="sb_tag_friend", color=COLOR_GREEN},
|
||||
{txt="sb_tag_susp", color=COLOR_YELLOW},
|
||||
{txt="sb_tag_avoid", color=Color(255, 150, 0, 255)},
|
||||
{txt="sb_tag_kill", color=COLOR_RED},
|
||||
{txt="sb_tag_miss", color=Color(130, 190, 130, 255)}
|
||||
};
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.TagButtons = {}
|
||||
|
||||
for k, tag in ipairs(tags) do
|
||||
self.TagButtons[k] = vgui.Create("TagButton", self)
|
||||
self.TagButtons[k]:SetupTag(tag)
|
||||
end
|
||||
|
||||
--self:SetMouseInputEnabled(false)
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.Player = ply
|
||||
|
||||
for _, btn in pairs(self.TagButtons) do
|
||||
btn:SetPlayer(ply)
|
||||
end
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:ApplySchemeSettings()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:UpdateTag()
|
||||
self:GetParent():UpdatePlayerData()
|
||||
|
||||
self:GetParent():SetOpen(false)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self:SetSize(self:GetWide(), 30)
|
||||
|
||||
local margin = 10
|
||||
local x = 250 --29
|
||||
local y = 0
|
||||
|
||||
for k, btn in ipairs(self.TagButtons) do
|
||||
btn:SetPos(x, y)
|
||||
btn:SetCursor("hand")
|
||||
btn:SizeToContents()
|
||||
btn:PerformLayout()
|
||||
x = x + btn:GetWide() + margin
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("TTTScorePlayerInfoTags", PANEL, "TTTScorePlayerInfoBase")
|
||||
|
||||
--- Tag button
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.Player = nil
|
||||
|
||||
self:SetText("")
|
||||
self:SetMouseInputEnabled(true)
|
||||
self:SetKeyboardInputEnabled(false)
|
||||
|
||||
self:SetTall(20)
|
||||
|
||||
self:SetPaintBackgroundEnabled(false)
|
||||
self:SetPaintBorderEnabled(false)
|
||||
|
||||
self:SetPaintBackground(false)
|
||||
self:SetDrawBorder(false)
|
||||
|
||||
self:SetFont("treb_small")
|
||||
self:SetTextColor(self.Tag and self.Tag.color or COLOR_WHITE)
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.Player = ply
|
||||
end
|
||||
|
||||
function PANEL:SetupTag(tag)
|
||||
self.Tag = tag
|
||||
|
||||
self.Color = tag.color
|
||||
self.Text = tag.txt
|
||||
|
||||
self:SetTextColor(self.Tag and self.Tag.color or COLOR_WHITE)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self:SetText(self.Tag and GetTranslation(self.Tag.txt) or "")
|
||||
self:SizeToContents()
|
||||
self:SetContentAlignment(5)
|
||||
self:SetSize(self:GetWide() + 10, self:GetTall() + 3)
|
||||
end
|
||||
|
||||
function PANEL:DoRightClick()
|
||||
if IsValid(self.Player) then
|
||||
self.Player.sb_tag = nil
|
||||
|
||||
self:GetParent():UpdateTag()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:DoClick()
|
||||
if IsValid(self.Player) then
|
||||
if self.Player.sb_tag == self.Tag then
|
||||
self.Player.sb_tag = nil
|
||||
else
|
||||
self.Player.sb_tag = self.Tag
|
||||
end
|
||||
|
||||
self:GetParent():UpdateTag()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local select_color = Color(255, 200, 0, 255)
|
||||
function PANEL:PaintOver()
|
||||
if self.Player and self.Player.sb_tag == self.Tag then
|
||||
surface.SetDrawColor(255,200,0,255)
|
||||
surface.DrawOutlinedRect(0, 0, self:GetWide(), self:GetTall())
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("TagButton", PANEL, "DButton")
|
||||
486
gamemodes/terrortown/gamemode/vgui/sb_main.lua
Normal file
486
gamemodes/terrortown/gamemode/vgui/sb_main.lua
Normal file
@@ -0,0 +1,486 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
---- VGUI panel version of the scoreboard, based on TEAM GARRY's sandbox mode
|
||||
---- scoreboard.
|
||||
|
||||
local surface = surface
|
||||
local draw = draw
|
||||
local math = math
|
||||
local string = string
|
||||
local vgui = vgui
|
||||
|
||||
local GetTranslation = LANG.GetTranslation
|
||||
local GetPTranslation = LANG.GetParamTranslation
|
||||
|
||||
include("sb_team.lua")
|
||||
|
||||
surface.CreateFont("cool_small", {font = "coolvetica",
|
||||
size = 20,
|
||||
weight = 400})
|
||||
surface.CreateFont("cool_large", {font = "coolvetica",
|
||||
size = 24,
|
||||
weight = 400})
|
||||
surface.CreateFont("treb_small", {font = "Trebuchet18",
|
||||
size = 14,
|
||||
weight = 700})
|
||||
|
||||
CreateClientConVar("ttt_scoreboard_sorting", "name", true, false, "name | role | karma | score | deaths | ping")
|
||||
CreateClientConVar("ttt_scoreboard_ascending", "1", true, false, "Should scoreboard ordering be in ascending order")
|
||||
|
||||
local logo = surface.GetTextureID("vgui/ttt/score_logo")
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
local max = math.max
|
||||
local floor = math.floor
|
||||
local function UntilMapChange()
|
||||
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 h = floor(time_left / 3600)
|
||||
time_left = time_left - floor(h * 3600)
|
||||
local m = floor(time_left / 60)
|
||||
time_left = time_left - floor(m * 60)
|
||||
local s = floor(time_left)
|
||||
|
||||
return rounds_left, string.format("%02i:%02i:%02i", h, m, s)
|
||||
end
|
||||
|
||||
|
||||
GROUP_TERROR = 1
|
||||
GROUP_NOTFOUND = 2
|
||||
GROUP_FOUND = 3
|
||||
GROUP_SPEC = 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)
|
||||
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 p:IsSpec() and (not p:Alive()) then
|
||||
if p:GetNWBool("body_found", false) then
|
||||
return GROUP_FOUND
|
||||
else
|
||||
local client = LocalPlayer()
|
||||
-- To terrorists, missing players show as alive
|
||||
if client:IsSpec() or
|
||||
client:IsActiveTraitor() or
|
||||
((GAMEMODE.round_state != ROUND_ACTIVE) and client:IsTerror()) then
|
||||
return GROUP_NOTFOUND
|
||||
else
|
||||
return GROUP_TERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return p:IsTerror() and GROUP_TERROR or GROUP_SPEC
|
||||
end
|
||||
|
||||
|
||||
-- Comparison functions used to sort scoreboard
|
||||
sboard_sort = {
|
||||
name = function (plya, plyb)
|
||||
-- Automatically sorts by name if this returns 0
|
||||
return 0
|
||||
end,
|
||||
ping = function (plya, plyb)
|
||||
return plya:Ping() - plyb:Ping()
|
||||
end,
|
||||
deaths = function (plya, plyb)
|
||||
return plya:Deaths() - plyb:Deaths()
|
||||
end,
|
||||
score = function (plya, plyb)
|
||||
return plya:Frags() - plyb:Frags()
|
||||
end,
|
||||
role = function (plya, plyb)
|
||||
local comp = (plya:GetRole() or 0) - (plyb:GetRole() or 0)
|
||||
-- Reverse on purpose;
|
||||
-- otherwise the default ascending order puts boring innocents first
|
||||
comp = 0 - comp
|
||||
return comp
|
||||
end,
|
||||
karma = function (plya, plyb)
|
||||
return (plya:GetBaseKarma() or 0) - (plyb:GetBaseKarma() or 0)
|
||||
end
|
||||
}
|
||||
|
||||
----- PANEL START
|
||||
|
||||
function PANEL:Init()
|
||||
|
||||
self.hostdesc = vgui.Create("DLabel", self)
|
||||
self.hostdesc:SetText(GetTranslation("sb_playing"))
|
||||
self.hostdesc:SetContentAlignment(9)
|
||||
|
||||
self.hostname = vgui.Create( "DLabel", self )
|
||||
self.hostname:SetText( GetHostName() )
|
||||
self.hostname:SetContentAlignment(6)
|
||||
|
||||
self.mapchange = vgui.Create("DLabel", self)
|
||||
self.mapchange:SetText("Map changes in 00 rounds or in 00:00:00")
|
||||
self.mapchange:SetContentAlignment(9)
|
||||
|
||||
self.mapchange.Think = function (sf)
|
||||
local r, t = UntilMapChange()
|
||||
|
||||
sf:SetText(GetPTranslation("sb_mapchange",
|
||||
{num = r, time = t}))
|
||||
sf:SizeToContents()
|
||||
end
|
||||
|
||||
|
||||
self.ply_frame = vgui.Create( "TTTPlayerFrame", self )
|
||||
|
||||
self.ply_groups = {}
|
||||
|
||||
local t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
|
||||
t:SetGroupInfo(GetTranslation("terrorists"), Color(0,200,0,100), GROUP_TERROR)
|
||||
self.ply_groups[GROUP_TERROR] = t
|
||||
|
||||
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
|
||||
t:SetGroupInfo(GetTranslation("spectators"), Color(200, 200, 0, 100), GROUP_SPEC)
|
||||
self.ply_groups[GROUP_SPEC] = t
|
||||
|
||||
if DetectiveMode() then
|
||||
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
|
||||
t:SetGroupInfo(GetTranslation("sb_mia"), Color(130, 190, 130, 100), GROUP_NOTFOUND)
|
||||
self.ply_groups[GROUP_NOTFOUND] = t
|
||||
|
||||
t = vgui.Create("TTTScoreGroup", self.ply_frame:GetCanvas())
|
||||
t:SetGroupInfo(GetTranslation("sb_confirmed"), Color(130, 170, 10, 100), GROUP_FOUND)
|
||||
self.ply_groups[GROUP_FOUND] = t
|
||||
end
|
||||
|
||||
hook.Call( "TTTScoreGroups", nil, self.ply_frame:GetCanvas(), self.ply_groups )
|
||||
|
||||
-- the various score column headers
|
||||
self.cols = {}
|
||||
self:AddColumn( GetTranslation("sb_ping"), nil, nil, "ping" )
|
||||
self:AddColumn( GetTranslation("sb_deaths"), nil, nil, "deaths" )
|
||||
self:AddColumn( GetTranslation("sb_score"), nil, nil, "score" )
|
||||
|
||||
if KARMA.IsEnabled() then
|
||||
self:AddColumn( GetTranslation("sb_karma"), nil, nil, "karma" )
|
||||
end
|
||||
|
||||
self.sort_headers = {}
|
||||
-- Reuse some translations
|
||||
-- Columns spaced out a bit to allow for more room for translations
|
||||
self:AddFakeColumn( GetTranslation("sb_sortby"), nil, 70, nil ) -- "Sort by:"
|
||||
self:AddFakeColumn( GetTranslation("equip_spec_name"), nil, 70, "name" )
|
||||
self:AddFakeColumn( GetTranslation("col_role"), nil, 70, "role" )
|
||||
|
||||
-- Let hooks add their column headers (via AddColumn() or AddFakeColumn())
|
||||
hook.Call( "TTTScoreboardColumns", nil, self )
|
||||
|
||||
self:UpdateScoreboard()
|
||||
self:StartUpdateTimer()
|
||||
end
|
||||
|
||||
local function sort_header_handler(self_, lbl)
|
||||
return function()
|
||||
surface.PlaySound("ui/buttonclick.wav")
|
||||
|
||||
local sorting = GetConVar("ttt_scoreboard_sorting")
|
||||
local ascending = GetConVar("ttt_scoreboard_ascending")
|
||||
|
||||
if lbl.HeadingIdentifier == sorting:GetString() then
|
||||
ascending:SetBool(not ascending:GetBool())
|
||||
else
|
||||
sorting:SetString( lbl.HeadingIdentifier )
|
||||
ascending:SetBool(true)
|
||||
end
|
||||
|
||||
for _, scoregroup in pairs(self_.ply_groups) do
|
||||
scoregroup:UpdateSortCache()
|
||||
scoregroup:InvalidateLayout()
|
||||
end
|
||||
|
||||
self_:ApplySchemeSettings()
|
||||
end
|
||||
end
|
||||
|
||||
-- For headings only the label parameter is relevant, second param is included for
|
||||
-- parity with sb_row
|
||||
local function column_label_work(self_, table_to_add, label, width, sort_identifier, sort_func )
|
||||
local lbl = vgui.Create( "DLabel", self_ )
|
||||
lbl:SetText( label )
|
||||
local can_sort = false
|
||||
lbl.IsHeading = true
|
||||
lbl.Width = width or 50 -- Retain compatibility with existing code
|
||||
|
||||
if sort_identifier != nil then
|
||||
can_sort = true
|
||||
-- If we have an identifier and an existing sort function then it was a built-in
|
||||
-- Otherwise...
|
||||
if _G.sboard_sort[sort_identifier] == nil then
|
||||
if sort_func == nil then
|
||||
ErrorNoHalt( "Sort ID provided without a sorting function, Label = ", label, " ; ID = ", sort_identifier )
|
||||
can_sort = false
|
||||
else
|
||||
_G.sboard_sort[sort_identifier] = sort_func
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if can_sort then
|
||||
lbl:SetMouseInputEnabled(true)
|
||||
lbl:SetCursor("hand")
|
||||
lbl.HeadingIdentifier = sort_identifier
|
||||
lbl.DoClick = sort_header_handler(self_, lbl)
|
||||
end
|
||||
|
||||
table.insert( table_to_add, lbl )
|
||||
return lbl
|
||||
end
|
||||
|
||||
function PANEL:AddColumn( label, _, width, sort_id, sort_func )
|
||||
return column_label_work( self, self.cols, label, width, sort_id, sort_func )
|
||||
end
|
||||
|
||||
-- Adds just column headers without player-specific data
|
||||
-- Identical to PANEL:AddColumn except it adds to the sort_headers table instead
|
||||
function PANEL:AddFakeColumn( label, _, width, sort_id, sort_func )
|
||||
return column_label_work( self, self.sort_headers, label, width, sort_id, sort_func )
|
||||
end
|
||||
|
||||
function PANEL:StartUpdateTimer()
|
||||
if not timer.Exists("TTTScoreboardUpdater") then
|
||||
timer.Create( "TTTScoreboardUpdater", 0.3, 0,
|
||||
function()
|
||||
local pnl = GAMEMODE:GetScoreboardPanel()
|
||||
if IsValid(pnl) then
|
||||
pnl:UpdateScoreboard()
|
||||
end
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
local colors = {
|
||||
bg = Color(30,30,30, 235),
|
||||
bar = Color(220,180,0,255)
|
||||
};
|
||||
|
||||
local y_logo_off = 72
|
||||
|
||||
function PANEL:Paint()
|
||||
-- Logo sticks out, so always offset 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
|
||||
draw.RoundedBox( 8, 0, y_logo_off + 25, self:GetWide(), 32, colors.bar)
|
||||
|
||||
-- TTT Logo
|
||||
surface.SetTexture( logo )
|
||||
surface.SetDrawColor( 255, 255, 255, 255 )
|
||||
surface.DrawTexturedRect( 5, 0, 256, 256 )
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
-- position groups and find their total size
|
||||
local gy = 0
|
||||
-- can't just use pairs (undefined ordering) or ipairs (group 2 and 3 might not exist)
|
||||
for i=1, GROUP_COUNT do
|
||||
local group = self.ply_groups[i]
|
||||
if IsValid(group) then
|
||||
if group:HasRows() then
|
||||
group:SetVisible(true)
|
||||
group:SetPos(0, gy)
|
||||
group:SetSize(self.ply_frame:GetWide(), group:GetTall())
|
||||
group:InvalidateLayout()
|
||||
gy = gy + group:GetTall() + 5
|
||||
else
|
||||
group:SetVisible(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
self.ply_frame:GetCanvas():SetSize(self.ply_frame:GetCanvas():GetWide(), gy)
|
||||
|
||||
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
|
||||
local scrolling = h > ScrH() * 0.95
|
||||
-- gui.EnableScreenClicker(scrolling)
|
||||
self.ply_frame:SetScroll(scrolling)
|
||||
|
||||
h = math.Clamp(h, 110 + y_logo_off, ScrH() * 0.95)
|
||||
|
||||
local w = math.max(ScrW() * 0.6, 640)
|
||||
|
||||
self:SetSize(w, h)
|
||||
self:SetPos( (ScrW() - w) / 2, math.min(72, (ScrH() - h) / 4))
|
||||
|
||||
self.ply_frame:SetPos(8, y_logo_off + 109)
|
||||
self.ply_frame:SetSize(self:GetWide() - 16, self:GetTall() - 109 - y_logo_off - 5)
|
||||
|
||||
-- server stuff
|
||||
self.hostdesc:SizeToContents()
|
||||
self.hostdesc:SetPos(w - self.hostdesc:GetWide() - 8, y_logo_off + 5)
|
||||
|
||||
local hw = w - 180 - 8
|
||||
self.hostname:SetSize(hw, 32)
|
||||
self.hostname:SetPos(w - self.hostname:GetWide() - 8, y_logo_off + 27)
|
||||
|
||||
surface.SetFont("cool_large")
|
||||
local hname = self.hostname:GetValue()
|
||||
local tw, _ = surface.GetTextSize(hname)
|
||||
while tw > hw do
|
||||
hname = string.sub(hname, 1, -6) .. "..."
|
||||
tw, th = surface.GetTextSize(hname)
|
||||
end
|
||||
|
||||
self.hostname:SetText(hname)
|
||||
|
||||
self.mapchange:SizeToContents()
|
||||
self.mapchange:SetPos(w - self.mapchange:GetWide() - 8, y_logo_off + 60)
|
||||
|
||||
-- score columns
|
||||
local cy = y_logo_off + 90
|
||||
local cx = w - 8 -(scrolling and 16 or 0)
|
||||
for k,v in ipairs(self.cols) do
|
||||
v:SizeToContents()
|
||||
cx = cx - v.Width
|
||||
v:SetPos(cx - v:GetWide()/2, cy)
|
||||
end
|
||||
|
||||
-- sort headers
|
||||
-- reuse cy
|
||||
-- cx = logo width + buffer space
|
||||
local cx = 256 + 8
|
||||
for k,v in ipairs(self.sort_headers) do
|
||||
v:SizeToContents()
|
||||
cx = cx + v.Width
|
||||
v:SetPos(cx - v:GetWide()/2, cy)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:ApplySchemeSettings()
|
||||
self.hostdesc:SetFont("cool_small")
|
||||
self.hostname:SetFont("cool_large")
|
||||
self.mapchange:SetFont("treb_small")
|
||||
|
||||
self.hostdesc:SetTextColor(COLOR_WHITE)
|
||||
self.hostname:SetTextColor(COLOR_BLACK)
|
||||
self.mapchange:SetTextColor(COLOR_WHITE)
|
||||
|
||||
local sorting = GetConVar("ttt_scoreboard_sorting"):GetString()
|
||||
|
||||
local highlight_color = Color(175, 175, 175, 255)
|
||||
local default_color = COLOR_WHITE
|
||||
|
||||
for k,v in pairs(self.cols) do
|
||||
v:SetFont("treb_small")
|
||||
if sorting == v.HeadingIdentifier then
|
||||
v:SetTextColor(highlight_color)
|
||||
else
|
||||
v:SetTextColor(default_color)
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(self.sort_headers) do
|
||||
v:SetFont("treb_small")
|
||||
if sorting == v.HeadingIdentifier then
|
||||
v:SetTextColor(highlight_color)
|
||||
else
|
||||
v:SetTextColor(default_color)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:UpdateScoreboard( force )
|
||||
if not force and not self:IsVisible() then return end
|
||||
|
||||
local layout = false
|
||||
|
||||
-- Put players where they belong. Groups will dump them as soon as they don't
|
||||
-- anymore.
|
||||
for k, p in player.Iterator() do
|
||||
if IsValid(p) then
|
||||
local group = ScoreGroup(p)
|
||||
if self.ply_groups[group] and not self.ply_groups[group]:HasPlayerRow(p) then
|
||||
self.ply_groups[group]:AddPlayerRow(p)
|
||||
layout = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for k, group in pairs(self.ply_groups) do
|
||||
if IsValid(group) then
|
||||
group:SetVisible( group:HasRows() )
|
||||
group:UpdatePlayerData()
|
||||
end
|
||||
end
|
||||
|
||||
if layout then
|
||||
self:PerformLayout()
|
||||
else
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register( "TTTScoreboard", PANEL, "Panel" )
|
||||
|
||||
---- PlayerFrame is defined in sandbox and is basically a little scrolling
|
||||
---- hack. Just putting it here (slightly modified) because it's tiny.
|
||||
|
||||
local PANEL = {}
|
||||
function PANEL:Init()
|
||||
self.pnlCanvas = vgui.Create( "Panel", self )
|
||||
self.YOffset = 0
|
||||
|
||||
self.scroll = vgui.Create("DVScrollBar", self)
|
||||
end
|
||||
|
||||
function PANEL:GetCanvas() return self.pnlCanvas end
|
||||
|
||||
function PANEL:OnMouseWheeled( dlta )
|
||||
self.scroll:AddScroll(dlta * -2)
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:SetScroll(st)
|
||||
self.scroll:SetEnabled(st)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.pnlCanvas:SetVisible(self:IsVisible())
|
||||
|
||||
-- scrollbar
|
||||
self.scroll:SetPos(self:GetWide() - 16, 0)
|
||||
self.scroll:SetSize(16, self:GetTall())
|
||||
|
||||
local was_on = self.scroll.Enabled
|
||||
self.scroll:SetUp(self:GetTall(), self.pnlCanvas:GetTall())
|
||||
self.scroll:SetEnabled(was_on) -- setup mangles enabled state
|
||||
|
||||
self.YOffset = self.scroll:GetOffset()
|
||||
|
||||
self.pnlCanvas:SetPos( 0, self.YOffset )
|
||||
self.pnlCanvas:SetSize( self:GetWide() - (self.scroll.Enabled and 16 or 0), self.pnlCanvas:GetTall() )
|
||||
end
|
||||
vgui.Register( "TTTPlayerFrame", PANEL, "Panel" )
|
||||
426
gamemodes/terrortown/gamemode/vgui/sb_row.lua
Normal file
426
gamemodes/terrortown/gamemode/vgui/sb_row.lua
Normal file
@@ -0,0 +1,426 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
---- Scoreboard player score row, based on sandbox version
|
||||
|
||||
include("sb_info.lua")
|
||||
|
||||
|
||||
local GetTranslation = LANG.GetTranslation
|
||||
local GetPTranslation = LANG.GetParamTranslation
|
||||
|
||||
|
||||
SB_ROW_HEIGHT = 24 --16
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
-- cannot create info card until player state is known
|
||||
self.info = nil
|
||||
|
||||
self.open = false
|
||||
|
||||
self.cols = {}
|
||||
self:AddColumn( GetTranslation("sb_ping"), function(ply) return ply:Ping() end )
|
||||
self:AddColumn( GetTranslation("sb_deaths"), function(ply) return ply:Deaths() end )
|
||||
self:AddColumn( GetTranslation("sb_score"), function(ply) return ply:Frags() end )
|
||||
|
||||
if KARMA.IsEnabled() then
|
||||
self:AddColumn( GetTranslation("sb_karma"), function(ply) return math.Round(ply:GetBaseKarma()) end )
|
||||
end
|
||||
|
||||
-- Let hooks add their custom columns
|
||||
hook.Call("TTTScoreboardColumns", nil, self)
|
||||
|
||||
for _, c in ipairs(self.cols) do
|
||||
c:SetMouseInputEnabled(false)
|
||||
end
|
||||
|
||||
self.tag = vgui.Create("DLabel", self)
|
||||
self.tag:SetText("")
|
||||
self.tag:SetMouseInputEnabled(false)
|
||||
|
||||
self.sresult = vgui.Create("DImage", self)
|
||||
self.sresult:SetSize(16,16)
|
||||
self.sresult:SetMouseInputEnabled(false)
|
||||
|
||||
self.avatar = vgui.Create( "AvatarImage", self )
|
||||
self.avatar:SetSize(SB_ROW_HEIGHT, SB_ROW_HEIGHT)
|
||||
self.avatar:SetMouseInputEnabled(false)
|
||||
|
||||
self.nick = vgui.Create("DLabel", self)
|
||||
self.nick:SetMouseInputEnabled(false)
|
||||
|
||||
self.voice = vgui.Create("DImageButton", self)
|
||||
self.voice:SetSize(16,16)
|
||||
|
||||
self:SetCursor( "hand" )
|
||||
end
|
||||
|
||||
function PANEL:AddColumn( label, func, width, _, _ )
|
||||
local lbl = vgui.Create( "DLabel", self )
|
||||
lbl.GetPlayerText = func
|
||||
lbl.IsHeading = false
|
||||
lbl.Width = width or 50 -- Retain compatibility with existing code
|
||||
|
||||
table.insert( self.cols, lbl )
|
||||
return lbl
|
||||
end
|
||||
|
||||
-- Mirror sb_main, of which it and this file both call using the
|
||||
-- TTTScoreboardColumns hook, but it is useless in this file
|
||||
-- Exists only so the hook wont return an error if it tries to
|
||||
-- use the AddFakeColumn function of `sb_main`, which would
|
||||
-- cause this file to raise a `function not found` error or others
|
||||
function PANEL:AddFakeColumn() end
|
||||
|
||||
local namecolor = {
|
||||
default = COLOR_WHITE,
|
||||
admin = Color(220, 180, 0, 255),
|
||||
dev = Color(100, 240, 105, 255)
|
||||
}
|
||||
|
||||
local rolecolor = {
|
||||
default = Color(0, 0, 0, 0),
|
||||
traitor = Color(255, 0, 0, 30),
|
||||
detective = Color(0, 0, 255, 30)
|
||||
}
|
||||
|
||||
function GM:TTTScoreboardColorForPlayer(ply)
|
||||
if not IsValid(ply) then return namecolor.default end
|
||||
|
||||
if ply:SteamID() == "STEAM_0:0:1963640" then
|
||||
return namecolor.dev
|
||||
elseif ply:IsAdmin() and GetGlobalBool("ttt_highlight_admins", true) then
|
||||
return namecolor.admin
|
||||
end
|
||||
return namecolor.default
|
||||
end
|
||||
|
||||
function GM:TTTScoreboardRowColorForPlayer(ply)
|
||||
if not IsValid(ply) then return rolecolor.default end
|
||||
|
||||
if ply:IsTraitor() then
|
||||
return rolecolor.traitor
|
||||
elseif ply:IsDetective() then
|
||||
return rolecolor.detective
|
||||
end
|
||||
|
||||
return rolecolor.default
|
||||
end
|
||||
|
||||
local function ColorForPlayer(ply)
|
||||
if IsValid(ply) then
|
||||
local c = hook.Call("TTTScoreboardColorForPlayer", GAMEMODE, ply)
|
||||
|
||||
-- verify that we got a proper color
|
||||
if c and istable(c) and c.r and c.b and c.g and c.a then
|
||||
return c
|
||||
else
|
||||
ErrorNoHalt("TTTScoreboardColorForPlayer hook returned something that isn't a color!\n")
|
||||
end
|
||||
end
|
||||
return namecolor.default
|
||||
end
|
||||
|
||||
function PANEL:Paint(width, height)
|
||||
if not IsValid(self.Player) then return end
|
||||
|
||||
-- if ( self.Player:GetFriendStatus() == "friend" ) then
|
||||
-- color = Color( 236, 181, 113, 255 )
|
||||
-- end
|
||||
|
||||
local ply = self.Player
|
||||
|
||||
local c = hook.Call("TTTScoreboardRowColorForPlayer", GAMEMODE, ply)
|
||||
|
||||
surface.SetDrawColor(c)
|
||||
surface.DrawRect(0, 0, width, SB_ROW_HEIGHT)
|
||||
|
||||
|
||||
if ply == LocalPlayer() then
|
||||
surface.SetDrawColor( 200, 200, 200, math.Clamp(math.sin(RealTime() * 2) * 50, 0, 100))
|
||||
surface.DrawRect(0, 0, width, SB_ROW_HEIGHT )
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.Player = ply
|
||||
self.avatar:SetPlayer(ply)
|
||||
|
||||
if not self.info then
|
||||
local g = ScoreGroup(ply)
|
||||
if g == GROUP_TERROR and ply != LocalPlayer() then
|
||||
self.info = vgui.Create("TTTScorePlayerInfoTags", self)
|
||||
self.info:SetPlayer(ply)
|
||||
|
||||
self:InvalidateLayout()
|
||||
elseif g == GROUP_FOUND or g == GROUP_NOTFOUND then
|
||||
self.info = vgui.Create("TTTScorePlayerInfoSearch", self)
|
||||
self.info:SetPlayer(ply)
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
else
|
||||
self.info:SetPlayer(ply)
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
self.voice.DoClick = function()
|
||||
if IsValid(ply) and ply != LocalPlayer() then
|
||||
ply:SetMuted(not ply:IsMuted())
|
||||
end
|
||||
end
|
||||
|
||||
self.voice.DoRightClick = function()
|
||||
if IsValid(ply) and ply != LocalPlayer() then
|
||||
self:ShowMicVolumeSlider()
|
||||
end
|
||||
end
|
||||
|
||||
self:UpdatePlayerData()
|
||||
end
|
||||
|
||||
function PANEL:GetPlayer() return self.Player end
|
||||
|
||||
function PANEL:UpdatePlayerData()
|
||||
if not IsValid(self.Player) then return end
|
||||
|
||||
local ply = self.Player
|
||||
for i=1,#self.cols do
|
||||
-- Set text from function, passing the label along so stuff like text
|
||||
-- color can be changed
|
||||
self.cols[i]:SetText( self.cols[i].GetPlayerText(ply, self.cols[i]) )
|
||||
end
|
||||
|
||||
self.nick:SetText(ply:Nick())
|
||||
self.nick:SizeToContents()
|
||||
self.nick:SetTextColor(ColorForPlayer(ply))
|
||||
|
||||
local ptag = ply.sb_tag
|
||||
if ScoreGroup(ply) != GROUP_TERROR then
|
||||
ptag = nil
|
||||
end
|
||||
|
||||
self.tag:SetText(ptag and GetTranslation(ptag.txt) or "")
|
||||
self.tag:SetTextColor(ptag and ptag.color or COLOR_WHITE)
|
||||
|
||||
self.sresult:SetVisible(ply.search_result != nil)
|
||||
|
||||
-- more blue if a detective searched them
|
||||
if ply.search_result and (LocalPlayer():IsDetective() or (not ply.search_result.show)) then
|
||||
self.sresult:SetImageColor(Color(200, 200, 255))
|
||||
end
|
||||
|
||||
-- cols are likely to need re-centering
|
||||
self:LayoutColumns()
|
||||
|
||||
if self.info then
|
||||
self.info:UpdatePlayerData()
|
||||
end
|
||||
|
||||
if self.Player != LocalPlayer() then
|
||||
local muted = self.Player:IsMuted()
|
||||
self.voice:SetImage(muted and "icon16/sound_mute.png" or "icon16/sound.png")
|
||||
else
|
||||
self.voice:Hide()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:ApplySchemeSettings()
|
||||
for k,v in pairs(self.cols) do
|
||||
v:SetFont("treb_small")
|
||||
v:SetTextColor(COLOR_WHITE)
|
||||
end
|
||||
|
||||
self.nick:SetFont("treb_small")
|
||||
self.nick:SetTextColor(ColorForPlayer(self.Player))
|
||||
|
||||
local ptag = self.Player and self.Player.sb_tag
|
||||
self.tag:SetTextColor(ptag and ptag.color or COLOR_WHITE)
|
||||
self.tag:SetFont("treb_small")
|
||||
|
||||
self.sresult:SetImage("icon16/magnifier.png")
|
||||
self.sresult:SetImageColor(Color(170, 170, 170, 150))
|
||||
end
|
||||
|
||||
function PANEL:LayoutColumns()
|
||||
local cx = self:GetWide()
|
||||
for k,v in ipairs(self.cols) do
|
||||
v:SizeToContents()
|
||||
cx = cx - v.Width
|
||||
v:SetPos(cx - v:GetWide()/2, (SB_ROW_HEIGHT - v:GetTall()) / 2)
|
||||
end
|
||||
|
||||
self.tag:SizeToContents()
|
||||
cx = cx - 90
|
||||
self.tag:SetPos(cx - self.tag:GetWide()/2, (SB_ROW_HEIGHT - self.tag:GetTall()) / 2)
|
||||
|
||||
self.sresult:SetPos(cx - 8, (SB_ROW_HEIGHT - 16) / 2)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self.avatar:SetPos(0,0)
|
||||
self.avatar:SetSize(SB_ROW_HEIGHT,SB_ROW_HEIGHT)
|
||||
|
||||
local fw = sboard_panel.ply_frame:GetWide()
|
||||
self:SetWide( sboard_panel.ply_frame.scroll.Enabled and fw-16 or fw )
|
||||
|
||||
if not self.open then
|
||||
self:SetSize(self:GetWide(), SB_ROW_HEIGHT)
|
||||
|
||||
if self.info then self.info:SetVisible(false) end
|
||||
elseif self.info then
|
||||
self:SetSize(self:GetWide(), 100 + SB_ROW_HEIGHT)
|
||||
|
||||
self.info:SetVisible(true)
|
||||
self.info:SetPos(5, SB_ROW_HEIGHT + 5)
|
||||
self.info:SetSize(self:GetWide(), 100)
|
||||
self.info:PerformLayout()
|
||||
|
||||
self:SetSize(self:GetWide(), SB_ROW_HEIGHT + self.info:GetTall())
|
||||
end
|
||||
|
||||
self.nick:SizeToContents()
|
||||
|
||||
self.nick:SetPos(SB_ROW_HEIGHT + 10, (SB_ROW_HEIGHT - self.nick:GetTall()) / 2)
|
||||
|
||||
self:LayoutColumns()
|
||||
|
||||
self.voice:SetVisible(not self.open)
|
||||
self.voice:SetSize(16, 16)
|
||||
self.voice:DockMargin(4, 4, 4, 4)
|
||||
self.voice:Dock(RIGHT)
|
||||
end
|
||||
|
||||
function PANEL:DoClick(x, y)
|
||||
self:SetOpen(not self.open)
|
||||
end
|
||||
|
||||
function PANEL:SetOpen(o)
|
||||
if self.open then
|
||||
surface.PlaySound("ui/buttonclickrelease.wav")
|
||||
else
|
||||
surface.PlaySound("ui/buttonclick.wav")
|
||||
end
|
||||
|
||||
self.open = o
|
||||
|
||||
self:PerformLayout()
|
||||
self:GetParent():PerformLayout()
|
||||
sboard_panel:PerformLayout()
|
||||
end
|
||||
|
||||
function PANEL:DoRightClick()
|
||||
local menu = DermaMenu()
|
||||
menu.Player = self:GetPlayer()
|
||||
|
||||
local close = hook.Call( "TTTScoreboardMenu", nil, menu )
|
||||
if close then menu:Remove() return end
|
||||
|
||||
menu:Open()
|
||||
end
|
||||
|
||||
|
||||
function PANEL:ShowMicVolumeSlider()
|
||||
local width = 300
|
||||
local height = 50
|
||||
local padding = 10
|
||||
|
||||
local sliderHeight = 16
|
||||
local sliderDisplayHeight = 8
|
||||
|
||||
local x = math.max(gui.MouseX() - width, 0)
|
||||
local y = math.min(gui.MouseY(), ScrH() - height)
|
||||
|
||||
local currentPlayerVolume = self:GetPlayer():GetVoiceVolumeScale()
|
||||
currentPlayerVolume = currentPlayerVolume != nil and currentPlayerVolume or 1
|
||||
|
||||
|
||||
-- Frame for the slider
|
||||
local frame = vgui.Create("DFrame")
|
||||
frame:SetPos(x, y)
|
||||
frame:SetSize(width, height)
|
||||
frame:MakePopup()
|
||||
frame:SetTitle("")
|
||||
frame:ShowCloseButton(false)
|
||||
frame:SetDraggable(false)
|
||||
frame:SetSizable(false)
|
||||
frame.Paint = function(self, w, h)
|
||||
draw.RoundedBox(5, 0, 0, w, h, Color(24, 25, 28, 255))
|
||||
end
|
||||
|
||||
-- Automatically close after 10 seconds (something may have gone wrong)
|
||||
timer.Simple(10, function() if IsValid(frame) then frame:Close() end end)
|
||||
|
||||
|
||||
-- "Player volume"
|
||||
local label = vgui.Create("DLabel", frame)
|
||||
label:SetPos(padding, padding)
|
||||
label:SetFont("cool_small")
|
||||
label:SetSize(width - padding * 2, 20)
|
||||
label:SetColor(Color(255, 255, 255, 255))
|
||||
label:SetText(LANG.GetTranslation("sb_playervolume"))
|
||||
|
||||
|
||||
-- Slider
|
||||
local slider = vgui.Create("DSlider", frame)
|
||||
slider:SetHeight(sliderHeight)
|
||||
slider:Dock(TOP)
|
||||
slider:DockMargin(padding, 0, padding, 0)
|
||||
slider:SetSlideX(currentPlayerVolume)
|
||||
slider:SetLockY(0.5)
|
||||
slider.TranslateValues = function(slider, x, y)
|
||||
if IsValid(self:GetPlayer()) then self:GetPlayer():SetVoiceVolumeScale(x) end
|
||||
return x, y
|
||||
end
|
||||
|
||||
-- Close the slider panel once the player has selected a volume
|
||||
slider.OnMouseReleased = function(panel, mcode) frame:Close() end
|
||||
slider.Knob.OnMouseReleased = function(panel, mcode) frame:Close() end
|
||||
|
||||
|
||||
-- Slider rendering
|
||||
-- Render slider bar
|
||||
slider.Paint = function(self, w, h)
|
||||
local volumePercent = slider:GetSlideX()
|
||||
|
||||
-- Filled in box
|
||||
draw.RoundedBox(5, 0, sliderDisplayHeight / 2, w * volumePercent, sliderDisplayHeight, Color(200, 46, 46, 255))
|
||||
|
||||
-- Grey box
|
||||
draw.RoundedBox(5, w * volumePercent, sliderDisplayHeight / 2, w * (1 - volumePercent), sliderDisplayHeight, Color(79, 84, 92, 255))
|
||||
end
|
||||
|
||||
-- Render slider "knob" & text
|
||||
slider.Knob.Paint = function(self, w, h)
|
||||
if slider:IsEditing() then
|
||||
local textValue = math.Round(slider:GetSlideX() * 100) .. "%"
|
||||
local textPadding = 5
|
||||
|
||||
-- The position of the text and size of rounded box are not relative to the text size. May cause problems if font size changes
|
||||
draw.RoundedBox(
|
||||
5, -- Radius
|
||||
-sliderHeight * 0.5 - textPadding, -- X
|
||||
-25, -- Y
|
||||
sliderHeight * 2 + textPadding * 2, -- Width
|
||||
sliderHeight + textPadding * 2, -- Height
|
||||
Color(52, 54, 57, 255)
|
||||
)
|
||||
draw.DrawText(textValue, "cool_small", sliderHeight / 2, -20, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER)
|
||||
end
|
||||
|
||||
draw.RoundedBox(100, 0, 0, sliderHeight, sliderHeight, Color(255, 255, 255, 255))
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register( "TTTScorePlayerRow", PANEL, "DButton" )
|
||||
200
gamemodes/terrortown/gamemode/vgui/sb_team.lua
Normal file
200
gamemodes/terrortown/gamemode/vgui/sb_team.lua
Normal file
@@ -0,0 +1,200 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
---- Unlike sandbox, we have teams to deal with, so here's an extra panel in the
|
||||
---- hierarchy that handles a set of player rows belonging to its team.
|
||||
|
||||
include("sb_row.lua")
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.name = "Unnamed"
|
||||
|
||||
self.color = COLOR_WHITE
|
||||
|
||||
self.rows = {}
|
||||
self.rowcount = 0
|
||||
|
||||
self.rows_sorted = {}
|
||||
|
||||
self.group = "spec"
|
||||
end
|
||||
|
||||
function PANEL:SetGroupInfo(name, color, group)
|
||||
self.name = name
|
||||
self.color = color
|
||||
self.group = group
|
||||
end
|
||||
|
||||
local bgcolor = Color(20,20,20, 150)
|
||||
function PANEL:Paint()
|
||||
-- Darkened background
|
||||
draw.RoundedBox(8, 0, 0, self:GetWide(), self:GetTall(), bgcolor)
|
||||
|
||||
surface.SetFont("treb_small")
|
||||
|
||||
-- Header bg
|
||||
local txt = self.name .. " (" .. self.rowcount .. ")"
|
||||
local w, h = surface.GetTextSize(txt)
|
||||
draw.RoundedBox(8, 0, 0, w + 24, 20, self.color)
|
||||
|
||||
-- Shadow
|
||||
surface.SetTextPos(11, 11 - h/2)
|
||||
surface.SetTextColor(0,0,0, 200)
|
||||
surface.DrawText(txt)
|
||||
|
||||
-- Text
|
||||
surface.SetTextPos(10, 10 - h/2)
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.DrawText(txt)
|
||||
|
||||
-- Alternating row background
|
||||
local y = 24
|
||||
for i, row in ipairs(self.rows_sorted) do
|
||||
if (i % 2) != 0 then
|
||||
surface.SetDrawColor(75,75,75, 100)
|
||||
surface.DrawRect(0, y, self:GetWide(), row:GetTall())
|
||||
end
|
||||
|
||||
y = y + row:GetTall() + 1
|
||||
end
|
||||
|
||||
-- Column darkening
|
||||
local scr = sboard_panel.ply_frame.scroll.Enabled and 16 or 0
|
||||
surface.SetDrawColor(0,0,0, 80)
|
||||
if sboard_panel.cols then
|
||||
local cx = self:GetWide() - scr
|
||||
for k,v in ipairs(sboard_panel.cols) do
|
||||
cx = cx - v.Width
|
||||
if k % 2 == 1 then -- Draw for odd numbered columns
|
||||
surface.DrawRect(cx-v.Width/2, 0, v.Width, self:GetTall())
|
||||
end
|
||||
end
|
||||
else
|
||||
-- If columns are not setup yet, fall back to darkening the areas for the
|
||||
-- default columns
|
||||
surface.DrawRect(self:GetWide() - 175 - 25 - scr, 0, 50, self:GetTall())
|
||||
surface.DrawRect(self:GetWide() - 75 - 25 - scr, 0, 50, self:GetTall())
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:AddPlayerRow(ply)
|
||||
if ScoreGroup(ply) == self.group and not self.rows[ply] then
|
||||
local row = vgui.Create("TTTScorePlayerRow", self)
|
||||
row:SetPlayer(ply)
|
||||
self.rows[ply] = row
|
||||
self.rowcount = table.Count(self.rows)
|
||||
|
||||
-- must force layout immediately or it takes its sweet time to do so
|
||||
self:PerformLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:HasPlayerRow(ply)
|
||||
return self.rows[ply] != nil
|
||||
end
|
||||
|
||||
function PANEL:HasRows()
|
||||
return self.rowcount > 0
|
||||
end
|
||||
|
||||
local strlower = string.lower
|
||||
function PANEL:UpdateSortCache()
|
||||
self.rows_sorted = {}
|
||||
|
||||
for _, row in pairs(self.rows) do
|
||||
table.insert(self.rows_sorted, row)
|
||||
end
|
||||
|
||||
table.sort(self.rows_sorted, function(rowa, rowb)
|
||||
local plya = rowa:GetPlayer()
|
||||
local plyb = rowb:GetPlayer()
|
||||
|
||||
if not IsValid(plya) then return false end
|
||||
if not IsValid(plyb) then return true end
|
||||
|
||||
local sort_mode = GetConVar("ttt_scoreboard_sorting"):GetString()
|
||||
local sort_func = sboard_sort[sort_mode]
|
||||
|
||||
local comp = 0
|
||||
if sort_func != nil then
|
||||
comp = sort_func(plya, plyb)
|
||||
end
|
||||
|
||||
local ret = true
|
||||
|
||||
if comp != 0 then
|
||||
ret = comp > 0
|
||||
else
|
||||
ret = strlower(plya:GetName()) > strlower(plyb:GetName())
|
||||
end
|
||||
|
||||
if GetConVar("ttt_scoreboard_ascending"):GetBool() then
|
||||
ret = not ret
|
||||
end
|
||||
|
||||
return ret
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL:UpdatePlayerData()
|
||||
local to_remove = {}
|
||||
for k,v in pairs(self.rows) do
|
||||
-- Player still belongs in this group?
|
||||
if IsValid(v) and IsValid(v:GetPlayer()) and ScoreGroup(v:GetPlayer()) == self.group then
|
||||
v:UpdatePlayerData()
|
||||
else
|
||||
-- can't remove now, will break pairs
|
||||
table.insert(to_remove, k)
|
||||
end
|
||||
end
|
||||
|
||||
if #to_remove == 0 then return end
|
||||
|
||||
for k,ply in pairs(to_remove) do
|
||||
local pnl = self.rows[ply]
|
||||
if IsValid(pnl) then
|
||||
pnl:Remove()
|
||||
end
|
||||
|
||||
self.rows[ply] = nil
|
||||
end
|
||||
self.rowcount = table.Count(self.rows)
|
||||
|
||||
self:UpdateSortCache()
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if self.rowcount < 1 then
|
||||
self:SetVisible(false)
|
||||
return
|
||||
end
|
||||
|
||||
self:SetSize(self:GetWide(), 30 + self.rowcount + self.rowcount * SB_ROW_HEIGHT)
|
||||
|
||||
-- Sort and layout player rows
|
||||
self:UpdateSortCache()
|
||||
|
||||
local y = 24
|
||||
for k, v in ipairs(self.rows_sorted) do
|
||||
v:SetPos(0, y)
|
||||
v:SetSize(self:GetWide(), v:GetTall())
|
||||
|
||||
y = y + v:GetTall() + 1
|
||||
end
|
||||
|
||||
self:SetSize(self:GetWide(), 30 + (y - 24))
|
||||
end
|
||||
|
||||
vgui.Register("TTTScoreGroup", PANEL, "Panel")
|
||||
88
gamemodes/terrortown/gamemode/vgui/scrolllabel.lua
Normal file
88
gamemodes/terrortown/gamemode/vgui/scrolllabel.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
|
||||
--- why can't the default label scroll? welcome to gmod
|
||||
|
||||
PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.Label = vgui.Create("DLabel", self)
|
||||
self.Label:SetPos(0, 0)
|
||||
|
||||
self.Scroll = vgui.Create("DVScrollBar", self)
|
||||
end
|
||||
|
||||
function PANEL:GetLabel() return self.Label end
|
||||
|
||||
function PANEL:OnMouseWheeled(dlta)
|
||||
if not self.Scroll then return end
|
||||
|
||||
self.Scroll:AddScroll(dlta * -2)
|
||||
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function PANEL:SetScrollEnabled(st) self.Scroll:SetEnabled(st) end
|
||||
|
||||
-- enable/disable scrollbar depending on content size
|
||||
function PANEL:UpdateScrollState()
|
||||
if not self.Scroll then return end
|
||||
|
||||
self.Scroll:SetScroll(0)
|
||||
self:SetScrollEnabled(false)
|
||||
|
||||
self.Label:SetSize(self:GetWide(), self:GetTall())
|
||||
|
||||
self.Label:SizeToContentsY()
|
||||
|
||||
self:SetScrollEnabled(self.Label:GetTall() > self:GetTall())
|
||||
|
||||
self.Label:InvalidateLayout(true)
|
||||
self:InvalidateLayout(true)
|
||||
end
|
||||
|
||||
function PANEL:SetText(txt)
|
||||
if not self.Label then return end
|
||||
|
||||
self.Label:SetText(txt)
|
||||
self:UpdateScrollState()
|
||||
|
||||
-- I give up. VGUI, you have won. Here is your ugly hack to make the label
|
||||
-- resize to the proper height, after you have completely mangled it the
|
||||
-- first time I call SizeToContents. I don't know how or what happens to the
|
||||
-- Label's internal state that makes it work when resizing a second time a
|
||||
-- tick later (it certainly isn't any variant of PerformLayout I can find),
|
||||
-- but it does.
|
||||
local pnl = self.Panel
|
||||
timer.Simple(0, function()
|
||||
if IsValid(pnl) then
|
||||
pnl:UpdateScrollState()
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if not self.Scroll then return end
|
||||
|
||||
self.Label:SetVisible(self:IsVisible())
|
||||
|
||||
self.Scroll:SetPos(self:GetWide() - 16, 0)
|
||||
self.Scroll:SetSize(16, self:GetTall())
|
||||
|
||||
local was_on = self.Scroll.Enabled
|
||||
self.Scroll:SetUp(self:GetTall(), self.Label:GetTall())
|
||||
self.Scroll:SetEnabled(was_on) -- setup mangles enabled state
|
||||
|
||||
self.Label:SetPos( 0, self.Scroll:GetOffset() )
|
||||
self.Label:SetSize( self:GetWide() - (self.Scroll.Enabled and 16 or 0), self.Label:GetTall() )
|
||||
end
|
||||
|
||||
vgui.Register("ScrollLabel", PANEL, "Panel")
|
||||
240
gamemodes/terrortown/gamemode/vgui/simpleicon.lua
Normal file
240
gamemodes/terrortown/gamemode/vgui/simpleicon.lua
Normal file
@@ -0,0 +1,240 @@
|
||||
--[[
|
||||
| This file was obtained through the combined efforts
|
||||
| of Madbluntz & Plymouth Antiquarian Society.
|
||||
|
|
||||
| Credits: lifestorm, Gregory Wayne Rossel JR.,
|
||||
| Maloy, DrPepper10 @ RIP, Atle!
|
||||
|
|
||||
| Visit for more: https://plymouth.thetwilightzone.ru/
|
||||
--]]
|
||||
|
||||
-- Altered version of gmod's SpawnIcon
|
||||
-- This panel does not deal with models and such
|
||||
|
||||
|
||||
local matHover = Material( "vgui/spawnmenu/hover" )
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
AccessorFunc( PANEL, "m_iIconSize", "IconSize" )
|
||||
|
||||
function PANEL:Init()
|
||||
self.Icon = vgui.Create( "DImage", self )
|
||||
self.Icon:SetMouseInputEnabled( false )
|
||||
self.Icon:SetKeyboardInputEnabled( false )
|
||||
|
||||
self.animPress = Derma_Anim( "Press", self, self.PressedAnim )
|
||||
|
||||
self:SetIconSize(64)
|
||||
|
||||
end
|
||||
|
||||
function PANEL:OnMousePressed( mcode )
|
||||
if mcode == MOUSE_LEFT then
|
||||
self:DoClick()
|
||||
self.animPress:Start(0.1)
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:OnMouseReleased()
|
||||
end
|
||||
|
||||
function PANEL:DoClick()
|
||||
end
|
||||
|
||||
function PANEL:OpenMenu()
|
||||
end
|
||||
|
||||
function PANEL:ApplySchemeSettings()
|
||||
end
|
||||
|
||||
function PANEL:OnCursorEntered()
|
||||
self.PaintOverOld = self.PaintOver
|
||||
self.PaintOver = self.PaintOverHovered
|
||||
end
|
||||
|
||||
function PANEL:OnCursorExited()
|
||||
if self.PaintOver == self.PaintOverHovered then
|
||||
self.PaintOver = self.PaintOverOld
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:PaintOverHovered()
|
||||
|
||||
if self.animPress:Active() then return end
|
||||
|
||||
surface.SetDrawColor( 255, 255, 255, 80 )
|
||||
surface.SetMaterial( matHover )
|
||||
self:DrawTexturedRect()
|
||||
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if self.animPress:Active() then return end
|
||||
self:SetSize( self.m_iIconSize, self.m_iIconSize )
|
||||
self.Icon:StretchToParent( 0, 0, 0, 0 )
|
||||
end
|
||||
|
||||
function PANEL:SetIcon( icon )
|
||||
self.Icon:SetImage(icon)
|
||||
end
|
||||
|
||||
function PANEL:GetIcon()
|
||||
return self.Icon:GetImage()
|
||||
end
|
||||
|
||||
function PANEL:SetIconColor(clr)
|
||||
self.Icon:SetImageColor(clr)
|
||||
end
|
||||
|
||||
function PANEL:Think()
|
||||
self.animPress:Run()
|
||||
end
|
||||
|
||||
function PANEL:PressedAnim( anim, delta, data )
|
||||
|
||||
if anim.Started then
|
||||
return
|
||||
end
|
||||
|
||||
if anim.Finished then
|
||||
self.Icon:StretchToParent( 0, 0, 0, 0 )
|
||||
return
|
||||
end
|
||||
|
||||
local border = math.sin( delta * math.pi ) * (self.m_iIconSize * 0.05 )
|
||||
self.Icon:StretchToParent( border, border, border, border )
|
||||
|
||||
end
|
||||
|
||||
vgui.Register( "SimpleIcon", PANEL, "Panel" )
|
||||
|
||||
---
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.Layers = {}
|
||||
end
|
||||
|
||||
-- Add a panel to this icon. Most recent addition will be the top layer.
|
||||
function PANEL:AddLayer(pnl)
|
||||
if not IsValid(pnl) then return end
|
||||
|
||||
pnl:SetParent(self)
|
||||
|
||||
pnl:SetMouseInputEnabled(false)
|
||||
pnl:SetKeyboardInputEnabled(false)
|
||||
|
||||
table.insert(self.Layers, pnl)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
if self.animPress:Active() then return end
|
||||
self:SetSize( self.m_iIconSize, self.m_iIconSize )
|
||||
self.Icon:StretchToParent( 0, 0, 0, 0 )
|
||||
|
||||
for _, p in ipairs(self.Layers) do
|
||||
p:SetPos(0, 0)
|
||||
p:InvalidateLayout()
|
||||
end
|
||||
end
|
||||
|
||||
function PANEL:EnableMousePassthrough(pnl)
|
||||
for _, p in pairs(self.Layers) do
|
||||
if p == pnl then
|
||||
p.OnMousePressed = function(s, mc) s:GetParent():OnMousePressed(mc) end
|
||||
p.OnCursorEntered = function(s) s:GetParent():OnCursorEntered() end
|
||||
p.OnCursorExited = function(s) s:GetParent():OnCursorExited() end
|
||||
|
||||
p:SetMouseInputEnabled(true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("LayeredIcon", PANEL, "SimpleIcon")
|
||||
|
||||
-- Avatar icon
|
||||
local PANEL = {}
|
||||
|
||||
function PANEL:Init()
|
||||
self.imgAvatar = vgui.Create( "AvatarImage", self )
|
||||
self.imgAvatar:SetMouseInputEnabled( false )
|
||||
self.imgAvatar:SetKeyboardInputEnabled( false )
|
||||
self.imgAvatar.PerformLayout = function(s) s:Center() end
|
||||
|
||||
self:SetAvatarSize(32)
|
||||
|
||||
self:AddLayer(self.imgAvatar)
|
||||
|
||||
--return self.BaseClass.Init(self)
|
||||
end
|
||||
|
||||
function PANEL:SetAvatarSize(s)
|
||||
self.imgAvatar:SetSize(s, s)
|
||||
end
|
||||
|
||||
function PANEL:SetPlayer(ply)
|
||||
self.imgAvatar:SetPlayer(ply)
|
||||
end
|
||||
|
||||
vgui.Register( "SimpleIconAvatar", PANEL, "LayeredIcon" )
|
||||
|
||||
|
||||
--- Labelled icon
|
||||
|
||||
local PANEL = {}
|
||||
|
||||
AccessorFunc(PANEL, "IconText", "IconText")
|
||||
AccessorFunc(PANEL, "IconTextColor", "IconTextColor")
|
||||
AccessorFunc(PANEL, "IconFont", "IconFont")
|
||||
AccessorFunc(PANEL, "IconTextShadow", "IconTextShadow")
|
||||
AccessorFunc(PANEL, "IconTextPos", "IconTextPos")
|
||||
|
||||
function PANEL:Init()
|
||||
self:SetIconText("")
|
||||
self:SetIconTextColor(Color(255, 200, 0))
|
||||
self:SetIconFont("TargetID")
|
||||
self:SetIconTextShadow({opacity=255, offset=2})
|
||||
self:SetIconTextPos({32, 32})
|
||||
|
||||
-- DPanelSelect loves to overwrite its children's PaintOver hooks and such,
|
||||
-- so have to use a dummy panel to do some custom painting.
|
||||
self.FakeLabel = vgui.Create("Panel", self)
|
||||
self.FakeLabel.PerformLayout = function(s) s:StretchToParent(0,0,0,0) end
|
||||
|
||||
self:AddLayer(self.FakeLabel)
|
||||
|
||||
return self.BaseClass.Init(self)
|
||||
end
|
||||
|
||||
function PANEL:PerformLayout()
|
||||
self:SetLabelText(self:GetIconText(), self:GetIconTextColor(), self:GetIconFont(), self:GetIconTextPos())
|
||||
|
||||
return self.BaseClass.PerformLayout(self)
|
||||
end
|
||||
|
||||
function PANEL:SetIconProperties(color, font, shadow, pos)
|
||||
self:SetIconTextColor( color or self:GetIconTextColor())
|
||||
self:SetIconFont( font or self:GetIconFont())
|
||||
self:SetIconTextShadow(shadow or self:GetIconShadow())
|
||||
self:SetIconTextPos( pos or self:GetIconTextPos())
|
||||
end
|
||||
|
||||
function PANEL:SetLabelText(text, color, font, pos)
|
||||
if self.FakeLabel then
|
||||
local spec = {pos=pos, color=color, text=text, font=font, xalign=TEXT_ALIGN_CENTER, yalign=TEXT_ALIGN_CENTER}
|
||||
|
||||
local shadow = self:GetIconTextShadow()
|
||||
local opacity = shadow and shadow.opacity or 0
|
||||
local offset = shadow and shadow.offset or 0
|
||||
|
||||
local drawfn = shadow and draw.TextShadow or draw.Text
|
||||
|
||||
self.FakeLabel.Paint = function()
|
||||
drawfn(spec, offset, opacity)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
vgui.Register("SimpleIconLabelled", PANEL, "LayeredIcon")
|
||||
Reference in New Issue
Block a user