mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-16 21:33:46 +03:00
385 lines
11 KiB
Lua
385 lines
11 KiB
Lua
|
|
--[[
|
||
|
|
| 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/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
-- HUD HUD HUD
|
||
|
|
|
||
|
|
local table = table
|
||
|
|
local surface = surface
|
||
|
|
local draw = draw
|
||
|
|
local math = math
|
||
|
|
local string = string
|
||
|
|
|
||
|
|
local GetTranslation = LANG.GetTranslation
|
||
|
|
local GetPTranslation = LANG.GetParamTranslation
|
||
|
|
local GetLang = LANG.GetUnsafeLanguageTable
|
||
|
|
local interp = string.Interp
|
||
|
|
|
||
|
|
-- Fonts
|
||
|
|
surface.CreateFont("TraitorState", {font = "Trebuchet24",
|
||
|
|
size = 28,
|
||
|
|
weight = 1000})
|
||
|
|
surface.CreateFont("TimeLeft", {font = "Trebuchet24",
|
||
|
|
size = 24,
|
||
|
|
weight = 800})
|
||
|
|
surface.CreateFont("HealthAmmo", {font = "Trebuchet24",
|
||
|
|
size = 24,
|
||
|
|
weight = 750})
|
||
|
|
-- Color presets
|
||
|
|
local bg_colors = {
|
||
|
|
background_main = Color(0, 0, 10, 200),
|
||
|
|
|
||
|
|
noround = Color(100,100,100,200),
|
||
|
|
traitor = Color(200, 25, 25, 200),
|
||
|
|
innocent = Color(25, 200, 25, 200),
|
||
|
|
detective = Color(25, 25, 200, 200)
|
||
|
|
};
|
||
|
|
|
||
|
|
local health_colors = {
|
||
|
|
border = COLOR_WHITE,
|
||
|
|
background = Color(100, 25, 25, 222),
|
||
|
|
fill = Color(200, 50, 50, 250)
|
||
|
|
};
|
||
|
|
|
||
|
|
local ammo_colors = {
|
||
|
|
border = COLOR_WHITE,
|
||
|
|
background = Color(20, 20, 5, 222),
|
||
|
|
fill = Color(205, 155, 0, 255)
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
-- Modified RoundedBox
|
||
|
|
local Tex_Corner8 = surface.GetTextureID( "gui/corner8" )
|
||
|
|
local function RoundedMeter( bs, x, y, w, h, color)
|
||
|
|
surface.SetDrawColor(clr(color))
|
||
|
|
|
||
|
|
surface.DrawRect( x+bs, y, w-bs*2, h )
|
||
|
|
surface.DrawRect( x, y+bs, bs, h-bs*2 )
|
||
|
|
|
||
|
|
surface.SetTexture( Tex_Corner8 )
|
||
|
|
surface.DrawTexturedRectRotated( x + bs/2 , y + bs/2, bs, bs, 0 )
|
||
|
|
surface.DrawTexturedRectRotated( x + bs/2 , y + h -bs/2, bs, bs, 90 )
|
||
|
|
|
||
|
|
if w > 14 then
|
||
|
|
surface.DrawRect( x+w-bs, y+bs, bs, h-bs*2 )
|
||
|
|
surface.DrawTexturedRectRotated( x + w - bs/2 , y + bs/2, bs, bs, 270 )
|
||
|
|
surface.DrawTexturedRectRotated( x + w - bs/2 , y + h - bs/2, bs, bs, 180 )
|
||
|
|
else
|
||
|
|
surface.DrawRect( x + math.max(w-bs, bs), y, bs/2, h )
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
---- The bar painting is loosely based on:
|
||
|
|
---- http://wiki.garrysmod.com/?title=Creating_a_HUD
|
||
|
|
|
||
|
|
-- Paints a graphical meter bar
|
||
|
|
local function PaintBar(x, y, w, h, colors, value)
|
||
|
|
-- Background
|
||
|
|
-- slightly enlarged to make a subtle border
|
||
|
|
draw.RoundedBox(8, x-1, y-1, w+2, h+2, colors.background)
|
||
|
|
|
||
|
|
-- Fill
|
||
|
|
local width = w * math.Clamp(value, 0, 1)
|
||
|
|
|
||
|
|
if width > 0 then
|
||
|
|
RoundedMeter(8, x, y, width, h, colors.fill)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local roundstate_string = {
|
||
|
|
[ROUND_WAIT] = "round_wait",
|
||
|
|
[ROUND_PREP] = "round_prep",
|
||
|
|
[ROUND_ACTIVE] = "round_active",
|
||
|
|
[ROUND_POST] = "round_post"
|
||
|
|
};
|
||
|
|
|
||
|
|
-- Returns player's ammo information
|
||
|
|
local function GetAmmo(ply)
|
||
|
|
local weap = ply:GetActiveWeapon()
|
||
|
|
if not weap or not ply:Alive() then return -1 end
|
||
|
|
|
||
|
|
local ammo_inv = weap:Ammo1() or 0
|
||
|
|
local ammo_clip = weap:Clip1() or 0
|
||
|
|
local ammo_max = weap.Primary.ClipSize or 0
|
||
|
|
|
||
|
|
return ammo_clip, ammo_max, ammo_inv
|
||
|
|
end
|
||
|
|
|
||
|
|
local function DrawBg(x, y, width, height, client)
|
||
|
|
-- Traitor area sizes
|
||
|
|
local th = 30
|
||
|
|
local tw = 170
|
||
|
|
|
||
|
|
-- Adjust for these
|
||
|
|
y = y - th
|
||
|
|
height = height + th
|
||
|
|
|
||
|
|
-- main bg area, invariant
|
||
|
|
-- encompasses entire area
|
||
|
|
draw.RoundedBox(8, x, y, width, height, bg_colors.background_main)
|
||
|
|
|
||
|
|
-- main border, traitor based
|
||
|
|
local col = bg_colors.innocent
|
||
|
|
if GAMEMODE.round_state != ROUND_ACTIVE then
|
||
|
|
col = bg_colors.noround
|
||
|
|
elseif client:GetTraitor() then
|
||
|
|
col = bg_colors.traitor
|
||
|
|
elseif client:GetDetective() then
|
||
|
|
col = bg_colors.detective
|
||
|
|
end
|
||
|
|
|
||
|
|
draw.RoundedBox(8, x, y, tw, th, col)
|
||
|
|
end
|
||
|
|
|
||
|
|
local sf = surface
|
||
|
|
local dr = draw
|
||
|
|
|
||
|
|
local function ShadowedText(text, font, x, y, color, xalign, yalign)
|
||
|
|
|
||
|
|
dr.SimpleText(text, font, x+2, y+2, COLOR_BLACK, xalign, yalign)
|
||
|
|
|
||
|
|
dr.SimpleText(text, font, x, y, color, xalign, yalign)
|
||
|
|
end
|
||
|
|
|
||
|
|
local margin = 10
|
||
|
|
|
||
|
|
-- Paint punch-o-meter
|
||
|
|
local function PunchPaint(client)
|
||
|
|
local L = GetLang()
|
||
|
|
local punch = client:GetNWFloat("specpunches", 0)
|
||
|
|
|
||
|
|
local width, height = 200, 25
|
||
|
|
local x = ScrW() / 2 - width/2
|
||
|
|
local y = margin/2 + height
|
||
|
|
|
||
|
|
PaintBar(x, y, width, height, ammo_colors, punch)
|
||
|
|
|
||
|
|
local color = bg_colors.background_main
|
||
|
|
|
||
|
|
dr.SimpleText(L.punch_title, "HealthAmmo", ScrW() / 2, y, color, TEXT_ALIGN_CENTER)
|
||
|
|
|
||
|
|
dr.SimpleText(L.punch_help, "TabLarge", ScrW() / 2, margin, COLOR_WHITE, TEXT_ALIGN_CENTER)
|
||
|
|
|
||
|
|
local bonus = client:GetNWInt("bonuspunches", 0)
|
||
|
|
if bonus != 0 then
|
||
|
|
local text
|
||
|
|
if bonus < 0 then
|
||
|
|
text = interp(L.punch_bonus, {num = bonus})
|
||
|
|
else
|
||
|
|
text = interp(L.punch_malus, {num = bonus})
|
||
|
|
end
|
||
|
|
|
||
|
|
dr.SimpleText(text, "TabLarge", ScrW() / 2, y * 2, COLOR_WHITE, TEXT_ALIGN_CENTER)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local key_params = { usekey = Key("+use", "USE") }
|
||
|
|
|
||
|
|
local function SpecHUDPaint(client)
|
||
|
|
local L = GetLang() -- for fast direct table lookups
|
||
|
|
|
||
|
|
-- Draw round state
|
||
|
|
local x = margin
|
||
|
|
local height = 32
|
||
|
|
local width = 250
|
||
|
|
local round_y = ScrH() - height - margin
|
||
|
|
|
||
|
|
-- move up a little on low resolutions to allow space for spectator hints
|
||
|
|
if ScrW() < 1000 then round_y = round_y - 15 end
|
||
|
|
|
||
|
|
local time_x = x + 170
|
||
|
|
local time_y = round_y + 4
|
||
|
|
|
||
|
|
draw.RoundedBox(8, x, round_y, width, height, bg_colors.background_main)
|
||
|
|
draw.RoundedBox(8, x, round_y, time_x - x, height, bg_colors.noround)
|
||
|
|
|
||
|
|
local text = L[ roundstate_string[GAMEMODE.round_state] ]
|
||
|
|
ShadowedText(text, "TraitorState", x + margin, round_y, COLOR_WHITE)
|
||
|
|
|
||
|
|
-- Draw round/prep/post time remaining
|
||
|
|
local text = util.SimpleTime(math.max(0, GetGlobalFloat("ttt_round_end", 0) - CurTime()), "%02i:%02i")
|
||
|
|
ShadowedText(text, "TimeLeft", time_x + margin, time_y, COLOR_WHITE)
|
||
|
|
|
||
|
|
local tgt = client:GetObserverTarget()
|
||
|
|
if IsValid(tgt) and tgt:IsPlayer() then
|
||
|
|
ShadowedText(tgt:Nick(), "TimeLeft", ScrW() / 2, margin, COLOR_WHITE, TEXT_ALIGN_CENTER)
|
||
|
|
|
||
|
|
elseif IsValid(tgt) and tgt:GetNWEntity("spec_owner", nil) == client then
|
||
|
|
PunchPaint(client)
|
||
|
|
else
|
||
|
|
ShadowedText(interp(L.spec_help, key_params), "TabLarge", ScrW() / 2, margin, COLOR_WHITE, TEXT_ALIGN_CENTER)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local ttt_health_label = CreateClientConVar("ttt_health_label", "0", true)
|
||
|
|
|
||
|
|
local function InfoPaint(client)
|
||
|
|
local L = GetLang()
|
||
|
|
|
||
|
|
local width = 250
|
||
|
|
local height = 90
|
||
|
|
|
||
|
|
local x = margin
|
||
|
|
local y = ScrH() - margin - height
|
||
|
|
|
||
|
|
DrawBg(x, y, width, height, client)
|
||
|
|
|
||
|
|
local bar_height = 25
|
||
|
|
local bar_width = width - (margin*2)
|
||
|
|
|
||
|
|
-- Draw health
|
||
|
|
local health = math.max(0, client:Health())
|
||
|
|
local health_y = y + margin
|
||
|
|
|
||
|
|
PaintBar(x + margin, health_y, bar_width, bar_height, health_colors, health/client:GetMaxHealth())
|
||
|
|
|
||
|
|
ShadowedText(tostring(health), "HealthAmmo", bar_width, health_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT)
|
||
|
|
|
||
|
|
if ttt_health_label:GetBool() then
|
||
|
|
local health_status = util.HealthToString(health, client:GetMaxHealth())
|
||
|
|
draw.SimpleText(L[health_status], "TabLarge", x + margin*2, health_y + bar_height/2, COLOR_WHITE, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Draw ammo
|
||
|
|
if client:GetActiveWeapon().Primary then
|
||
|
|
local ammo_clip, ammo_max, ammo_inv = GetAmmo(client)
|
||
|
|
if ammo_clip != -1 then
|
||
|
|
local ammo_y = health_y + bar_height + margin
|
||
|
|
PaintBar(x+margin, ammo_y, bar_width, bar_height, ammo_colors, ammo_clip/ammo_max)
|
||
|
|
local text = string.format("%i + %02i", ammo_clip, ammo_inv)
|
||
|
|
|
||
|
|
ShadowedText(text, "HealthAmmo", bar_width, ammo_y, COLOR_WHITE, TEXT_ALIGN_RIGHT, TEXT_ALIGN_RIGHT)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Draw traitor state
|
||
|
|
local round_state = GAMEMODE.round_state
|
||
|
|
|
||
|
|
local traitor_y = y - 30
|
||
|
|
local text = nil
|
||
|
|
if round_state == ROUND_ACTIVE then
|
||
|
|
text = L[ client:GetRoleStringRaw() ]
|
||
|
|
else
|
||
|
|
text = L[ roundstate_string[round_state] ]
|
||
|
|
end
|
||
|
|
|
||
|
|
ShadowedText(text, "TraitorState", x + margin + 73, traitor_y, COLOR_WHITE, TEXT_ALIGN_CENTER)
|
||
|
|
|
||
|
|
-- Draw round time
|
||
|
|
local is_haste = HasteMode() and round_state == ROUND_ACTIVE
|
||
|
|
local is_traitor = client:IsActiveTraitor()
|
||
|
|
|
||
|
|
local endtime = GetGlobalFloat("ttt_round_end", 0) - CurTime()
|
||
|
|
|
||
|
|
local text
|
||
|
|
local font = "TimeLeft"
|
||
|
|
local color = COLOR_WHITE
|
||
|
|
local rx = x + margin + 170
|
||
|
|
local ry = traitor_y + 3
|
||
|
|
|
||
|
|
-- Time displays differently depending on whether haste mode is on,
|
||
|
|
-- whether the player is traitor or not, and whether it is overtime.
|
||
|
|
if is_haste then
|
||
|
|
local hastetime = GetGlobalFloat("ttt_haste_end", 0) - CurTime()
|
||
|
|
if hastetime < 0 then
|
||
|
|
if (not is_traitor) or (math.ceil(CurTime()) % 7 <= 2) then
|
||
|
|
-- innocent or blinking "overtime"
|
||
|
|
text = L.overtime
|
||
|
|
font = "Trebuchet18"
|
||
|
|
|
||
|
|
-- need to hack the position a little because of the font switch
|
||
|
|
ry = ry + 5
|
||
|
|
rx = rx - 3
|
||
|
|
else
|
||
|
|
-- traitor and not blinking "overtime" right now, so standard endtime display
|
||
|
|
text = util.SimpleTime(math.max(0, endtime), "%02i:%02i")
|
||
|
|
color = COLOR_RED
|
||
|
|
end
|
||
|
|
else
|
||
|
|
-- still in starting period
|
||
|
|
local t = hastetime
|
||
|
|
if is_traitor and math.ceil(CurTime()) % 6 < 2 then
|
||
|
|
t = endtime
|
||
|
|
color = COLOR_RED
|
||
|
|
end
|
||
|
|
text = util.SimpleTime(math.max(0, t), "%02i:%02i")
|
||
|
|
end
|
||
|
|
else
|
||
|
|
-- bog standard time when haste mode is off (or round not active)
|
||
|
|
text = util.SimpleTime(math.max(0, endtime), "%02i:%02i")
|
||
|
|
end
|
||
|
|
|
||
|
|
ShadowedText(text, font, rx, ry, color)
|
||
|
|
|
||
|
|
if is_haste then
|
||
|
|
dr.SimpleText(L.hastemode, "TabLarge", x + margin + 165, traitor_y - 8)
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Paints player status HUD element in the bottom left
|
||
|
|
function GM:HUDPaint()
|
||
|
|
local client = LocalPlayer()
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTTargetID" ) then
|
||
|
|
hook.Call( "HUDDrawTargetID", GAMEMODE )
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTMStack" ) then
|
||
|
|
MSTACK:Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if (not client:Alive()) or client:Team() == TEAM_SPEC then
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTSpecHUD" ) then
|
||
|
|
SpecHUDPaint(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTRadar" ) then
|
||
|
|
RADAR:Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTTButton" ) then
|
||
|
|
TBHUD:Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTWSwitch" ) then
|
||
|
|
WSWITCH:Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTVoice" ) then
|
||
|
|
VOICE.Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTDisguise" ) then
|
||
|
|
DISGUISE.Draw(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTPickupHistory" ) then
|
||
|
|
hook.Call( "HUDDrawPickupHistory", GAMEMODE )
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Draw bottom left info panel
|
||
|
|
if hook.Call( "HUDShouldDraw", GAMEMODE, "TTTInfoPanel" ) then
|
||
|
|
InfoPaint(client)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Hide the standard HUD stuff
|
||
|
|
local hud = {["CHudHealth"] = true, ["CHudBattery"] = true, ["CHudAmmo"] = true, ["CHudSecondaryAmmo"] = true}
|
||
|
|
function GM:HUDShouldDraw(name)
|
||
|
|
if hud[name] then return false end
|
||
|
|
|
||
|
|
return self.BaseClass.HUDShouldDraw(self, name)
|
||
|
|
end
|
||
|
|
|