+// returns location of sprite text
+vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
+{
+ float SQRT2 = 1.414;
+ float BORDER; BORDER = 1.5 * t;
+ float TSIZE; TSIZE = 8 * t;
+ float RLENGTH; RLENGTH = 8 * t;
+ float RWIDTH; RWIDTH = 4 * t;
+ float MLENGTH; MLENGTH = 4 * t;
+
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(o + rotate(eX * -(TSIZE + BORDER * (1 + SQRT2)) + eY * (TSIZE + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_PolygonVertex(o + rotate(eX * (TSIZE + BORDER * (1 + SQRT2)) + eY * (TSIZE + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_PolygonVertex(o + rotate(eY * -( BORDER * SQRT2), ang), '0 0 0', '0 0 0', a);
+ R_EndPolygon();
+ R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_PolygonVertex(o + rotate(eX * -(RWIDTH + BORDER) + eY * (TSIZE + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_PolygonVertex(o + rotate(eX * -(RWIDTH + BORDER) + eY * (TSIZE + RLENGTH + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_PolygonVertex(o + rotate(eX * (RWIDTH + BORDER) + eY * (TSIZE + RLENGTH + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_PolygonVertex(o + rotate(eX * (RWIDTH + BORDER) + eY * (TSIZE + BORDER), ang), '0 0 0', '0 0 0', a);
+ R_EndPolygon();
+
+ R_BeginPolygon("", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex(o + rotate(eX * -TSIZE + eY * TSIZE, ang), '0 0 0', rgb, a);
+ R_PolygonVertex(o + rotate(eX * TSIZE + eY * TSIZE, ang), '0 0 0', rgb, a);
+ R_PolygonVertex(o + rotate('0 0 0', ang), '0 0 0', rgb, a);
+ R_EndPolygon();
+ R_BeginPolygon("", DRAWFLAG_ADDITIVE);
+ R_PolygonVertex(o + rotate(eX * -RWIDTH + eY * TSIZE, ang), '0 0 0', rgb, a);
+ R_PolygonVertex(o + rotate(eX * -RWIDTH + eY * (TSIZE + RLENGTH), ang), '0 0 0', rgb, a);
+ R_PolygonVertex(o + rotate(eX * RWIDTH + eY * (TSIZE + RLENGTH), ang), '0 0 0', rgb, a);
+ R_PolygonVertex(o + rotate(eX * RWIDTH + eY * TSIZE, ang), '0 0 0', rgb, a);
+ R_EndPolygon();
+
+ return
+ o + rotate(eY * (TSIZE + RLENGTH + MLENGTH), ang);
+}
+
+// returns location of sprite healthbar
+vector drawspritetext(vector o, float ang, float minwidth, vector rgb, float a, vector fontsize, string s)
+{
+ float algnx, algny;
+ float sw, w, h;
+ float aspect, sa, ca;
+
+ sw = stringwidth(s, FALSE, fontsize);
+ if(sw > minwidth)
+ w = sw;
+ else
+ w = minwidth;
+ h = fontsize_y;
+
+ // how do corners work?
+ aspect = vid_conwidth / vid_conheight;
+ sa = sin(ang);
+ ca = cos(ang) * aspect;
+ if(fabs(sa) > fabs(ca))
+ {
+ algnx = (sa < 0);
+ algny = 0.5 - 0.5 * ca / fabs(sa);
+ }
+ else
+ {
+ algnx = 0.5 - 0.5 * sa / fabs(ca);
+ algny = (ca < 0);
+ }
+
+ // align
+ o_x -= w * algnx;
+ o_y -= h * algny;
+
+ // we want to be onscreen
+ if(o_x < 0)
+ o_x = 0;
+ if(o_y < 0)
+ o_y = 0;
+ if(o_x > vid_conwidth - w)
+ o_x = vid_conwidth - w;
+ if(o_y > vid_conheight - h)
+ o_x = vid_conheight - h;
+
+ o_x += 0.5 * (w - sw);
+
+ drawstring(o, s, fontsize, rgb, a, DRAWFLAG_NORMAL);
+
+ o_x += 0.5 * sw;
+ o_y += 0.5 * h;
+
+ return o;
+}
+
+float spritelookupblinkvalue(string s)
+{
+ switch(s)
+ {
+ case "ons-cp-atck-neut": return 2;
+ case "ons-cp-atck-red": return 2;
+ case "ons-cp-atck-blue": return 2;
+ case "ons-cp-dfnd-red": return 0.5;
+ case "ons-cp-dfnd-blue": return 0.5;
+ case "item-invis": return 2;
+ case "item-extralife": return 2;
+ case "item-speed": return 2;
+ case "item-strength": return 2;
+ case "item-shueld": return 2;
+ case "item-fuelregen": return 2;
+ case "item-jetpack": return 2;
+ case "tagged-target": return 2;
+ default: return 1;
+ }
+}
+vector spritelookupcolor(string s, vector def)
+{
+ switch(s)
+ {
+ case "keycarrier-friend": return '0 1 0';
+ case "wpn-laser": return '1 0.5 0.5';
+ case "wpn-shotgun": return '0.5 0.25 0';
+ case "wpn-uzi": return '1 1 0';
+ case "wpn-gl": return '1 0 0';
+ case "wpn-electro": return '0 0.5 1';
+ case "wpn-crylink": return '1 0.5 1';
+ case "wpn-nex": return '0.5 1 1';
+ case "wpn-hagar": return '1 1 0.5';
+ case "wpn-rl": return '1 1 0';
+ case "wpn-porto": return '0.5 0.5 0.5';
+ case "wpn-minstanex": return '0.5 1 1';
+ case "wpn-hookgun": return '0 0.5 0';
+ case "wpn-fireball": return '1 0.5 0';
+ case "wpn-hlac": return '0 1 0';
+ case "wpn-campingrifle": return '0.5 1 0';
+ case "wpn-minelayer": return '0.75 1 0';
+ default: return def;
+ }
+}
+string spritelookuptext(string s)
+{
+ switch(s)
+ {
+ case "as-push": return _("Push");
+ case "as-destroy": return _("Destroy");
+ case "as-defend": return _("Defend");
+ case "bluebase": return _("Blue base");
+ case "danger": return _("DANGER");
+ case "flagcarrier": return _("Flag carrier");
+ case "flagdropped": return _("Dropped flag");
+ case "helpme": return _("Help me!");
+ case "here": return _("Here");
+ case "key-dropped": return _("Dropped key");
+ case "keycarrier-blue": return _("Key carrier");
+ case "keycarrier-finish": return _("Run here");
+ case "keycarrier-friend": return _("Key carrier");
+ case "keycarrier-pink": return _("Key carrier");
+ case "keycarrier-red": return _("Key carrier");
+ case "keycarrier-yellow": return _("Key carrier");
+ case "redbase": return _("Red base");
+ case "waypoint": return _("Waypoint");
+ case "ons-gen-red": return _("Generator");
+ case "ons-gen-blue": return _("Generator");
+ case "ons-gen-shielded": return _("Generator");
+ case "ons-cp-neut": return _("Control point");
+ case "ons-cp-red": return _("Control point");
+ case "ons-cp-blue": return _("Control point");
+ case "ons-cp-atck-neut": return _("Control point");
+ case "ons-cp-atck-red": return _("Control point");
+ case "ons-cp-atck-blue": return _("Control point");
+ case "ons-cp-dfnd-red": return _("Control point");
+ case "ons-cp-dfnd-blue": return _("Control point");
+ case "race-checkpoint": return _("Checkpoint");
+ case "race-finish": return _("Finish");
+ case "race-start": return _("Start");
+ case "race-start-finish": return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
+ case "nb-ball": return _("Ball");
+ case "ka-ball": return _("Ball");
+ case "ka-ballcarrier": return _("Ball carrier");
+ case "wpn-laser": return _("Laser");
+ case "wpn-shotgun": return _("Shotgun");
+ case "wpn-uzi": return _("Machine Gun");
+ case "wpn-gl": return _("Mortar");
+ case "wpn-electro": return _("Electro");
+ case "wpn-crylink": return _("Crylink");
+ case "wpn-nex": return _("Nex");
+ case "wpn-hagar": return _("Hagar");
+ case "wpn-rl": return _("Rocket Launcher");
+ case "wpn-porto": return _("Port-O-Launch");
+ case "wpn-minstanex": return _("Minstanex");
+ case "wpn-hookgun": return _("Hook");
+ case "wpn-fireball": return _("Fireball");
+ case "wpn-hlac": return _("HLAC");
+ case "wpn-campingrifle": return _("Rifle");
+ case "wpn-minelayer": return _("Mine Layer");
+ case "dom-neut": return _("Control point");
+ case "dom-red": return _("Control point");
+ case "dom-blue": return _("Control point");
+ case "dom-yellow": return _("Control point");
+ case "dom-pink": return _("Control point");
+ case "item-invis": return _("Invisibility");
+ case "item-extralife": return _("Extra life");
+ case "item-speed": return _("Speed");
+ case "item-strength": return _("Strength");
+ case "item-shield": return _("Shield");
+ case "item-fuelregen": return _("Fuel regen");
+ case "item-jetpack": return _("Jet Pack");
+ case "freezetag_frozen": return _("Frozen!");
+ case "tagged-target": return _("Tagged");
+ case "vehicle": return _("Vehicle");
+ default: return s;
+ }
+}
+
+vector fixrgbexcess_move(vector rgb, vector src, vector dst)
+{
+ vector yvec = '0.299 0.587 0.114';
+ return rgb + dst * ((src * yvec) / (dst * yvec)) * ((rgb - '1 1 1') * src);
+}
+vector fixrgbexcess(vector rgb)
+{
+ if(rgb_x > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '1 0 0', '0 1 1');
+ if(rgb_y > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 1 0', '0 0 1');
+ if(rgb_z > 1)
+ rgb_z = 1;
+ }
+ else if(rgb_z > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 0 1', '0 1 0');
+ if(rgb_y > 1)
+ rgb_y = 1;
+ }
+ }
+ else if(rgb_y > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 1 0', '1 0 1');
+ if(rgb_x > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '1 0 0', '0 0 1');
+ if(rgb_z > 1)
+ rgb_z = 1;
+ }
+ else if(rgb_z > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 0 1', '1 0 0');
+ if(rgb_x > 1)
+ rgb_x = 1;
+ }
+ }
+ else if(rgb_z > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 0 1', '1 1 0');
+ if(rgb_x > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '1 0 0', '0 1 0');
+ if(rgb_y > 1)
+ rgb_y = 1;
+ }
+ else if(rgb_y > 1)
+ {
+ rgb = fixrgbexcess_move(rgb, '0 1 0', '1 0 0');
+ if(rgb_x > 1)
+ rgb_x = 1;
+ }
+ }
+ return rgb;
+}
+
+float waypointsprite_count, waypointsprite_newcount;