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_x;
13 float waypointsprite_edgeoffset_y;
14 float waypointsprite_crosshairfadealpha;
15 float waypointsprite_crosshairfadescale;
16 float waypointsprite_crosshairfadedistance;
17 float waypointsprite_distancefadealpha;
18 float waypointsprite_distancefadescale;
19 float waypointsprite_distancefadedistance;
20 float waypointsprite_alpha;
23 .string netname; // primary picture
24 .string netname2; // secondary picture
25 .string netname3; // tertiary picture
26 .float team; // team that gets netname2
34 .float build_starthealth;
35 .float build_finished;
37 vector SPRITE_SIZE = '288 36 0';
38 vector SPRITE_HOTSPOT = '144 36 0';
39 float SPRITE_HEALTHBAR_WIDTH = 144;
40 float SPRITE_HEALTHBAR_HEIGHT = 9;
41 float SPRITE_HEALTHBAR_MARGIN = 6;
42 float SPRITE_HEALTHBAR_BORDER = 2;
43 float SPRITE_HEALTHBAR_BORDERALPHA = 1;
44 float SPRITE_HEALTHBAR_HEALTHALPHA = 0.5;
46 void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)
48 vector v1, v2, v3, v4;
50 hotspot = -1 * hotspot;
52 // hotspot-relative coordinates of the corners
54 v2 = hotspot + '1 0 0' * sz_x;
55 v3 = hotspot + '1 0 0' * sz_x + '0 1 0' * sz_y;
56 v4 = hotspot + '0 1 0' * sz_y;
58 // rotate them, and make them absolute
59 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
60 v1 = rotate(v1, rot) + org;
61 v2 = rotate(v2, rot) + org;
62 v3 = rotate(v3, rot) + org;
63 v4 = rotate(v4, rot) + org;
66 R_BeginPolygon(pic, f);
67 R_PolygonVertex(v1, '0 0 0', rgb, a);
68 R_PolygonVertex(v2, '1 0 0', rgb, a);
69 R_PolygonVertex(v3, '1 1 0', rgb, a);
70 R_PolygonVertex(v4, '0 1 0', rgb, a);
74 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
76 R_BeginPolygon(pic, f);
77 R_PolygonVertex(o, '0 0 0', rgb, a);
78 R_PolygonVertex(o + ri, '1 0 0', rgb, a);
79 R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
80 R_PolygonVertex(o + up, '0 1 0', rgb, a);
84 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)
87 float owidth; // outer width
89 hotspot = -1 * hotspot;
91 // hotspot-relative coordinates of the healthbar corners
96 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
97 o = rotate(o, rot) + org;
101 owidth = width + 2 * border;
102 o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
104 drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
105 drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
106 drawquad(o, ri * border, up * height, "", rgb, a, f);
107 drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
108 drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
111 void Draw_WaypointSprite()
117 self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
121 if(self.hideflags & 2)
122 return; // radar only
124 if(autocvar_cl_hidewaypoints >= 2)
127 if(self.hideflags & 1)
128 if(autocvar_cl_hidewaypoints)
129 return; // fixed waypoint
131 InterpolateOrigin_Do();
133 t = GetPlayerColor(player_localentnum - 1) + 1;
140 case SPRITERULE_DEFAULT:
144 spriteimage = self.netname;
149 spriteimage = self.netname;
151 case SPRITERULE_TEAMPLAY:
152 if(t == COLOR_SPECTATOR + 1)
153 spriteimage = self.netname3;
154 else if(self.team == t)
155 spriteimage = self.netname2;
157 spriteimage = self.netname;
160 error("Invalid waypointsprite rule!");
164 if(spriteimage == "")
168 dist = vlen(self.origin - view_origin);
171 a = self.alpha * autocvar_hud_panel_fg_alpha;
173 if(self.maxdistance > waypointsprite_normdistance)
174 a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
175 else if(self.maxdistance > 0)
176 a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
181 // draw the sprite image
184 o = project_3d_to_2d(self.origin);
187 print("origin: ", vtos(o), ", edgeoffsets: ", ftos(waypointsprite_edgeoffset_x), " - ", ftos(autocvar_g_waypointsprite_edgeoffset_x), ". \n");
190 || o_x < (vid_conwidth * waypointsprite_edgeoffset_x)
191 || o_y < (vid_conheight * waypointsprite_edgeoffset_y)
192 || o_x > (vid_conwidth - (vid_conwidth * waypointsprite_edgeoffset_x))
193 || o_y > (vid_conheight - (vid_conheight * waypointsprite_edgeoffset_y)))
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_x) / f1);
227 d = d * (-(0.5 - waypointsprite_edgeoffset_x) / f1);
236 d = d * ((0.5 - waypointsprite_edgeoffset_y) / f2);
242 d = d * (-(0.5 - waypointsprite_edgeoffset_y) / 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, o_x,vid_conwidth - o_x, vid_conheight - o_y);
263 crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
265 t = waypointsprite_scale * vidscale;
266 a *= waypointsprite_alpha;
269 a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
270 t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
272 if (edgedistance_min < waypointsprite_edgefadedistance) {
273 a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
274 t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
276 if(crosshairdistance < waypointsprite_crosshairfadedistance) {
277 a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
278 t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
280 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * t, SPRITE_HOTSPOT * t, '1 1 1', a, DRAWFLAG_MIPMAP);
282 if(self.build_finished)
284 if(time < self.build_finished + 0.25)
286 if(time < self.build_started)
287 self.health = self.build_starthealth;
288 else if(time < self.build_finished)
289 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
300 if(self.build_finished)
304 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);
308 void Ent_RemoveWaypointSprite()
311 strunzone(self.netname);
313 strunzone(self.netname2);
315 strunzone(self.netname3);
318 void Ent_WaypointSprite()
320 float sendflags, f, t;
321 sendflags = ReadByte();
324 self.spawntime = time;
326 self.draw2d = Draw_WaypointSprite;
328 InterpolateOrigin_Undo();
335 self.health = t / 191.0;
336 self.build_finished = 0;
340 t = (t - 192) * 256 + ReadByte();
341 self.build_started = servertime;
342 if(self.build_finished)
343 self.build_starthealth = bound(0, self.health, 1);
345 self.build_starthealth = 0;
346 self.build_finished = servertime + t / 32;
352 self.build_finished = 0;
357 // unfortunately, this needs to be exact (for the 3D display)
358 self.origin_x = ReadCoord();
359 self.origin_y = ReadCoord();
360 self.origin_z = ReadCoord();
365 self.team = ReadByte();
366 self.rule = ReadByte();
372 strunzone(self.netname);
373 self.netname = strzone(ReadString());
379 strunzone(self.netname2);
380 self.netname2 = strzone(ReadString());
386 strunzone(self.netname3);
387 self.netname3 = strzone(ReadString());
392 self.lifetime = ReadCoord();
393 self.fadetime = ReadCoord();
394 self.maxdistance = ReadShort();
395 self.hideflags = ReadByte();
401 self.teamradar_icon = (f & 0x7F);
404 self.(teamradar_times[self.teamradar_time_index]) = time;
405 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
407 self.teamradar_color_x = ReadByte() / 255.0;
408 self.teamradar_color_y = ReadByte() / 255.0;
409 self.teamradar_color_z = ReadByte() / 255.0;
412 InterpolateOrigin_Note();
414 self.entremove = Ent_RemoveWaypointSprite;
417 void WaypointSprite_Load()
419 waypointsprite_fadedistance = vlen(mi_scale);
420 waypointsprite_normdistance = autocvar_g_waypointsprite_normdistance;
421 waypointsprite_minscale = autocvar_g_waypointsprite_minscale;
422 waypointsprite_minalpha = autocvar_g_waypointsprite_minalpha;
423 waypointsprite_distancealphaexponent = autocvar_g_waypointsprite_distancealphaexponent;
424 waypointsprite_timealphaexponent = autocvar_g_waypointsprite_timealphaexponent;
425 waypointsprite_scale = autocvar_g_waypointsprite_scale;
426 waypointsprite_edgefadealpha = autocvar_g_waypointsprite_edgefadealpha;
427 waypointsprite_edgefadescale = autocvar_g_waypointsprite_edgefadescale;
428 waypointsprite_edgefadedistance = autocvar_g_waypointsprite_edgefadedistance;
429 waypointsprite_edgeoffset_x = autocvar_g_waypointsprite_edgeoffset_x;
430 waypointsprite_edgeoffset_y = autocvar_g_waypointsprite_edgeoffset_y;
431 waypointsprite_crosshairfadealpha = autocvar_g_waypointsprite_crosshairfadealpha;
432 waypointsprite_crosshairfadescale = autocvar_g_waypointsprite_crosshairfadescale;
433 waypointsprite_crosshairfadedistance = autocvar_g_waypointsprite_crosshairfadedistance;
434 waypointsprite_distancefadealpha = autocvar_g_waypointsprite_distancefadealpha;
435 waypointsprite_distancefadescale = autocvar_g_waypointsprite_distancefadescale;
436 waypointsprite_distancefadedistance = waypointsprite_fadedistance * autocvar_g_waypointsprite_distancefadedistancemultiplier;
437 waypointsprite_alpha = autocvar_g_waypointsprite_alpha * (1 - autocvar__menu_alpha);
439 if(!waypointsprite_initialized)
441 float dh, n, i, o, f;
442 string s, sname, sframes;
444 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
445 n = search_getsize(dh);
446 for(i = 0; i < n; ++i)
448 s = search_getfilename(dh, i);
449 s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .tga
451 o = strstrofs(s, "_frame", 0);
452 sname = strcat("/spriteframes/", substring(s, 0, o));
453 sframes = substring(s, o + 6, strlen(s) - o - 6);
454 f = stof(sframes) + 1;
455 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
459 dh = search_begin("models/sprites/*_frame*.jpg", FALSE, FALSE);
460 n = search_getsize(dh);
461 for(i = 0; i < n; ++i)
463 s = search_getfilename(dh, i);
464 s = substring(s, 15, strlen(s) - 15 - 4); // strip models/sprites/ and .jpg
466 o = strstrofs(s, "_frame", 0);
467 sname = strcat("/spriteframes/", substring(s, 0, o));
468 sframes = substring(s, o + 6, strlen(s) - o - 6);
469 f = stof(sframes) + 1;
470 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
473 waypointsprite_initialized = true;