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_crosshairfadealpha;
13 float waypointsprite_crosshairfadescale;
14 float waypointsprite_crosshairfadedistance;
15 float waypointsprite_distancefadealpha;
16 float waypointsprite_distancefadescale;
17 float waypointsprite_distancefadedistance;
18 float waypointsprite_alpha;
21 .string netname; // primary picture
22 .string netname2; // secondary picture
23 .string netname3; // tertiary picture
24 .float team; // team that gets netname2
32 .float build_starthealth;
33 .float build_finished;
35 vector SPRITE_SIZE = '288 36 0';
36 vector SPRITE_HOTSPOT = '144 36 0';
37 float SPRITE_HEALTHBAR_WIDTH = 144;
38 float SPRITE_HEALTHBAR_HEIGHT = 9;
39 float SPRITE_HEALTHBAR_MARGIN = 6;
40 float SPRITE_HEALTHBAR_BORDER = 2;
41 float SPRITE_HEALTHBAR_BORDERALPHA = 1;
42 float SPRITE_HEALTHBAR_HEALTHALPHA = 0.5;
44 void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)
46 vector v1, v2, v3, v4;
48 hotspot = -1 * hotspot;
50 // hotspot-relative coordinates of the corners
52 v2 = hotspot + '1 0 0' * sz_x;
53 v3 = hotspot + '1 0 0' * sz_x + '0 1 0' * sz_y;
54 v4 = hotspot + '0 1 0' * sz_y;
56 // rotate them, and make them absolute
57 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
58 v1 = rotate(v1, rot) + org;
59 v2 = rotate(v2, rot) + org;
60 v3 = rotate(v3, rot) + org;
61 v4 = rotate(v4, rot) + org;
64 R_BeginPolygon(pic, f);
65 R_PolygonVertex(v1, '0 0 0', rgb, a);
66 R_PolygonVertex(v2, '1 0 0', rgb, a);
67 R_PolygonVertex(v3, '1 1 0', rgb, a);
68 R_PolygonVertex(v4, '0 1 0', rgb, a);
72 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
74 R_BeginPolygon(pic, f);
75 R_PolygonVertex(o, '0 0 0', rgb, a);
76 R_PolygonVertex(o + ri, '1 0 0', rgb, a);
77 R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
78 R_PolygonVertex(o + up, '0 1 0', rgb, a);
82 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)
85 float owidth; // outer width
87 hotspot = -1 * hotspot;
89 // hotspot-relative coordinates of the healthbar corners
94 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
95 o = rotate(o, rot) + org;
99 owidth = width + 2 * border;
100 o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
102 drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
103 drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
104 drawquad(o, ri * border, up * height, "", rgb, a, f);
105 drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
106 drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
109 void Draw_WaypointSprite()
115 self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
119 if(self.hideflags & 2)
120 return; // radar only
122 if(autocvar_cl_hidewaypoints >= 2)
125 if(self.hideflags & 1)
126 if(autocvar_cl_hidewaypoints)
127 return; // fixed waypoint
129 InterpolateOrigin_Do();
131 t = GetPlayerColor(player_localentnum - 1) + 1;
138 case SPRITERULE_DEFAULT:
142 spriteimage = self.netname;
147 spriteimage = self.netname;
149 case SPRITERULE_TEAMPLAY:
150 if(t == COLOR_SPECTATOR + 1)
151 spriteimage = self.netname3;
152 else if(self.team == t)
153 spriteimage = self.netname2;
155 spriteimage = self.netname;
158 error("Invalid waypointsprite rule!");
162 if(spriteimage == "")
166 dist = vlen(self.origin - view_origin);
169 a = self.alpha * autocvar_hud_panel_fg_alpha;
171 if(self.maxdistance > waypointsprite_normdistance)
172 a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
173 else if(self.maxdistance > 0)
174 a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
179 // draw the sprite image
182 o = project_3d_to_2d(self.origin);
185 if(o_z < 0 || o_x < 0 || o_y < 0 || o_x > vid_conwidth || o_y > vid_conheight)
187 // scale it to be just in view
191 // get the waypoint angle vector
193 d_x = view_right * (self.origin - view_origin) * vid_conwidth / vid_width;
194 d_y = -view_up * (self.origin - view_origin) * vid_conheight / (vid_height * vid_pixelheight);
198 d = o - '0.5 0 0' * vid_conwidth - '0 0.5 0' * vid_conheight;
201 if(autocvar_v_flipped)
205 f1 = d_x / vid_conwidth;
206 f2 = d_y / vid_conheight;
208 if(max(f1, -f1) > max(f2, -f2))
239 o = d + '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
244 vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
246 t = stof(db_get(tempdb, strcat("/spriteframes/", spriteimage)));
248 spriteimage = strcat("models/sprites/", spriteimage);
250 spriteimage = strcat("models/sprites/", spriteimage, "_frame", ftos(mod(floor((max(0, time - self.spawntime)) * 2), t)));
252 float edgedistance_min, crosshairdistance;
253 edgedistance_min = min4(o_y, o_x,vid_conwidth - o_x, vid_conheight - o_y);
255 crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
257 t = waypointsprite_scale * vidscale;
258 a *= waypointsprite_alpha;
261 a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
262 t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
264 if (edgedistance_min < waypointsprite_edgefadedistance) {
265 a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
266 t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
268 if(crosshairdistance < waypointsprite_crosshairfadedistance) {
269 a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
270 t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
272 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * t, SPRITE_HOTSPOT * t, '1 1 1', a, DRAWFLAG_MIPMAP);
274 if(self.build_finished)
276 if(time < self.build_finished + 0.25)
278 if(time < self.build_started)
279 self.health = self.build_starthealth;
280 else if(time < self.build_finished)
281 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
292 if(self.build_finished)
296 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);
300 void Ent_RemoveWaypointSprite()
303 strunzone(self.netname);
305 strunzone(self.netname2);
307 strunzone(self.netname3);
310 void Ent_WaypointSprite()
312 float sendflags, f, t;
313 sendflags = ReadByte();
316 self.spawntime = time;
318 self.draw2d = Draw_WaypointSprite;
320 InterpolateOrigin_Undo();
327 self.health = t / 191.0;
328 self.build_finished = 0;
332 t = (t - 192) * 256 + ReadByte();
333 self.build_started = servertime;
334 if(self.build_finished)
335 self.build_starthealth = bound(0, self.health, 1);
337 self.build_starthealth = 0;
338 self.build_finished = servertime + t / 32;
344 self.build_finished = 0;
349 // unfortunately, this needs to be exact (for the 3D display)
350 self.origin_x = ReadCoord();
351 self.origin_y = ReadCoord();
352 self.origin_z = ReadCoord();
357 self.team = ReadByte();
358 self.rule = ReadByte();
364 strunzone(self.netname);
365 self.netname = strzone(ReadString());
371 strunzone(self.netname2);
372 self.netname2 = strzone(ReadString());
378 strunzone(self.netname3);
379 self.netname3 = strzone(ReadString());
384 self.lifetime = ReadCoord();
385 self.fadetime = ReadCoord();
386 self.maxdistance = ReadShort();
387 self.hideflags = ReadByte();
393 self.teamradar_icon = (f & 0x7F);
396 self.(teamradar_times[self.teamradar_time_index]) = time;
397 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
399 self.teamradar_color_x = ReadByte() / 255.0;
400 self.teamradar_color_y = ReadByte() / 255.0;
401 self.teamradar_color_z = ReadByte() / 255.0;
404 InterpolateOrigin_Note();
406 self.entremove = Ent_RemoveWaypointSprite;
409 void WaypointSprite_Load()
411 waypointsprite_fadedistance = vlen(mi_scale);
412 waypointsprite_normdistance = autocvar_g_waypointsprite_normdistance;
413 waypointsprite_minscale = autocvar_g_waypointsprite_minscale;
414 waypointsprite_minalpha = autocvar_g_waypointsprite_minalpha;
415 waypointsprite_distancealphaexponent = autocvar_g_waypointsprite_distancealphaexponent;
416 waypointsprite_timealphaexponent = autocvar_g_waypointsprite_timealphaexponent;
417 waypointsprite_scale = autocvar_g_waypointsprite_scale;
418 waypointsprite_edgefadealpha = autocvar_g_waypointsprite_edgefadealpha;
419 waypointsprite_edgefadescale = autocvar_g_waypointsprite_edgefadescale;
420 waypointsprite_edgefadedistance = autocvar_g_waypointsprite_edgefadedistance;
421 waypointsprite_crosshairfadealpha = autocvar_g_waypointsprite_crosshairfadealpha;
422 waypointsprite_crosshairfadescale = autocvar_g_waypointsprite_crosshairfadescale;
423 waypointsprite_crosshairfadedistance = autocvar_g_waypointsprite_crosshairfadedistance;
424 waypointsprite_distancefadealpha = autocvar_g_waypointsprite_distancefadealpha;
425 waypointsprite_distancefadescale = autocvar_g_waypointsprite_distancefadescale;
426 waypointsprite_distancefadedistance = waypointsprite_fadedistance * autocvar_g_waypointsprite_distancefadedistancemultiplier;
427 waypointsprite_alpha = autocvar_g_waypointsprite_alpha * (1 - autocvar__menu_alpha);
429 if(!waypointsprite_initialized)
431 float dh, n, i, o, f;
432 string s, sname, sframes;
434 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
435 n = search_getsize(dh);
436 for(i = 0; i < n; ++i)
438 s = search_getfilename(dh, i);
439 s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .tga
441 o = strstrofs(s, "_frame", 0);
442 sname = strcat("/spriteframes/", substring(s, 0, o));
443 sframes = substring(s, o + 6, strlen(s) - o - 6);
444 f = stof(sframes) + 1;
445 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
449 dh = search_begin("models/sprites/*_frame*.jpg", 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 .jpg
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)))));
463 waypointsprite_initialized = true;