Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
shownames.qc
Go to the documentation of this file.
1#include "shownames.qh"
2
3#include <client/draw.qh>
4#include <client/hud/_mod.qh>
5#include <client/view.qh>
6#include <common/constants.qh>
7#include <common/ent_cs.qh>
10#include <common/teams.qh>
12
13// this.isactive = player is in range and coordinates/status (health and armor) are up to date
14// this.origin = player origin
15// this.healthvalue
16// this.armorvalue
17// this.sameteam = player is on same team as local client
18// this.fadedelay = time to wait before name tag starts fading in for enemies
19// this.pointtime = last time you pointed at this player
20// this.csqcmodel_isdead = value of csqcmodel_isdead to know when the player is dead or not
21
24{
26 for (int i = 0; i < maxclients; ++i)
27 {
28 entity e = new_pure(shownames_tag);
29 e.sv_entnum = i + 1;
31 }
32}
33
34// used by the antioverlap code
35.vector box_ofs;
36.vector box_org;
37
38const float SHOWNAMES_FADESPEED = 4;
39const float SHOWNAMES_FADEDELAY = 0;
41{
42 if (this.sv_entnum == current_player + 1) // self or spectatee
43 {
45 return;
46
49 {
50 return;
51 }
52 }
53
54 if (!this.sameteam && !autocvar_hud_shownames_enemies) return;
55 bool hit;
56 if (!autocvar_hud_shownames_crosshairdistance && this.sameteam)
57 {
58 hit = true;
59 }
60 else
61 {
62 traceline(view_origin, this.origin, MOVE_NOMONSTERS, this);
63 hit = !(trace_fraction < 1 && (trace_networkentity != this.sv_entnum && trace_ent.entnum != this.sv_entnum));
64 }
65 // handle tag fading
66 int overlap = -1;
69 {
71 float w = o.x - vid_conwidth / 2;
72 float h = o.y - vid_conheight / 2;
73 if (d * d > w * w + h * h) this.pointtime = time;
75 overlap = 1;
77 overlap = 0;
78 }
79
80 // o.z is < 0 when o is behind me
81 #define OFF_SCREEN(o) (o.z < 0 || o.x < 0 || o.y < 0 || o.x > vid_conwidth || o.y > vid_conheight)
82 if (overlap == -1 && autocvar_hud_shownames_antioverlap)
83 {
84 // fade tag out if another tag that is closer to you overlaps
86 LL_EACH(shownames_ent, it != this, {
88 if (!(entcs && entcs.has_origin))
89 continue;
91 if (OFF_SCREEN(eo)) continue;
92 eo.z = 0;
93 if (boxesoverlap(this.box_org - this.box_ofs, this.box_org + this.box_ofs, it.box_org - it.box_ofs, it.box_org + it.box_ofs)
94 && vlen2(it.origin - view_origin) < vlen2(this.origin - view_origin))
95 {
96 overlap = 1;
97 break;
98 }
99 });
100 }
101 if (!this.fadedelay) this.fadedelay = time + SHOWNAMES_FADEDELAY;
102 if (this.csqcmodel_isdead) // dead player, fade out slowly
103 {
104 this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * 0.25 * frametime);
105 }
106 else if (!this.sameteam && !hit) // view blocked, fade out
107 {
108 this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
109 this.fadedelay = 0; // reset fade in delay, enemy has left the view
110 }
111 else if (OFF_SCREEN(o)) // out of view, fade out
112 {
113 this.alpha = max(0, this.alpha - SHOWNAMES_FADESPEED * frametime);
114 }
115 else if (overlap > 0) // tag overlap detected, fade out
116 {
118 if (this.alpha >= minalpha)
119 this.alpha = max(minalpha, this.alpha - SHOWNAMES_FADESPEED * frametime);
120 else
121 this.alpha = min(minalpha, this.alpha + SHOWNAMES_FADESPEED * frametime);
122 }
123 else if (this.sameteam) // fade in for teammates
124 {
125 this.alpha = min(1, this.alpha + SHOWNAMES_FADESPEED * frametime);
126 }
127 else if (time > this.fadedelay || this.alpha > 0) // fade in for enemies
128 {
129 this.alpha = min(1, this.alpha + SHOWNAMES_FADESPEED * frametime);
130 }
131 float a = autocvar_hud_shownames_alpha * this.alpha;
132 if (!this.sameteam || (this.sv_entnum == player_localentnum))
133 {
134 float f = entcs_GetAlpha(this.sv_entnum - 1);
135 if (f == 0) f = 1;
136 if (f < 0) f = 0;
137 a *= f;
138 }
139 if (MUTATOR_CALLHOOK(ShowNames_Draw, this, a)) return;
140 a = M_ARGV(1, float);
141
142 if (a < ALPHA_MIN_VISIBLE) return;
143
144 float dist = -1; // dist will be calculated only when really needed to avoid wasting a vlen call
146 {
148 if (vdist(this.origin - view_origin, >=, max_dist))
149 return;
151 {
153 if (dist == -1)
154 dist = vlen(this.origin - view_origin);
155 a *= (f - max(0, dist - autocvar_hud_shownames_mindistance)) / f;
156 }
157 }
158 else if (vdist(this.origin - view_origin, >=, max_shot_distance))
159 return;
160 if (!a || o.z < 0) return;
161
162 o.z = 0;
163 float resize = 1;
165 {
166 // limit resize so its never smaller than 0.5... gets unreadable
168 if (dist == -1)
169 dist = vlen(this.origin - view_origin);
170 resize = 0.5 + 0.5 * (f - max(0, dist - autocvar_hud_shownames_mindistance)) / f;
171 }
173 vector myPos = o - vec2(0.5 * mySize.x, mySize.y);
174 mySize.x *= resize;
175 mySize.y *= resize;
176 myPos.x += 0.5 * (mySize.x / resize - mySize.x);
177 myPos.y += (mySize.y / resize - mySize.y);
178
179 this.box_org = myPos + mySize / 2;
180 this.box_ofs = mySize / 2;
181
182 float namewidth = mySize.x;
183 if (autocvar_hud_shownames_status && this.sameteam && !this.csqcmodel_isdead)
184 {
185 vector pos = myPos + eY * autocvar_hud_shownames_fontsize * resize;
186 vector sz = vec2(0.5 * mySize.x, resize * autocvar_hud_shownames_statusbar_height);
187
188 this.box_ofs.x = max(mySize.x / 2, sz.x); // sz.x is already half as wide
189 this.box_ofs.y += sz.y / 2;
190 this.box_org.y = myPos.y + (mySize.y + sz.y) / 2;
191 // antioverlap debug code
192 //drawfill(this.box_org - this.box_ofs, this.box_ofs * 2, '1 1 1', a / 2, DRAWFLAG_NORMAL);
193
195 drawfill(pos + eX * 0.25 * mySize.x, sz, '0.7 0.7 0.7', a / 2, DRAWFLAG_NORMAL);
196 if (this.healthvalue > 0)
197 {
198 HUD_Panel_DrawProgressBar(pos, sz, "nametag_statusbar",
199 this.healthvalue / autocvar_hud_panel_healtharmor_maxhealth, false, 1, '1 0 0', a,
201 }
202 if (GetResource(this, RES_ARMOR) > 0)
203 {
204 HUD_Panel_DrawProgressBar(pos + eX * 0.5 * mySize.x, sz, "nametag_statusbar",
207 }
208 }
209 // antioverlap debug code
210 //else drawfill(this.box_org - this.box_ofs, this.box_ofs * 2, '1 1 1', a / 2, DRAWFLAG_NORMAL);
211
212 string s = entcs_GetName(this.sv_entnum - 1);
214 s = playername(s, entcs_GetTeam(this.sv_entnum - 1), true);
215 drawfontscale = '1 1 0' * resize;
217 float width = stringwidth(s, true, '1 1 0' * autocvar_hud_shownames_fontsize);
218 myPos.x = o.x - (width * resize) / 2;
220 drawfontscale = '1 1 0';
221}
222
224{
225 if (!autocvar_hud_shownames) return;
226 LL_EACH(shownames_ent, true, {
228 if (!entcs)
229 {
230 make_pure(it);
231 continue;
232 }
233 make_impure(it);
236 if (!entcs.has_origin) continue;
237 if (entcs.m_entcs_private)
238 {
239 it.healthvalue = entcs.healthvalue;
241 it.sameteam = true;
242 }
243 else
244 {
245 it.healthvalue = 0;
247 it.sameteam = false;
248 }
249 bool dead = entcs_IsDead(i) || entcs_IsSpectating(i);
250 if ((!it.csqcmodel_isdead || it.alpha > 0) && entcs.origin != it.origin)
251 setorigin(it, entcs.origin);
252 it.csqcmodel_isdead = dead;
253 Draw_ShowNames(it);
254 });
255}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float GetResource(entity e, Resource res_type)
Returns the current amount of resource the given entity has.
bool SetResourceExplicit(entity e, Resource res_type, float amount)
Sets the resource amount of an entity without calling any hooks.
Header file that describes the resource system.
#define drawcolorcodedstring(position, text, scale, alpha, flag)
Definition draw.qh:30
vector drawfontscale
Definition draw.qh:3
#define drawfill(position, size, rgb, alpha, flag)
Definition draw.qh:36
float alpha
Definition items.qc:13
float pointtime
Definition items.qc:17
float spectatee_status_changed_time
Definition main.qh:198
vector view_origin
Definition main.qh:109
const float ALPHA_MIN_VISIBLE
Definition main.qh:158
int spectatee_status
the -1 disables HUD panels before CSQC receives necessary data
Definition main.qh:197
int sv_entnum
Definition main.qh:186
#define M_ARGV(x, type)
Definition events.qh:17
string playername(string thename, int teamid, bool team_colorize)
Definition util.qc:2082
string textShortenToWidth(string theText, float maxWidth, vector theFontSize, textLengthUpToWidth_widthFunction_t tw)
Definition util.qc:1071
const float DRAWFLAG_NORMAL
const float MOVE_NOMONSTERS
float maxclients
entity trace_ent
float frametime
float time
float trace_networkentity
float player_localentnum
vector origin
float trace_fraction
#define stringwidth
bool csqcmodel_isdead
RES_ARMOR
Definition ent_cs.qc:130
bool entcs_IsDead(int i)
Definition ent_cs.qh:190
float entcs_GetAlpha(int i)
Definition ent_cs.qh:167
string entcs_GetName(int i)
Definition ent_cs.qh:151
#define entcs_receiver(...)
Definition ent_cs.qh:65
int entcs_GetTeam(int i)
Definition ent_cs.qh:133
#define entcs_IsSpectating(i)
Definition ent_cs.qh:76
entity entcs
Definition ent_cs.qh:34
int autocvar_hud_panel_healtharmor_maxhealth
int autocvar_hud_panel_healtharmor_maxarmor
void HUD_Panel_DrawProgressBar(vector theOrigin, vector theSize, string pic, float length_ratio, bool vertical, float baralign, vector theColor, float theAlpha, int drawflag)
Definition hud.qc:269
float current_player
Definition hud.qh:185
noref float vid_conwidth
Definition draw.qh:8
noref float vid_conheight
Definition draw.qh:9
#define LL_NEW()
Definition linkedlist.qh:14
#define LL_EACH(list, cond, body)
Definition linkedlist.qh:73
entity LL_PUSH(LinkedList this, entity e)
Push to tail.
Definition linkedlist.qh:21
#define assert(expr,...)
Definition log.qh:8
float vlen(vector v)
float min(float f,...)
void eprint(entity e)
float max(float f,...)
#define make_impure(e)
Definition oo.qh:22
#define make_pure(e)
direct use is
Definition oo.qh:13
#define new_pure(class)
purely logical entities (not linked to the area grid)
Definition oo.qh:67
#define NULL
Definition post.qh:14
#define getthink(e)
vector
Definition self.qh:92
LinkedList shownames_ent
Definition shownames.qc:22
const float SHOWNAMES_FADEDELAY
Definition shownames.qc:39
const float SHOWNAMES_FADESPEED
Definition shownames.qc:38
void Draw_ShowNames_All()
Definition shownames.qc:223
vector box_ofs
Definition shownames.qc:35
vector box_org
Definition shownames.qc:36
void Draw_ShowNames(entity this)
Definition shownames.qc:40
#define OFF_SCREEN(o)
bool autocvar_hud_shownames
Definition shownames.qh:3
bool autocvar_hud_shownames_self
Definition shownames.qh:8
bool autocvar_hud_shownames_status
Definition shownames.qh:9
float autocvar_hud_shownames_alpha
Definition shownames.qh:15
float autocvar_hud_shownames_crosshairdistance_time
Definition shownames.qh:6
float autocvar_hud_shownames_crosshairdistance
Definition shownames.qh:5
int autocvar_hud_shownames_decolorize
Definition shownames.qh:14
float autocvar_hud_shownames_fontsize
Definition shownames.qh:13
float autocvar_hud_shownames_statusbar_height
Definition shownames.qh:10
float autocvar_hud_shownames_mindistance
Definition shownames.qh:17
float autocvar_hud_shownames_crosshairdistance_antioverlap
Definition shownames.qh:7
bool autocvar_hud_shownames_resize
Definition shownames.qh:16
float autocvar_hud_shownames_statusbar_highlight
Definition shownames.qh:11
bool autocvar_hud_shownames_antioverlap
Definition shownames.qh:19
float autocvar_hud_shownames_offset
Definition shownames.qh:21
float autocvar_hud_shownames_aspect
Definition shownames.qh:12
float autocvar_hud_shownames_maxdistance
Definition shownames.qh:18
float autocvar_hud_shownames_antioverlap_minalpha
Definition shownames.qh:20
bool autocvar_hud_shownames_enemies
Definition shownames.qh:4
#define STATIC_INIT(func)
during worldspawn
Definition static.qh:32
float stringwidth_colors(string s, vector theSize)
Definition string.qh:30
bool teamplay
Definition teams.qh:59
#define vlen2(v)
Definition vector.qh:4
const vector eY
Definition vector.qh:45
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt()
Definition vector.qh:8
const vector eZ
Definition vector.qh:46
ERASEABLE float boxesoverlap(vector m1, vector m2, vector m3, vector m4)
requires that m2>m1 in all coordinates, and that m4>m3
Definition vector.qh:73
const vector eX
Definition vector.qh:44
#define vec2(...)
Definition vector.qh:90
vector project_3d_to_2d(vector vec)
Definition view.qc:373
int autocvar_chase_active
Definition view.qh:17
int max_shot_distance
Definition weapon.qh:203