REGISTER_NET_LINKED(waypointsprites)
#ifdef SVQC
-/** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
{
WriteHeader(MSG_ENTITY, waypointsprites);
if (this.max_health || (this.pain_finished && (time < this.pain_finished + 0.25)))
sendflags |= 0x80;
- int f = 0;
- if(this.currentammo == 1)
- f |= 1; // hideable
- if(this.exteriormodeltoclient == to)
- f |= 2; // my own
- if(this.currentammo == 2)
- f |= 2; // radar only
+ int hide_flags = 0;
+ if(this.currentammo == 1) hide_flags |= 1; // hideable
+ else if(this.currentammo == 2) hide_flags |= 2; // radar only
+ if(this.exteriormodeltoclient == to) hide_flags |= 2; // my own
- MUTATOR_CALLHOOK(SendWaypoint, this, to, sendflags, f);
+ MUTATOR_CALLHOOK(SendWaypoint, this, to, sendflags, hide_flags);
sendflags = M_ARGV(2, int);
- f = M_ARGV(3, int);
+ hide_flags = M_ARGV(3, int);
WriteByte(MSG_ENTITY, sendflags);
WriteByte(MSG_ENTITY, this.wp_extra);
{
WriteCoord(MSG_ENTITY, this.fade_time);
WriteCoord(MSG_ENTITY, this.teleport_time);
- WriteShort(MSG_ENTITY, this.fade_rate); // maxdist
- WriteByte(MSG_ENTITY, f);
+ WriteShort(MSG_ENTITY, bound(0, this.fade_rate, 32767)); // maxdist
+ WriteByte(MSG_ENTITY, hide_flags);
}
if (sendflags & 32)
strfree(this.netname3);
}
-/** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
void Ent_WaypointSprite(entity this, bool isnew)
{
int sendflags = ReadByte();
float spritelookupblinkvalue(entity this, string s)
{
if (s == WP_Weapon.netname) {
- if (Weapons_from(this.wp_extra).spawnflags & WEP_FLAG_SUPERWEAPON)
+ if (REGISTRY_GET(Weapons, this.wp_extra).spawnflags & WEP_FLAG_SUPERWEAPON)
return 2;
}
- if (s == WP_Item.netname) return Items_from(this.wp_extra).m_waypointblink;
+ if (s == WP_Item.netname) return REGISTRY_GET(Items, this.wp_extra).m_waypointblink;
if(s == WP_FlagReturn.netname) return 2;
return 1;
vector spritelookupcolor(entity this, string s, vector def)
{
- if (s == WP_Weapon.netname || s == RADARICON_Weapon.netname) return Weapons_from(this.wp_extra).wpcolor;
- if (s == WP_Item.netname || s == RADARICON_Item.netname) return Items_from(this.wp_extra).m_color;
+ if (s == WP_Weapon.netname || s == RADARICON_Weapon.netname) return REGISTRY_GET(Weapons, this.wp_extra).wpcolor;
+ if (s == WP_Item.netname || s == RADARICON_Item.netname) return REGISTRY_GET(Items, this.wp_extra).m_color;
if (MUTATOR_CALLHOOK(WP_Format, this, s))
{
return M_ARGV(2, vector);
if(autocvar_g_waypointsprite_spam && waypointsprite_count >= autocvar_g_waypointsprite_spam)
return "Spam"; // no need to translate this debug string
if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
- if (s == WP_Weapon.netname) return Weapons_from(this.wp_extra).m_name;
- if (s == WP_Item.netname) return Items_from(this.wp_extra).m_waypoint;
+ if (s == WP_Weapon.netname) return REGISTRY_GET(Weapons, this.wp_extra).m_name;
+ if (s == WP_Item.netname) return REGISTRY_GET(Items, this.wp_extra).m_waypoint;
if (s == WP_Monster.netname) return get_monsterinfo(this.wp_extra).monster_name;
if (MUTATOR_CALLHOOK(WP_Format, this, s))
{
string spritelookupicon(entity this, string s)
{
// TODO: needs icons! //if (s == WP_RaceStartFinish.netname) return (race_checkpointtime || race_mycheckpointtime) ? _("Finish") : _("Start");
- if (s == WP_Weapon.netname) return Weapons_from(this.wp_extra).model2;
- if (s == WP_Item.netname) return Items_from(this.wp_extra).m_icon;
- if (s == WP_Vehicle.netname) return Vehicles_from(this.wp_extra).m_icon;
+ if (s == WP_Weapon.netname) return REGISTRY_GET(Weapons, this.wp_extra).model2;
+ if (s == WP_Item.netname) return REGISTRY_GET(Items, this.wp_extra).m_icon;
+ if (s == WP_Vehicle.netname) return REGISTRY_GET(Vehicles, this.wp_extra).m_icon;
//if (s == WP_Monster.netname) return get_monsterinfo(this.wp_extra).m_icon;
if (MUTATOR_CALLHOOK(WP_Format, this, s))
{
v4 = Rotate(v4, rot) + org;
// draw them
- R_BeginPolygon(pic, f);
+ R_BeginPolygon(pic, f, true);
R_PolygonVertex(v1, '0 0 0', rgb, a);
R_PolygonVertex(v2, '1 0 0', rgb, a);
R_PolygonVertex(v3, '1 1 0', rgb, a);
void drawquad(vector o, vector ri, vector up, string pic, vector rgb, float a, float f)
{
- R_BeginPolygon(pic, f);
+ R_BeginPolygon(pic, f, true);
R_PolygonVertex(o, '0 0 0', rgb, a);
R_PolygonVertex(o + ri, '1 0 0', rgb, a);
R_PolygonVertex(o + up + ri, '1 1 0', rgb, a);
vector borderX = eX * (size+borderDiag);
vector borderY = eY * (size+borderDiag+border);
- R_BeginPolygon("", DRAWFLAG_NORMAL);
+ R_BeginPolygon("", DRAWFLAG_NORMAL, true);
R_PolygonVertex(o, '0 0 0', '0 0 0', a);
R_PolygonVertex(o + Rotate(arrowY - borderX, ang), '0 0 0', '0 0 0', a);
R_PolygonVertex(o + Rotate(borderY - borderX, ang), '0 0 0', '0 0 0', a);
R_PolygonVertex(o + Rotate(arrowY + borderX, ang), '0 0 0', '0 0 0', a);
R_EndPolygon();
- R_BeginPolygon("", DRAWFLAG_ADDITIVE);
+ R_BeginPolygon("", DRAWFLAG_ADDITIVE, true);
R_PolygonVertex(o + Rotate(eY * borderDiag, ang), '0 0 0', rgb, a);
R_PolygonVertex(o + Rotate(arrowY - arrowX, ang), '0 0 0', rgb, a);
R_PolygonVertex(o + Rotate(arrowY + arrowX, ang), '0 0 0', rgb, a);
float dist = vlen(this.origin - view_origin);
float a = this.alpha * autocvar_hud_panel_fg_alpha;
- if (this.maxdistance > waypointsprite_normdistance)
- a *= (bound(0, (this.maxdistance - dist) / (this.maxdistance - waypointsprite_normdistance), 1) ** waypointsprite_distancealphaexponent);
- else if (this.maxdistance > 0)
- a *= (bound(0, (waypointsprite_fadedistance - dist) / (waypointsprite_fadedistance - waypointsprite_normdistance), 1) ** waypointsprite_distancealphaexponent) * (1 - waypointsprite_minalpha) + waypointsprite_minalpha;
+ if(this.maxdistance > 0)
+ {
+ // restrict maximum normal distance to the waypoint's maximum distance to prevent exploiting cvars
+ float maxnormdistance = bound(0, waypointsprite_normdistance, this.maxdistance - 1);
+ a *= (bound(0, (this.maxdistance - dist) / (this.maxdistance - maxnormdistance), 1) ** waypointsprite_distancealphaexponent);
+ }
vector rgb = spritelookupcolor(this, spriteimage, this.teamradar_color);
if (rgb == '0 0 0')
}
vector sz;
- vector txt_color;
- string txt = string_null;
+ vector col = rgb;
+ string txt = string_null; // it will contain either the text or the icon path
if (is_text)
{
txt = spritelookuptext(this, spriteimage);
txt = sprintf(_("%s needing help!"), txt);
if (autocvar_g_waypointsprite_uppercase)
txt = strtoupper(txt);
- txt_color = rgb;
sz = waypointsprite_fontsize * '1 1 0';
}
else
{
- // for convenience icon path and color are saved to txt and txt_color
- txt = pic;
- txt_color = ((autocvar_g_waypointsprite_iconcolor) ? '1 1 1' : rgb);
+ txt = pic; // icon path
+ if (autocvar_g_waypointsprite_iconcolor == 0)
+ col = '1 1 1';
+ else if (autocvar_g_waypointsprite_iconcolor > 0 && autocvar_g_waypointsprite_iconcolor != 1)
+ {
+ col = rgb_to_hsv(col);
+ col.y *= autocvar_g_waypointsprite_iconcolor; // scale saturation
+ col = hsv_to_rgb(col);
+ }
sz = autocvar_g_waypointsprite_iconsize * '1 1 0';
}
marg = SPRITE_HEALTHBAR_MARGIN * t + 0.5 * sz.y;
float minwidth = (SPRITE_HEALTHBAR_WIDTH + 2 * SPRITE_HEALTHBAR_BORDER) * t;
- o = drawsprite_TextOrIcon(is_text, o, ang, minwidth, txt_color, a, sz, txt);
+ o = drawsprite_TextOrIcon(is_text, o, ang, minwidth, col, a, sz, txt);
drawhealthbar(
o,
0,
}
else
{
- drawsprite_TextOrIcon(is_text, o, ang, 0, txt_color, a, sz, txt);
+ drawsprite_TextOrIcon(is_text, o, ang, 0, col, a, sz, txt);
}
draw_endBoldFont();
{
// no check, as this is never called without doing an actual change (usually only once)
int i = icon.m_id;
- e.cnt = (e.cnt & BIT(7)) | (i & BITS(7));
- e.colormod = col;
- e.SendFlags |= 32;
+ int new_cnt = (e.cnt & BIT(7)) | (i & BITS(7));
+ if (new_cnt != e.cnt || col != e.colormod)
+ {
+ e.cnt = new_cnt;
+ e.colormod = col;
+ e.SendFlags |= 32;
+ }
}
void WaypointSprite_Ping(entity e)