1 float waypointsprite_initialized;
2 float waypointsprite_fadedistance;
3 float waypointsprite_normdistance;
4 float waypointsprite_minscale;
5 float waypointsprite_minalpha;
6 float waypointsprite_distancealphaexponent;
7 float waypointsprite_timealphaexponent;
8 float waypointsprite_scale;
9 float waypointsprite_edgefadealpha;
10 float waypointsprite_edgefadescale;
11 float waypointsprite_edgefadedistance;
12 float waypointsprite_edgeoffset_bottom;
13 float waypointsprite_edgeoffset_left;
14 float waypointsprite_edgeoffset_right;
15 float waypointsprite_edgeoffset_top;
16 float waypointsprite_crosshairfadealpha;
17 float waypointsprite_crosshairfadescale;
18 float waypointsprite_crosshairfadedistance;
19 float waypointsprite_distancefadealpha;
20 float waypointsprite_distancefadescale;
21 float waypointsprite_distancefadedistance;
22 float waypointsprite_alpha;
25 .string netname; // primary picture
26 .string netname2; // secondary picture
27 .string netname3; // tertiary picture
28 .float team; // team that gets netname2
36 .float build_starthealth;
37 .float build_finished;
39 vector SPRITE_SIZE = '288 36 0';
40 vector SPRITE_HOTSPOT = '144 36 0';
41 float SPRITE_HEALTHBAR_WIDTH = 144;
42 float SPRITE_HEALTHBAR_HEIGHT = 9;
43 float SPRITE_HEALTHBAR_MARGIN = 6;
44 float SPRITE_HEALTHBAR_BORDER = 2;
45 float SPRITE_HEALTHBAR_BORDERALPHA = 1;
46 float SPRITE_HEALTHBAR_HEALTHALPHA = 0.5;
48 void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)
50 vector v1, v2, v3, v4;
52 hotspot = -1 * hotspot;
54 // hotspot-relative coordinates of the corners
56 v2 = hotspot + '1 0 0' * sz_x;
57 v3 = hotspot + '1 0 0' * sz_x + '0 1 0' * sz_y;
58 v4 = hotspot + '0 1 0' * sz_y;
60 // rotate them, and make them absolute
61 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
62 v1 = rotate(v1, rot) + org;
63 v2 = rotate(v2, rot) + org;
64 v3 = rotate(v3, rot) + org;
65 v4 = rotate(v4, rot) + org;
68 R_BeginPolygon(pic, f);
69 R_PolygonVertex(v1, '0 0 0', rgb, a);
70 R_PolygonVertex(v2, '1 0 0', rgb, a);
71 R_PolygonVertex(v3, '1 1 0', rgb, a);
72 R_PolygonVertex(v4, '0 1 0', rgb, a);
76 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
78 R_BeginPolygon(pic, f);
79 R_PolygonVertex(o, '0 0 0', rgb, a);
80 R_PolygonVertex(o + ri, '1 0 0', rgb, a);
81 R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
82 R_PolygonVertex(o + up, '0 1 0', rgb, a);
86 void drawhealthbar(vector org, float rot, float h, vector sz, vector hotspot, float width, float height, float margin, float border, float align, vector rgb, float a, vector hrgb, float ha, float f)
89 float owidth; // outer width
91 hotspot = -1 * hotspot;
93 // hotspot-relative coordinates of the healthbar corners
98 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
99 o = rotate(o, rot) + org;
100 ri = rotate(ri, rot);
101 up = rotate(up, rot);
103 owidth = width + 2 * border;
104 o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
106 drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
107 drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
108 drawquad(o, ri * border, up * height, "", rgb, a, f);
109 drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
110 drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
113 void Draw_WaypointSprite()
119 self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
123 if(self.hideflags & 2)
124 return; // radar only
126 if(autocvar_cl_hidewaypoints >= 2)
129 if(self.hideflags & 1)
130 if(autocvar_cl_hidewaypoints)
131 return; // fixed waypoint
133 InterpolateOrigin_Do();
135 t = GetPlayerColor(player_localentnum - 1) + 1;
142 case SPRITERULE_DEFAULT:
146 spriteimage = self.netname;
151 spriteimage = self.netname;
153 case SPRITERULE_TEAMPLAY:
154 if(t == COLOR_SPECTATOR + 1)
155 spriteimage = self.netname3;
156 else if(self.team == t)
157 spriteimage = self.netname2;
159 spriteimage = self.netname;
162 error("Invalid waypointsprite rule!");
166 if(spriteimage == "")
170 dist = vlen(self.origin - view_origin);
173 a = self.alpha * autocvar_hud_panel_fg_alpha;
175 if(self.maxdistance > waypointsprite_normdistance)
176 a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
177 else if(self.maxdistance > 0)
178 a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
183 // draw the sprite image
186 o = project_3d_to_2d(self.origin);
190 || o_x < (vid_conwidth * waypointsprite_edgeoffset_left)
191 || o_y < (vid_conheight * waypointsprite_edgeoffset_top)
192 || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_right))
193 || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_bottom)))
195 // scale it to be just in view
199 // get the waypoint angle vector
201 d_x = view_right * (self.origin - view_origin) * vid_conwidth / vid_width;
202 d_y = -view_up * (self.origin - view_origin) * vid_conheight / (vid_height * vid_pixelheight);
206 d = o - '0.5 0 0' * vid_conwidth - '0 0.5 0' * vid_conheight;
209 if(autocvar_v_flipped)
213 f1 = d_x / vid_conwidth;
214 f2 = d_y / vid_conheight;
216 if(max(f1, -f1) > max(f2, -f2))
221 d = d * ((0.5 - waypointsprite_edgeoffset_right) / f1);
227 d = d * (-(0.5 - waypointsprite_edgeoffset_left) / f1);
236 d = d * ((0.5 - waypointsprite_edgeoffset_bottom) / f2);
242 d = d * (-(0.5 - waypointsprite_edgeoffset_top) / f2);
247 o = d + '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
252 vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
254 t = stof(db_get(tempdb, strcat("/spriteframes/", spriteimage)));
256 spriteimage = strcat("models/sprites/", spriteimage);
258 spriteimage = strcat("models/sprites/", spriteimage, "_frame", ftos(mod(floor((max(0, time - self.spawntime)) * 2), t)));
260 float edgedistance_min, crosshairdistance;
261 edgedistance_min = min4(o_y, // todo: FIGURE THIS SHIT OUT
264 vid_conheight - o_y);
266 crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
268 t = waypointsprite_scale * vidscale;
269 a *= waypointsprite_alpha;
272 a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
273 t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
275 if (edgedistance_min < waypointsprite_edgefadedistance) {
276 a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
277 t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
279 if(crosshairdistance < waypointsprite_crosshairfadedistance) {
280 a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
281 t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
283 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * t, SPRITE_HOTSPOT * t, '1 1 1', a, DRAWFLAG_MIPMAP);
285 if(self.build_finished)
287 if(time < self.build_finished + 0.25)
289 if(time < self.build_started)
290 self.health = self.build_starthealth;
291 else if(time < self.build_finished)
292 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
303 if(self.build_finished)
307 drawhealthbar(o, rot * 90 * DEG2RAD, self.health, SPRITE_SIZE * t, SPRITE_HOTSPOT * t, SPRITE_HEALTHBAR_WIDTH * t, SPRITE_HEALTHBAR_HEIGHT * t, SPRITE_HEALTHBAR_MARGIN * t, SPRITE_HEALTHBAR_BORDER * t, align, self.teamradar_color, a * SPRITE_HEALTHBAR_BORDERALPHA, self.teamradar_color, a * SPRITE_HEALTHBAR_HEALTHALPHA, DRAWFLAG_NORMAL);
311 void Ent_RemoveWaypointSprite()
314 strunzone(self.netname);
316 strunzone(self.netname2);
318 strunzone(self.netname3);
321 void Ent_WaypointSprite()
323 float sendflags, f, t;
324 sendflags = ReadByte();
327 self.spawntime = time;
329 self.draw2d = Draw_WaypointSprite;
331 InterpolateOrigin_Undo();
338 self.health = t / 191.0;
339 self.build_finished = 0;
343 t = (t - 192) * 256 + ReadByte();
344 self.build_started = servertime;
345 if(self.build_finished)
346 self.build_starthealth = bound(0, self.health, 1);
348 self.build_starthealth = 0;
349 self.build_finished = servertime + t / 32;
355 self.build_finished = 0;
360 // unfortunately, this needs to be exact (for the 3D display)
361 self.origin_x = ReadCoord();
362 self.origin_y = ReadCoord();
363 self.origin_z = ReadCoord();
368 self.team = ReadByte();
369 self.rule = ReadByte();
375 strunzone(self.netname);
376 self.netname = strzone(ReadString());
382 strunzone(self.netname2);
383 self.netname2 = strzone(ReadString());
389 strunzone(self.netname3);
390 self.netname3 = strzone(ReadString());
395 self.lifetime = ReadCoord();
396 self.fadetime = ReadCoord();
397 self.maxdistance = ReadShort();
398 self.hideflags = ReadByte();
404 self.teamradar_icon = (f & 0x7F);
407 self.(teamradar_times[self.teamradar_time_index]) = time;
408 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
410 self.teamradar_color_x = ReadByte() / 255.0;
411 self.teamradar_color_y = ReadByte() / 255.0;
412 self.teamradar_color_z = ReadByte() / 255.0;
415 InterpolateOrigin_Note();
417 self.entremove = Ent_RemoveWaypointSprite;
420 void WaypointSprite_Load()
422 waypointsprite_fadedistance = vlen(mi_scale);
423 waypointsprite_normdistance = autocvar_g_waypointsprite_normdistance;
424 waypointsprite_minscale = autocvar_g_waypointsprite_minscale;
425 waypointsprite_minalpha = autocvar_g_waypointsprite_minalpha;
426 waypointsprite_distancealphaexponent = autocvar_g_waypointsprite_distancealphaexponent;
427 waypointsprite_timealphaexponent = autocvar_g_waypointsprite_timealphaexponent;
428 waypointsprite_scale = autocvar_g_waypointsprite_scale;
429 waypointsprite_edgefadealpha = autocvar_g_waypointsprite_edgefadealpha;
430 waypointsprite_edgefadescale = autocvar_g_waypointsprite_edgefadescale;
431 waypointsprite_edgefadedistance = autocvar_g_waypointsprite_edgefadedistance;
432 waypointsprite_edgeoffset_bottom = autocvar_g_waypointsprite_edgeoffset_bottom;
433 waypointsprite_edgeoffset_left = autocvar_g_waypointsprite_edgeoffset_left;
434 waypointsprite_edgeoffset_right = autocvar_g_waypointsprite_edgeoffset_right;
435 waypointsprite_edgeoffset_top = autocvar_g_waypointsprite_edgeoffset_top;
436 waypointsprite_crosshairfadealpha = autocvar_g_waypointsprite_crosshairfadealpha;
437 waypointsprite_crosshairfadescale = autocvar_g_waypointsprite_crosshairfadescale;
438 waypointsprite_crosshairfadedistance = autocvar_g_waypointsprite_crosshairfadedistance;
439 waypointsprite_distancefadealpha = autocvar_g_waypointsprite_distancefadealpha;
440 waypointsprite_distancefadescale = autocvar_g_waypointsprite_distancefadescale;
441 waypointsprite_distancefadedistance = waypointsprite_fadedistance * autocvar_g_waypointsprite_distancefadedistancemultiplier;
442 waypointsprite_alpha = autocvar_g_waypointsprite_alpha * (1 - autocvar__menu_alpha);
444 if(!waypointsprite_initialized)
446 float dh, n, i, o, f;
447 string s, sname, sframes;
449 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
450 n = search_getsize(dh);
451 for(i = 0; i < n; ++i)
453 s = search_getfilename(dh, i);
454 s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .tga
456 o = strstrofs(s, "_frame", 0);
457 sname = strcat("/spriteframes/", substring(s, 0, o));
458 sframes = substring(s, o + 6, strlen(s) - o - 6);
459 f = stof(sframes) + 1;
460 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
464 dh = search_begin("models/sprites/*_frame*.jpg", FALSE, FALSE);
465 n = search_getsize(dh);
466 for(i = 0; i < n; ++i)
468 s = search_getfilename(dh, i);
469 s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .jpg
471 o = strstrofs(s, "_frame", 0);
472 sname = strcat("/spriteframes/", substring(s, 0, o));
473 sframes = substring(s, o + 6, strlen(s) - o - 6);
474 f = stof(sframes) + 1;
475 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
478 waypointsprite_initialized = true;