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;
20 .string netname; // primary picture
21 .string netname2; // secondary picture
22 .string netname3; // tertiary picture
23 .float team; // team that gets netname2
31 .float build_starthealth;
32 .float build_finished;
34 vector SPRITE_SIZE = '288 36 0';
35 vector SPRITE_HOTSPOT = '144 36 0';
36 float SPRITE_HEALTHBAR_WIDTH = 144;
37 float SPRITE_HEALTHBAR_HEIGHT = 9;
38 float SPRITE_HEALTHBAR_MARGIN = 6;
39 float SPRITE_HEALTHBAR_BORDER = 2;
40 float SPRITE_HEALTHBAR_BORDERALPHA = 1;
41 float SPRITE_HEALTHBAR_HEALTHALPHA = 0.5;
43 void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)
45 vector v1, v2, v3, v4;
47 hotspot = -1 * hotspot;
49 // hotspot-relative coordinates of the corners
51 v2 = hotspot + '1 0 0' * sz_x;
52 v3 = hotspot + '1 0 0' * sz_x + '0 1 0' * sz_y;
53 v4 = hotspot + '0 1 0' * sz_y;
55 // rotate them, and make them absolute
56 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
57 v1 = rotate(v1, rot) + org;
58 v2 = rotate(v2, rot) + org;
59 v3 = rotate(v3, rot) + org;
60 v4 = rotate(v4, rot) + org;
63 R_BeginPolygon(pic, f);
64 R_PolygonVertex(v1, '0 0 0', rgb, a);
65 R_PolygonVertex(v2, '1 0 0', rgb, a);
66 R_PolygonVertex(v3, '1 1 0', rgb, a);
67 R_PolygonVertex(v4, '0 1 0', rgb, a);
71 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
73 R_BeginPolygon(pic, f);
74 R_PolygonVertex(o, '0 0 0', rgb, a);
75 R_PolygonVertex(o + ri, '1 0 0', rgb, a);
76 R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
77 R_PolygonVertex(o + up, '0 1 0', rgb, a);
81 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)
84 float owidth; // outer width
86 hotspot = -1 * hotspot;
88 // hotspot-relative coordinates of the healthbar corners
93 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
94 o = rotate(o, rot) + org;
98 owidth = width + 2 * border;
99 o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
101 drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
102 drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
103 drawquad(o, ri * border, up * height, "", rgb, a, f);
104 drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
105 drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
108 void Draw_WaypointSprite()
114 self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
118 if(self.hideflags & 2)
119 return; // radar only
121 if(cvar("cl_hidewaypoints") >= 2)
124 if(self.hideflags & 1)
125 if(cvar("cl_hidewaypoints"))
126 return; // fixed waypoint
128 InterpolateOrigin_Do();
130 t = GetPlayerColor(player_localentnum - 1) + 1;
137 case SPRITERULE_DEFAULT:
141 spriteimage = self.netname;
146 spriteimage = self.netname;
148 case SPRITERULE_TEAMPLAY:
149 if(t == COLOR_SPECTATOR + 1)
150 spriteimage = self.netname3;
151 else if(self.team == t)
152 spriteimage = self.netname2;
154 spriteimage = self.netname;
157 error("Invalid waypointsprite rule!");
161 if(spriteimage == "")
165 dist = vlen(self.origin - view_origin);
168 a = self.alpha * sbar_alpha_fg;
170 if(self.maxdistance > waypointsprite_normdistance)
171 a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
172 else if(self.maxdistance > 0)
173 a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
178 // draw the sprite image
181 o = project_3d_to_2d(self.origin);
184 if(o_z < 0 || o_x < 0 || o_y < 0 || o_x > vid_conwidth || o_y > vid_conheight)
186 // scale it to be just in view
190 // get the waypoint angle vector
192 d_x = view_right * (self.origin - view_origin) * vid_conwidth / vid_width;
193 d_y = -view_up * (self.origin - view_origin) * vid_conheight / (vid_height * vid_pixelheight);
197 d = o - '0.5 0 0' * vid_conwidth - '0 0.5 0' * vid_conheight;
200 if(cvar("v_flipped"))
204 f1 = d_x / vid_conwidth;
205 f2 = d_y / vid_conheight;
207 if(max(f1, -f1) > max(f2, -f2))
238 o = d + '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
243 vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
245 t = stof(db_get(tempdb, strcat("/spriteframes/", spriteimage)));
247 spriteimage = strcat("models/sprites/", spriteimage);
249 spriteimage = strcat("models/sprites/", spriteimage, "_frame", ftos(mod(floor((max(0, time - self.spawntime)) * 2), t)));
251 float edgedistance_min, crosshairdistance;
252 edgedistance_min = min4(o_y, o_x,vid_conwidth - o_x, vid_conheight - o_y);
254 crosshairdistance = sqrt( pow(o_x - vid_conwidth/2, 2) + pow(o_y - vid_conheight/2, 2) );
256 t = waypointsprite_scale * vidscale;
259 a = a * (1 - (1 - waypointsprite_distancefadealpha) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
260 t = t * (1 - (1 - waypointsprite_distancefadescale) * (bound(0, dist/waypointsprite_distancefadedistance, 1)));
262 if (edgedistance_min < waypointsprite_edgefadedistance) {
263 a = a * (1 - (1 - waypointsprite_edgefadealpha) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
264 t = t * (1 - (1 - waypointsprite_edgefadescale) * (1 - bound(0, edgedistance_min/waypointsprite_edgefadedistance, 1)));
266 if(crosshairdistance < waypointsprite_crosshairfadedistance) {
267 a = a * (1 - (1 - waypointsprite_crosshairfadealpha) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
268 t = t * (1 - (1 - waypointsprite_crosshairfadescale) * (1 - bound(0, crosshairdistance/waypointsprite_crosshairfadedistance, 1)));
270 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * t, SPRITE_HOTSPOT * t, '1 1 1', a, DRAWFLAG_MIPMAP);
272 if(self.build_finished)
274 if(time < self.build_finished + 0.25)
276 if(time < self.build_started)
277 self.health = self.build_starthealth;
278 else if(time < self.build_finished)
279 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
290 if(self.build_finished)
294 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);
298 void Ent_RemoveWaypointSprite()
301 strunzone(self.netname);
303 strunzone(self.netname2);
305 strunzone(self.netname3);
308 void Ent_WaypointSprite()
310 float sendflags, f, t;
311 sendflags = ReadByte();
314 self.spawntime = time;
316 self.draw2d = Draw_WaypointSprite;
318 InterpolateOrigin_Undo();
325 self.health = t / 191.0;
326 self.build_finished = 0;
330 t = (t - 192) * 256 + ReadByte();
331 self.build_started = servertime;
332 if(self.build_finished)
333 self.build_starthealth = bound(0, self.health, 1);
335 self.build_starthealth = 0;
336 self.build_finished = servertime + t / 32;
337 //print("build: ", ftos(self.build_finished - self.build_started), "\n");
343 self.build_finished = 0;
348 // unfortunately, this needs to be exact (for the 3D display)
349 self.origin_x = ReadCoord();
350 self.origin_y = ReadCoord();
351 self.origin_z = ReadCoord();
356 self.team = ReadByte();
357 self.rule = ReadByte();
363 strunzone(self.netname);
364 self.netname = strzone(ReadString());
370 strunzone(self.netname2);
371 self.netname2 = strzone(ReadString());
377 strunzone(self.netname3);
378 self.netname3 = strzone(ReadString());
383 self.lifetime = ReadCoord();
384 self.fadetime = ReadCoord();
385 self.maxdistance = ReadShort();
386 self.hideflags = ReadByte();
392 self.teamradar_icon = (f & 0x7F);
395 self.(teamradar_times[self.teamradar_time_index]) = time;
396 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
398 self.teamradar_color_x = ReadByte() / 255.0;
399 self.teamradar_color_y = ReadByte() / 255.0;
400 self.teamradar_color_z = ReadByte() / 255.0;
403 InterpolateOrigin_Note();
405 self.entremove = Ent_RemoveWaypointSprite;
408 void WaypointSprite_Load()
410 waypointsprite_fadedistance = vlen(mi_max - mi_min);
411 waypointsprite_normdistance = cvar("g_waypointsprite_normdistance");
412 waypointsprite_minscale = cvar("g_waypointsprite_minscale");
413 waypointsprite_minalpha = cvar("g_waypointsprite_minalpha");
414 waypointsprite_distancealphaexponent = cvar("g_waypointsprite_distancealphaexponent");
415 waypointsprite_timealphaexponent = cvar("g_waypointsprite_timealphaexponent");
416 waypointsprite_scale = cvar_or("g_waypointsprite_scale", 1) * (1 - cvar("_menu_alpha"));
417 waypointsprite_edgefadealpha = cvar_or("g_waypointsprite_edgefadealpha", 1);
418 waypointsprite_edgefadescale = cvar_or("g_waypointsprite_edgefadescale", 1);
419 waypointsprite_edgefadedistance = cvar("g_waypointsprite_edgefadedistance");
420 waypointsprite_crosshairfadealpha = cvar_or("g_waypointsprite_crosshairfadealpha", 1);
421 waypointsprite_crosshairfadescale = cvar_or("g_waypointsprite_crosshairfadescale", 1);
422 waypointsprite_crosshairfadedistance = cvar("g_waypointsprite_crosshairfadedistance");
423 waypointsprite_distancefadealpha = cvar_or("g_waypointsprite_distancefadealpha", 1);
424 waypointsprite_distancefadescale = cvar_or("g_waypointsprite_distancefadescale", 1);
425 waypointsprite_distancefadedistance = vlen(mi_max - mi_min) * cvar_or("g_waypointsprite_distancefadedistancemultiplier", 1);
427 if(!waypointsprite_initialized)
429 float dh, n, i, o, f;
430 string s, sname, sframes;
431 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
432 n = search_getsize(dh);
433 for(i = 0; i < n; ++i)
435 s = search_getfilename(dh, i);
436 if(substring(s, 0, 15) != "models/sprites/")
438 if(substring(s, strlen(s) - 4, 4) != ".tga")
440 s = substring(s, 15, strlen(s) - 19);
442 o = strstrofs(s, "_frame", 0);
443 sname = strcat("/spriteframes/", substring(s, 0, o));
444 sframes = substring(s, o + 6, strlen(s) - o - 6);
445 f = stof(sframes) + 1;
446 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
450 waypointsprite_initialized = 1;