zombiesurvival-evolved/gamemodes/zombiesurvival/gamemode/vgui/zshealtharea.lua
JetBoom aa08d47a35 Fixed health area size changing during crouch.
No longer bothering to update cam pos / look angles on model change.
Just do it every paint.
2014-11-08 22:49:03 -05:00

333 lines
9.2 KiB
Lua

local PANEL = {}
local colHealth = Color(0, 0, 0, 240)
local function ContentsPaint(self)
local lp = LocalPlayer()
if lp:IsValid() then
local health = math.max(lp:Health(), 0)
local healthperc = math.Clamp(health / lp:GetMaxHealthEx(), 0, 1)
colHealth.r = (1 - healthperc) * 180
colHealth.g = healthperc * 180
draw.SimpleTextBlurry(health, "ZSHUDFont", 8, self:GetTall() - 8, colHealth, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
end
end
function PANEL:Init()
self:DockMargin(0, 0, 0, 0)
self:DockPadding(0, 0, 0, 0)
self.HealthModel = vgui.Create("ZSHealthModelPanel", self)
self.HealthModel:Dock(LEFT)
local contents = vgui.Create("Panel", self)
contents:Dock(FILL)
contents.Paint = ContentsPaint
local poisonstatus = vgui.Create("ZSHealthStatus", contents)
poisonstatus:SetTall(20)
poisonstatus:SetAlpha(200)
poisonstatus:SetColor(Color(180, 180, 0))
poisonstatus:SetMemberName("POISON!")
poisonstatus.GetMemberValue = function(me)
local lp = LocalPlayer()
if lp:IsValid() then
return lp:GetPoisonDamage()
end
return 0
end
poisonstatus.MemberMaxValue = 50
poisonstatus:Dock(TOP)
local bleedstatus = vgui.Create("ZSHealthStatus", contents)
bleedstatus:SetTall(20)
bleedstatus:SetAlpha(200)
bleedstatus:SetColor(Color(220, 0, 0))
bleedstatus:SetMemberName("BLEED!")
bleedstatus.GetMemberValue = function(me)
local lp = LocalPlayer()
if lp:IsValid() then
return lp:GetBleedDamage()
end
return 0
end
bleedstatus.MemberMaxValue = 20
bleedstatus:Dock(TOP)
local ghoultouchstatus = vgui.Create("ZSHealthStatus", contents)
ghoultouchstatus:SetTall(20)
ghoultouchstatus:SetAlpha(200)
ghoultouchstatus:SetColor(Color(255, 0, 0))
ghoultouchstatus:SetMemberName("GHOUL TOUCH!")
ghoultouchstatus.GetMemberValue = function(me)
local lp = LocalPlayer()
if lp:IsValid() then
local status = lp:GetStatus("ghoultouch")
if status and status:IsValid() then
return math.max(status.DieTime - CurTime(), 0)
end
end
return 0
end
ghoultouchstatus.MemberMaxValue = 10
ghoultouchstatus:Dock(TOP)
self:ParentToHUD()
self:InvalidateLayout()
end
function PANEL:PerformLayout()
local screenscale = BetterScreenScale()
self:SetSize(screenscale * 350, screenscale * 128)
self.HealthModel:SetWide(self:GetTall())
self:AlignLeft(screenscale * 24)
self:AlignBottom(screenscale * 24)
end
function PANEL:Paint()
end
vgui.Register("ZSHealthArea", PANEL, "Panel")
local PANEL = {}
PANEL.ModelLow = 0
PANEL.ModelHigh = 72
PANEL.Health = 100
PANEL.BarricadeGhosting = 0
function PANEL:Init()
self:SetAnimSpeed(0)
self:SetFOV(55)
end
local function LowestAndHighest(ent)
local lowest
local highest
local basepos = ent:GetPos()
for i=0, ent:GetBoneCount() - 1 do
local bonepos, boneang = ent:GetBonePosition(i)
if bonepos and bonepos ~= basepos then
if lowest == nil then
lowest = bonepos.z
highest = bonepos.z
else
lowest = math.min(lowest, bonepos.z)
highest = math.max(highest, bonepos.z)
end
end
end
highest = (highest or 1) + ent:GetModelScale() * 8
return lowest or 0, highest
end
function PANEL:Think()
local lp = LocalPlayer()
if lp:IsValid() then
self.Health = math.Clamp(lp:Health() / lp:GetMaxHealthEx(), 0, 1)
self.BarricadeGhosting = math.Approach(self.BarricadeGhosting, lp:IsBarricadeGhosting() and 1 or 0, FrameTime() * 5)
local model = lp:GetModel()
local ent = self.Entity
if not ent or not ent:IsValid() or model ~= ent:GetModel() then
if IsValid(self.OverrideEntity) then
self.OverrideEntity:Remove()
self.OverrideEntity = nil
end
self:SetModel(model)
end
local overridemodel = lp.status_overridemodel
if overridemodel and overridemodel:IsValid() then
if IsValid(self.Entity) and not IsValid(self.OverrideEntity) then
self.OverrideEntity = ClientsideModel(overridemodel:GetModel(), RENDER_GROUP_OPAQUE_ENTITY)
if IsValid(self.OverrideEntity) then
self.OverrideEntity:SetPos(self.Entity:GetPos())
self.OverrideEntity:SetParent(self.Entity)
self.OverrideEntity:AddEffects(bit.bor(EF_BONEMERGE, EF_BONEMERGE_FASTCULL))
self.OverrideEntity:SetNoDraw(true)
end
end
elseif self.OverrideEntity and self.OverrideEntity:IsValid() then
self.OverrideEntity:Remove()
self.OverrideEntity = nil
end
ent = self.Entity
if ent and ent:IsValid() then
ent:SetSequence(lp:GetSequence())
ent:SetPoseParameter("move_x", lp:GetPoseParameter("move_x") * 2 - 1)
ent:SetPoseParameter("move_y", lp:GetPoseParameter("move_y") * 2 - 1)
ent:SetCycle(lp:GetCycle())
local modellow, modelhigh = LowestAndHighest(ent)
self.ModelLow = math.Approach(self.ModelLow, modellow, FrameTime() * 256)
self.ModelHigh = math.Approach(self.ModelHigh, modelhigh, FrameTime() * 256)
self.ModelHigh = math.max(self.ModelLow + 1, self.ModelHigh)
end
end
end
function PANEL:OnRemove()
if IsValid(self.Entity) then
self.Entity:Remove()
end
if IsValid(self.OverrideEntity) then
self.OverrideEntity:Remove()
end
end
local matWhite = Material("models/debug/debugwhite")
local matGlow = Material("sprites/glow04_noz")
local matShadow = CreateMaterial("zshealthhudshadow", "UnlitGeneric", {["$basetexture"] = "decals/simpleshadow", ["$vertexalpha"] = "1", ["$vertexcolor"] = "1"})
local colShadow = Color(20, 20, 20, 230)
function PANEL:Paint()
local ent = self.OverrideEntity or self.Entity
if not ent or not ent:IsValid() then return end
local lp = LocalPlayer()
if not lp:IsValid() then return end
local x, y = self:LocalToScreen(0, 0)
local w, h = self:GetSize()
local health = self.Health
local entpos = ent:GetPos()
local mins, maxs = lp:OBBMins(), lp:OBBMaxs()
maxs.z = maxs.x * 4.5
local campos = mins:Distance(maxs) * Vector(0, -0.9, 0.4)
local lookat = (mins + maxs) / 2
local ang = (lookat - campos):Angle()
local modelscale = lp:GetModelScale()
if ent:GetModelScale() ~= modelscale then
ent:SetModelScale(modelscale, 0)
end
self:LayoutEntity(ent)
render.ModelMaterialOverride(matWhite)
render.SuppressEngineLighting(true)
cam.IgnoreZ(true)
cam.Start3D(campos - ang:Forward() * 16, ang, self.fFOV * 0.75, x, y, w, h, 5, 4096)
render.OverrideDepthEnable(true, false)
render.SetColorModulation(0, 0, self.BarricadeGhosting)
ent:DrawModel()
render.OverrideDepthEnable(false)
cam.End3D()
cam.Start3D(campos, ang, self.fFOV, x, y, w, h, 5, 4096)
render.SetMaterial(matShadow)
render.DrawQuadEasy(entpos, Vector(0, 0, 1), 45, 90, colShadow)
render.SetLightingOrigin(entpos)
render.ResetModelLighting(0.2, 0.2, 0.2)
render.SetModelLighting(BOX_FRONT, 0.8, 0.8, 0.8)
render.SetModelLighting(BOX_TOP, 0.8, 0.8, 0.8)
if health == 1 then
render.SetColorModulation(0, 0.6, 0)
ent:DrawModel()
elseif health == 0 then
render.SetColorModulation(0, 0, 0)
ent:DrawModel()
else
local normal = Vector(0, 0, 1)
local pos = entpos + Vector(0, 0, self.ModelLow * (1 - health) + self.ModelHigh * health)
render.EnableClipping(true)
render.PushCustomClipPlane(normal, normal:Dot(pos))
render.SetColorModulation(health > 0.5 and 0.6 or (0.7 + math.sin(CurTime() * math.pi * 2) * 0.2), 0, 0)
ent:DrawModel()
render.PopCustomClipPlane()
normal = normal * -1
render.PushCustomClipPlane(normal, normal:Dot(pos))
render.SetColorModulation(0, 0.6, 0)
ent:DrawModel()
render.PopCustomClipPlane()
render.EnableClipping(false)
end
cam.End3D()
render.ModelMaterialOverride()
render.SuppressEngineLighting(false)
render.SetColorModulation(1, 1, 1)
cam.IgnoreZ(false)
end
function PANEL:LayoutEntity(ent)
self:RunAnimation()
end
vgui.Register("ZSHealthModelPanel", PANEL, "DModelPanel")
local PANEL = {}
PANEL.MemberValue = 0
PANEL.LerpMemberValue = 0
PANEL.MemberMaxValue = 100
PANEL.MemberName = "Unnamed"
function PANEL:SetColor(col) self.m_Color = col end
function PANEL:GetColor() return self.m_Color end
function PANEL:SetMemberName(n) self.MemberName = n end
function PANEL:GetMemberName() return self.MemberName end
function PANEL:Init()
self:SetColor(Color(255, 255, 255))
end
function PANEL:Think()
if self.GetMemberValue then
self.MemberValue = self:GetMemberValue() or self.MemberValue
end
if self.GetMemberMaxValue then
self.MemberMaxValue = self:GetMemberMaxValue() or self.MemberMaxValue
end
if self.MemberValue > self.LerpMemberValue then
self.LerpMemberValue = self.MemberValue
elseif self.MemberValue < self.LerpMemberValue then
self.LerpMemberValue = math.Approach(self.LerpMemberValue, self.MemberValue, FrameTime() * 10)
end
end
function PANEL:Paint()
local value = self.LerpMemberValue
if value <= 0 then return end
local col = self:GetColor()
local max = self.MemberMaxValue
local w, h = self:GetSize()
surface.SetDrawColor(0, 0, 0, 255)
surface.DrawRect(0, 0, w, h)
surface.SetDrawColor(col)
surface.DrawOutlinedRect(0, 0, w, h)
surface.DrawRect(3, 3, (w - 6) * math.Clamp(value / max, 0, 1), h - 6)
local t1 = math.ceil(value)
draw.SimpleText(t1, "ZSHUDFontTinyNS", w - 3, h / 2 + 1, color_black, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
draw.SimpleText(t1, "ZSHUDFontTinyNS", w - 4, h / 2, color_white, TEXT_ALIGN_RIGHT, TEXT_ALIGN_CENTER)
draw.SimpleText(self.MemberName, "ZSHUDFontTinyNS", 5, h / 2 + 1, color_black, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
draw.SimpleText(self.MemberName, "ZSHUDFontTinyNS", 4, h / 2, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
end
vgui.Register("ZSHealthStatus", PANEL, "Panel")