aboutsummaryrefslogtreecommitdiff
path: root/gamemode/client/hud/cl_healthbar.lua
blob: 2705a42a0231d1039b190348fd0b16b19faeb8c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
hook.Add("HUDShouldDraw", "HideHUD", function(name)
	if name == "CHudHealth" then return false end
end)

--[[
--A function that rotates a point around another point
local function rotatepoint(x, y, cx, cy, rot)
	rot = math.rad(rot)
	local cs, sn = math.cos(rot), math.sin(rot)
	local px = x * cs - y * sn
	local py = x * sn + y * cs

	return px, py
end
]]

--Add a function to the draw library to draw elipses for blood
local segments = 20
local fade = 0.5

function draw.DrawElipse(x, y, radius, elong, rotation)
	rotation = math.rad(rotation)
	local cir = {}

	table.insert(cir, {
		x = x,
		y = y,
		u = fade,
		v = fade
	})

	for i = 0, segments do
		local a = math.rad((i / segments) * -360)
		local xu, yu = math.sin(a), math.cos(a)
		local xpos = xu * radius * elong
		local ypos = yu * radius
		local cs, sn = math.cos(rotation), math.sin(rotation)
		xpos, ypos = xpos * cs - ypos * sn, xpos * sn + ypos * cs

		table.insert(cir, {
			x = x + xpos,
			y = y + ypos,
			u = 1,
			v = 1
		})
	end

	surface.DrawPoly(cir)
end

local width, height = ScrW(), ScrH()
local padding = height / 32
local barheight = height / 16
local bubbles = {}
local blobs = {}
local bubbleradius = height / 64
local delpoint = height

hook.Add("Tick", "Hudpaintbloodtick", function()
	for k, v in pairs(blobs) do
		if v.y > delpoint then
			blobs[k] = nil
		else
			blobs[k] = {
				["x"] = v.x + v.xv,
				["y"] = v.y + v.yv,
				["xv"] = v.xv,
				["yv"] = v.yv + 1
			}
		end
	end

	for k, v in pairs(bubbles) do
		if v.y < height - padding - barheight - bubbleradius then
			bubbles[k] = nil
		else
			local subheight = v.y - (1.5 + math.sin((v.y / 4) + (v.x * 10))) / 5
			bubbles[k].y = subheight
		end
	end
end)

local lasthealth
local obarlength = width / 4
local barlength = obarlength
local xs, ys = padding, height - padding - barheight
local bubblespawnrate, bubblespawnchance = 1, 0.7

timer.Create("Healthbar_bubble_timer", bubblespawnrate, 0, function()
	if math.random() < bubblespawnchance then
		local newbubble = {
			["x"] = math.random(xs + bubbleradius, barlength - bubbleradius),
			["y"] = height - padding + bubbleradius
		}

		table.insert(bubbles, newbubble)
	end
end)

hook.Add("HUDPaint", "HUD_DrawHealth", function()
	--Spawn a bunch of blobs if our health has changed
	local health = LocalPlayer():Health()

	if lasthealth == nil then
		lasthealth = health
	end

	if health ~= lasthealth then
		local difference = lasthealth - health
		barlength = obarlength * (health / 100)

		for i = 0, difference * 3 do
			local rtime = math.random()

			timer.Simple(rtime, function()
				local yvel = -20 + math.random(10)
				local xvel = math.random() * 5
				local xpos = padding + xs + barlength - difference - 5
				local ypos = ys + (math.random() * barheight)

				table.insert(blobs, {
					x = xpos,
					y = ypos,
					xv = xvel,
					yv = yvel
				})
			end)
		end

		lasthealth = health
	end

	--Draw the current health thing
	--Background
	surface.SetDrawColor(100, 100, 100, 100)
	surface.DrawRect(xs, ys, obarlength, barheight)
	--Foreground
	surface.SetDrawColor(150, 0, 0, 255)
	surface.DrawRect(xs, ys, barlength, barheight)
	--Heighlighting/shadows
	surface.SetTexture( surface.GetTextureID("gui/gradient.vtf") )
	surface.SetDrawColor( 0, 0, 0, 255 )
	surface.DrawTexturedRectRotated( xs + (barlength/2), ys + (barheight/4) * 3, barheight/2, barlength,90)
	surface.SetDrawColor( 255, 255, 255, 50 )
	surface.DrawTexturedRectRotated( xs + (barlength/2), ys + (barheight/8), barheight/4, barlength,270)

	--Draw bubbles
	render.SetScissorRect(xs, ys, xs + barlength, ys + barheight, true) -- Enable the rect
	surface.SetDrawColor(250, 150, 150, 10)

	for k, v in pairs(bubbles) do
		if k > 50 then break end
		surface.DrawCircle(v.x, v.y, bubbleradius, 250, 150, 150, 30)
		draw.DrawElipse(v.x, v.y, bubbleradius, 1, 0)
	end

	render.SetScissorRect(0, 0, 0, 0, false) -- Disable after you are done
	--Draw the animation for blobs
	surface.SetDrawColor(150, 0, 0, 255)

	for k, v in pairs(blobs) do
		--Elongation is based on velocity
		local elong = (v.yv ^ 2 + v.xv ^ 2) ^ 0.5
		elong = elong / 5
		elong = math.Clamp(elong, 1, 3)
		--Rotation is also based on velcotiy
		local rot = math.deg(math.atan(v.yv / v.xv))
		draw.DrawElipse(v.x, v.y, 10 / elong, elong, rot)
	end
end)