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);
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");
315 // unfortunately, this needs to be exact (for the 3D display)
316 self.origin_x = ReadCoord();
317 self.origin_y = ReadCoord();
318 self.origin_z = ReadCoord();
323 self.team = ReadByte();
324 self.rule = ReadByte();
330 strunzone(self.netname);
331 self.netname = strzone(ReadString());
337 strunzone(self.netname2);
338 self.netname2 = strzone(ReadString());
344 strunzone(self.netname3);
345 self.netname3 = strzone(ReadString());
350 self.lifetime = ReadCoord();
351 self.fadetime = ReadCoord();
352 self.maxdistance = ReadShort();
353 self.hideflags = ReadByte();
359 self.teamradar_icon = (f & 0x7F);
362 self.(teamradar_times[self.teamradar_time_index]) = time;
363 self.teamradar_time_index = mod(self.teamradar_time_index + 1, MAX_TEAMRADAR_TIMES);
365 self.teamradar_color_x = ReadByte() / 255.0;
366 self.teamradar_color_y = ReadByte() / 255.0;
367 self.teamradar_color_z = ReadByte() / 255.0;
370 InterpolateOrigin_Note();
372 self.entremove = Ent_RemoveWaypointSprite;
375 void WaypointSprite_Load()
377 waypointsprite_fadedistance = vlen(world.maxs - world.mins);
378 waypointsprite_normdistance = cvar("g_waypointsprite_normdistance");
379 waypointsprite_minscale = cvar("g_waypointsprite_minscale");
380 waypointsprite_minalpha = cvar("g_waypointsprite_minalpha");
381 waypointsprite_distancealphaexponent = cvar("g_waypointsprite_distancealphaexponent");
382 waypointsprite_timealphaexponent = cvar("g_waypointsprite_timealphaexponent");
383 waypointsprite_scale = cvar("g_waypointsprite_scale");
384 if(!waypointsprite_scale)
385 waypointsprite_scale = 1.0;
387 if(!waypointsprite_initialized)
389 float dh, n, i, o, f;
390 string s, sname, sframes;
391 dh = search_begin("models/sprites/*_frame*.tga", FALSE, FALSE);
392 n = search_getsize(dh);
393 for(i = 0; i < n; ++i)
395 s = search_getfilename(dh, i);
396 if(substring(s, 0, 15) != "models/sprites/")
398 if(substring(s, strlen(s) - 4, 4) != ".tga")
400 s = substring(s, 15, strlen(s) - 19);
402 o = strstrofs(s, "_frame", 0);
403 sname = strcat("/spriteframes/", substring(s, 0, o));
404 sframes = substring(s, o + 6, strlen(s) - o - 6);
405 f = stof(sframes) + 1;
406 db_put(tempdb, sname, ftos(max(f, stof(db_get(tempdb, sname)))));
410 waypointsprite_initialized = 1;