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;
191 if(cvar("v_flipped"))
195 f1 = d_x / vid_conwidth;
196 f2 = d_y / vid_conheight;
198 if(max(f1, -f1) > max(f2, -f2))
229 o = d + '0.5 0 0' * vid_conwidth + '0 0.5 0' * vid_conheight;
234 vidscale = max(vid_conwidth / vid_width, vid_conheight / vid_height);
236 t = stof(db_get(tempdb, strcat("/spriteframes/", spriteimage)));
238 spriteimage = strcat("models/sprites/", spriteimage);
240 spriteimage = strcat("models/sprites/", spriteimage, "_frame", ftos(mod(floor((max(0, time - self.spawntime)) * 2), t)));
242 drawrotpic(o, rot * 90 * DEG2RAD, spriteimage, SPRITE_SIZE * waypointsprite_scale * vidscale, SPRITE_HOTSPOT * waypointsprite_scale * vidscale, '1 1 1', a, DRAWFLAG_MIPMAP);
244 if(self.build_finished)
246 if(time < self.build_finished + 0.25)
248 if(time < self.build_started)
249 self.health = self.build_starthealth;
250 else if(time < self.build_finished)
251 self.health = (time - self.build_started) / (self.build_finished - self.build_started) * (1 - self.build_starthealth) + self.build_starthealth;
262 if(self.build_finished)
266 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);
270 void Ent_RemoveWaypointSprite()
273 strunzone(self.netname);
275 strunzone(self.netname2);
277 strunzone(self.netname3);
280 void Ent_WaypointSprite()
282 float sendflags, f, t;
283 sendflags = ReadByte();
286 self.spawntime = time;
288 self.draw2d = Draw_WaypointSprite;
290 InterpolateOrigin_Undo();
297 self.health = t / 191.0;
298 self.build_finished = 0;
302 t = (t - 192) * 256 + ReadByte();
303 self.build_started = servertime;
304 if(self.build_finished)
305 self.build_starthealth = bound(0, self.health, 1);
307 self.build_starthealth = 0;
308 self.build_finished = servertime + t / 32;
309 //print("build: ", ftos(self.build_finished - self.build_started), "\n");
315 self.build_finished = 0;
320 // unfortunately, this needs to be exact (for the 3D display)
321 self.origin_x = ReadCoord();
322 self.origin_y = ReadCoord();
323 self.origin_z = ReadCoord();
328 self.team = ReadByte();
329 self.rule = ReadByte();
335 strunzone(self.netname);
336 self.netname = strzone(ReadString());
342 strunzone(self.netname2);
343 self.netname2 = strzone(ReadString());
349 strunzone(self.netname3);
350 self.netname3 = strzone(ReadString());
355 self.lifetime = ReadCoord();
356 self.fadetime = ReadCoord();
357 self.maxdistance = ReadShort();
358 self.hideflags = ReadByte();
364 self.teamradar_icon = (f & 0x7F);
367 self.(teamradar_times[self.teamradar_time_index]) = time;
368 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
370 self.teamradar_color_x = ReadByte() / 255.0;
371 self.teamradar_color_y = ReadByte() / 255.0;
372 self.teamradar_color_z = ReadByte() / 255.0;
375 InterpolateOrigin_Note();
377 self.entremove = Ent_RemoveWaypointSprite;
380 void WaypointSprite_Load()
382 waypointsprite_fadedistance = vlen(world.maxs - world.mins);
383 waypointsprite_normdistance = cvar("g_waypointsprite_normdistance");
384 waypointsprite_minscale = cvar("g_waypointsprite_minscale");
385 waypointsprite_minalpha = cvar("g_waypointsprite_minalpha");
386 waypointsprite_distancealphaexponent = cvar("g_waypointsprite_distancealphaexponent");
387 waypointsprite_timealphaexponent = cvar("g_waypointsprite_timealphaexponent");
388 waypointsprite_scale = cvar("g_waypointsprite_scale") * (1 - cvar("_menu_alpha"));
389 if(!waypointsprite_scale)
390 waypointsprite_scale = 1.0 * (1 - cvar("_menu_alpha"));
392 if(!waypointsprite_initialized)
394 float dh, n, i, o, f;
395 string s, sname, sframes;
396 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
397 n = search_getsize(dh);
398 for(i = 0; i < n; ++i)
400 s = search_getfilename(dh, i);
401 if(substring(s, 0, 15) != "models/sprites/")
403 if(substring(s, strlen(s) - 4, 4) != ".tga")
405 s = substring(s, 15, strlen(s) - 19);
407 o = strstrofs(s, "_frame", 0);
408 sname = strcat("/spriteframes/", substring(s, 0, o));
409 sframes = substring(s, o + 6, strlen(s) - o - 6);
410 f = stof(sframes) + 1;
411 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
415 waypointsprite_initialized = 1;