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;
11 .string netname; // primary picture
12 .string netname2; // secondary picture
13 .string netname3; // tertiary picture
14 .float team; // team that gets netname2
22 .float build_starthealth;
23 .float build_finished;
25 vector SPRITE_SIZE = '288 36 0';
26 vector SPRITE_HOTSPOT = '144 36 0';
27 float SPRITE_HEALTHBAR_WIDTH = 96;
28 float SPRITE_HEALTHBAR_HEIGHT = 6;
29 float SPRITE_HEALTHBAR_MARGIN = 4;
30 float SPRITE_HEALTHBAR_BORDER = 1;
31 float SPRITE_HEALTHBAR_BORDERALPHA = 1;
32 float SPRITE_HEALTHBAR_HEALTHALPHA = 0.5;
34 void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, vector rgb, float a, float f)
36 vector v1, v2, v3, v4;
38 hotspot = -1 * hotspot;
40 // hotspot-relative coordinates of the corners
42 v2 = hotspot + '1 0 0' * sz_x;
43 v3 = hotspot + '1 0 0' * sz_x + '0 1 0' * sz_y;
44 v4 = hotspot + '0 1 0' * sz_y;
46 // rotate them, and make them absolute
47 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
48 v1 = rotate(v1, rot) + org;
49 v2 = rotate(v2, rot) + org;
50 v3 = rotate(v3, rot) + org;
51 v4 = rotate(v4, rot) + org;
54 R_BeginPolygon(pic, f);
55 R_PolygonVertex(v1, '0 0 0', rgb, a);
56 R_PolygonVertex(v2, '1 0 0', rgb, a);
57 R_PolygonVertex(v3, '1 1 0', rgb, a);
58 R_PolygonVertex(v4, '0 1 0', rgb, a);
62 void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
64 R_BeginPolygon(pic, f);
65 R_PolygonVertex(o, '0 0 0', rgb, a);
66 R_PolygonVertex(o + ri, '1 0 0', rgb, a);
67 R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
68 R_PolygonVertex(o + up, '0 1 0', rgb, a);
72 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)
75 float owidth; // outer width
77 hotspot = -1 * hotspot;
79 // hotspot-relative coordinates of the healthbar corners
84 rot = -rot; // rotate by the opposite angle, as our coordinate system is reversed
85 o = rotate(o, rot) + org;
89 owidth = width + 2 * border;
90 o = o - up * (margin + border + height) + ri * (sz_x - owidth) * 0.5;
92 drawquad(o - up * border, ri * owidth, up * border, "", rgb, a, f);
93 drawquad(o + up * height, ri * owidth, up * border, "", rgb, a, f);
94 drawquad(o, ri * border, up * height, "", rgb, a, f);
95 drawquad(o + ri * (owidth - border), ri * border, up * height, "", rgb, a, f);
96 drawquad(o + ri * (border + align * ((1 - h) * width)), ri * width * h, up * height, "", hrgb, ha, f);
99 void Draw_WaypointSprite()
105 self.alpha = pow(bound(0, (self.fadetime - time) / self.lifetime, 1), waypointsprite_timealphaexponent);
109 if(self.hideflags & 2)
110 return; // radar only
112 if(cvar("cl_hidewaypoints") >= 2)
115 if(self.hideflags & 1)
116 if(cvar("cl_hidewaypoints"))
117 return; // fixed waypoint
119 InterpolateOrigin_Do();
121 t = GetPlayerColor(player_localentnum - 1) + 1;
128 case SPRITERULE_DEFAULT:
132 spriteimage = self.netname;
137 spriteimage = self.netname;
139 case SPRITERULE_TEAMPLAY:
140 if(t == COLOR_SPECTATOR + 1)
141 spriteimage = self.netname3;
142 else if(self.team == t)
143 spriteimage = self.netname2;
145 spriteimage = self.netname;
148 error("Invalid waypointsprite rule!");
152 if(spriteimage == "")
156 dist = vlen(self.origin - view_origin);
159 a = self.alpha * sbar_alpha_fg;
161 if(self.maxdistance > waypointsprite_normdistance)
162 a *= pow(bound(0, (self.maxdistance - dist) / (self.maxdistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent);
163 else if(self.maxdistance > 0)
164 a *= pow(bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1), waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
169 // draw the sprite image
172 o = project_3d_to_2d(self.origin);
175 if(o_z < 0 || o_x < 0 || o_y < 0 || o_x > vid_conwidth || o_y > vid_conheight)
177 // scale it to be just in view
181 // get the waypoint angle vector
183 d_x = view_right * (self.origin - view_origin) * vid_conwidth / vid_width;
184 d_y = -view_up * (self.origin - view_origin) * vid_conheight / (vid_height * vid_pixelheight);
188 d = o - '0.5 0 0' * vid_conwidth - '0 0.5 0' * vid_conheight;
190 if(cvar("v_flipped"))
193 f1 = d_x / vid_conwidth;
194 f2 = d_y / vid_conheight;
196 if(max(f1, -f1) > max(f2, -f2))
227 o = d + '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
232 vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
234 t = stof(db_get(tempdb, strcat("/spriteframes/", spriteimage)));
236 spriteimage = strcat("models/sprites/", spriteimage);
238 spriteimage = strcat("models/sprites/", spriteimage, "_frame", ftos(mod(floor((max(0, time - self.spawntime)) * 2), t)));
240 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * waypointsprite_scale * vidscale, SPRITE_HOTSPOT * waypointsprite_scale * vidscale, '1 1 1', a, DRAWFLAG_MIPMAP);
242 if(self.build_finished)
244 if(time < self.build_finished + 0.25)
246 if(time < self.build_started)
247 self.health = self.build_starthealth;
248 else if(time < self.build_finished)
249 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
260 if(self.build_finished)
264 drawhealthbar(o, rot * 90 * DEG2RAD, self.health, SPRITE_SIZE * waypointsprite_scale * vidscale, SPRITE_HOTSPOT * waypointsprite_scale * vidscale, SPRITE_HEALTHBAR_WIDTH, SPRITE_HEALTHBAR_HEIGHT, SPRITE_HEALTHBAR_MARGIN, SPRITE_HEALTHBAR_BORDER, align, self.teamradar_color, a * SPRITE_HEALTHBAR_BORDERALPHA, self.teamradar_color, a * SPRITE_HEALTHBAR_HEALTHALPHA, DRAWFLAG_NORMAL);
268 void Ent_RemoveWaypointSprite()
271 strunzone(self.netname);
273 strunzone(self.netname2);
275 strunzone(self.netname3);
278 void Ent_WaypointSprite()
280 float sendflags, f, t;
281 sendflags = ReadByte();
284 self.spawntime = time;
286 self.draw2d = Draw_WaypointSprite;
288 InterpolateOrigin_Undo();
295 self.health = t / 191.0;
296 self.build_finished = 0;
300 t = (t - 192) * 256 + ReadByte();
301 self.build_started = servertime;
302 if(self.build_finished)
303 self.build_starthealth = bound(0, self.health, 1);
305 self.build_starthealth = 0;
306 self.build_finished = servertime + t / 32;
307 //print("build: ", ftos(self.build_finished - self.build_started), "\n");
313 self.build_finished = 0;
318 // unfortunately, this needs to be exact (for the 3D display)
319 self.origin_x = ReadCoord();
320 self.origin_y = ReadCoord();
321 self.origin_z = ReadCoord();
326 self.team = ReadByte();
327 self.rule = ReadByte();
333 strunzone(self.netname);
334 self.netname = strzone(ReadString());
340 strunzone(self.netname2);
341 self.netname2 = strzone(ReadString());
347 strunzone(self.netname3);
348 self.netname3 = strzone(ReadString());
353 self.lifetime = ReadCoord();
354 self.fadetime = ReadCoord();
355 self.maxdistance = ReadShort();
356 self.hideflags = ReadByte();
362 self.teamradar_icon = (f & 0x7F);
365 self.(teamradar_times[self.teamradar_time_index]) = time;
366 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
368 self.teamradar_color_x = ReadByte() / 255.0;
369 self.teamradar_color_y = ReadByte() / 255.0;
370 self.teamradar_color_z = ReadByte() / 255.0;
373 InterpolateOrigin_Note();
375 self.entremove = Ent_RemoveWaypointSprite;
378 void WaypointSprite_Load()
380 waypointsprite_fadedistance = vlen(world.maxs - world.mins);
381 waypointsprite_normdistance = cvar("g_waypointsprite_normdistance");
382 waypointsprite_minscale = cvar("g_waypointsprite_minscale");
383 waypointsprite_minalpha = cvar("g_waypointsprite_minalpha");
384 waypointsprite_distancealphaexponent = cvar("g_waypointsprite_distancealphaexponent");
385 waypointsprite_timealphaexponent = cvar("g_waypointsprite_timealphaexponent");
386 waypointsprite_scale = cvar("g_waypointsprite_scale") * (1 - cvar("_menu_alpha"));
387 if(!waypointsprite_scale)
388 waypointsprite_scale = 1.0 * (1 - cvar("_menu_alpha"));
390 if(!waypointsprite_initialized)
392 float dh, n, i, o, f;
393 string s, sname, sframes;
394 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
395 n = search_getsize(dh);
396 for(i = 0; i < n; ++i)
398 s = search_getfilename(dh, i);
399 if(substring(s, 0, 15) != "models/sprites/")
401 if(substring(s, strlen(s) - 4, 4) != ".tga")
403 s = substring(s, 15, strlen(s) - 19);
405 o = strstrofs(s, "_frame", 0);
406 sname = strcat("/spriteframes/", substring(s, 0, o));
407 sframes = substring(s, o + 6, strlen(s) - o - 6);
408 f = stof(sframes) + 1;
409 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
413 waypointsprite_initialized = 1;