]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/common/mutators/mutator/waypoints/waypointsprites.qc
Merge branch 'bones_was_here/sv_legacy_bbox_expand_4' into 'master'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / waypoints / waypointsprites.qc
index a9e1c5f57dd2996c7f5c6cf79b365cd11de84d60..f19fc059e393661839737c680b3089491e7bd4db 100644 (file)
@@ -5,7 +5,6 @@ REGISTER_MUTATOR(waypointsprites, true);
 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);
@@ -15,17 +14,14 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
     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);
@@ -69,8 +65,8 @@ bool WaypointSprite_SendEntity(entity this, entity to, float sendflags)
     {
         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)
@@ -107,7 +103,6 @@ void Ent_RemoveWaypointSprite(entity this)
     strfree(this.netname3);
 }
 
-/** flags origin [team displayrule] [spritename] [spritename2] [spritename3] [lifetime maxdistance hideable] */
 void Ent_WaypointSprite(entity this, bool isnew)
 {
     int sendflags = ReadByte();
@@ -213,10 +208,10 @@ void Ent_WaypointSprite(entity this, bool isnew)
 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;
@@ -224,8 +219,8 @@ float spritelookupblinkvalue(entity this, string s)
 
 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);
@@ -238,8 +233,8 @@ string spritelookuptext(entity this, string s)
        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))
     {
@@ -257,9 +252,9 @@ string spritelookuptext(entity this, string 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))
     {
@@ -296,7 +291,7 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve
     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);
@@ -306,7 +301,7 @@ void drawrotpic(vector org, float rot, string pic, vector sz, vector hotspot, ve
 
 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);
@@ -354,7 +349,7 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
     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);
@@ -362,7 +357,7 @@ vector drawspritearrow(vector o, float ang, vector rgb, float a, float t)
     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);
@@ -536,10 +531,12 @@ void Draw_WaypointSprite(entity this)
     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')
@@ -686,8 +683,8 @@ void Draw_WaypointSprite(entity this)
        }
 
        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);
@@ -695,14 +692,19 @@ void Draw_WaypointSprite(entity this)
             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';
     }
 
@@ -720,7 +722,7 @@ void Draw_WaypointSprite(entity this)
             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,
@@ -741,7 +743,7 @@ void Draw_WaypointSprite(entity this)
     }
     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();
@@ -879,9 +881,13 @@ void WaypointSprite_UpdateTeamRadar(entity e, entity icon, vector col)
 {
     // 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)