Merge branch 'master' into martin-t/damagetext
authorMartin Taibr <taibr.martin@gmail.com>
Sun, 19 Feb 2017 12:44:54 +0000 (13:44 +0100)
committerMartin Taibr <taibr.martin@gmail.com>
Sun, 19 Feb 2017 12:44:54 +0000 (13:44 +0100)
1  2 
defaultXonotic.cfg
qcsrc/common/mutators/mutator/damagetext/damagetext.qc

diff --combined defaultXonotic.cfg
@@@ -60,7 -60,7 +60,7 @@@ _cl_playerskin 
  
  seta cl_reticle 1 "enable zoom reticles"
  seta cl_reticle_stretch 0 "stretch reticles so they fit the screen (breaks image proportions)"
- seta cl_reticle_normal 1 "draw an aiminig reticle when zooming with the zoom button"
+ seta cl_reticle_normal 1 "draw an aiming reticle when zooming with the zoom button"
  seta cl_reticle_normal_alpha 1 "alpha of the normal reticle"
  seta cl_reticle_weapon 1 "draw custom aiming reticle when zooming with certain weapons"
  seta cl_reticle_weapon_alpha 1 "alpha of the custom reticle"
@@@ -237,6 -237,11 +237,11 @@@ seta cl_eventchase_maxs "12 12 8" "max 
  seta cl_eventchase_mins "-12 -12 -8" "min size of eventchase camera bbox"
  seta cl_eventchase_viewoffset "0 0 20" "viewoffset of eventchase camera"
  seta cl_eventchase_generator_viewoffset "0 0 80" "viewoffset of eventchase camera while viewing generator explosion"
+ seta cl_eventchase_vehicle 1 "camera goes into 3rd person mode when inside a vehicle"
+ seta cl_eventchase_vehicle_viewoffset "0 0 80"
+ seta cl_eventchase_vehicle_distance 250
+ set _vehicles_shownchasemessage 0
  
  //nifreks lockonrestart feature, used in team-based game modes, if set to 1 and all players readied up no other player can then join the game anymore, useful to block spectators from joining
  set teamplay_lockonrestart 0 "lock teams once all players readied up and the game restarted (no new players can join after restart unless using the server-command unlockteams)"
@@@ -370,24 -375,24 +375,24 @@@ set bot_ai_aimskill_think 1 "Aiming vel
  set bot_ai_custom_weapon_priority_distances "300 850" "Define close and far distances in any order. Based on the distance to the enemy bots will choose different weapons"
  set bot_ai_custom_weapon_priority_far   "vaporizer vortex rifle electro devastator mortar hagar hlac crylink blaster machinegun fireball seeker shotgun shockwave tuba minelayer"     "Desired weapons for far distances ordered by priority"
  set bot_ai_custom_weapon_priority_mid   "vaporizer devastator vortex fireball seeker mortar electro machinegun arc crylink hlac hagar shotgun shockwave blaster rifle tuba minelayer" "Desired weapons for middle distances ordered by priority"
- set bot_ai_custom_weapon_priority_close "vaporizer shotgun shockwave vortex machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer" "Desired weapons for close distances ordered by priority"
+ set bot_ai_custom_weapon_priority_close "vaporizer vortex shotgun shockwave machinegun arc hlac tuba seeker hagar crylink mortar electro devastator blaster fireball rifle minelayer" "Desired weapons for close distances ordered by priority"
  set bot_ai_weapon_combo 1     "Enable bots to do weapon combos"
  set bot_ai_weapon_combo_threshold 0.4 "Try to make a combo N seconds after the last attack"
  set bot_ai_friends_aware_pickup_radius "500"  "Bots will not pickup items if a team mate is this distance near the item"
  set bot_ai_ignoregoal_timeout 3       "Ignore goals making bots to get stuck in front of a wall for N seconds"
  set bot_ai_bunnyhop_skilloffset 7     "Bots with skill equal or greater than this value will perform the  \"bunnyhop\" technique"
  set bot_ai_bunnyhop_startdistance 200 "Run to goals located further than this distance"
- set bot_ai_bunnyhop_stopdistance 200 "Stop jumping after reaching this distance to the goal"
+ set bot_ai_bunnyhop_stopdistance 300 "Stop jumping after reaching this distance to the goal"
  set bot_ai_bunnyhop_firstjumpdelay 0.2 "Start running to the goal only if it was seen for more than N seconds"
  set bot_god 0 "god mode for bots"
  set bot_ai_navigation_jetpack 0 "Enable bots to navigate maps using the jetpack"
  set bot_ai_navigation_jetpack_mindistance 3500 "Bots will try fly to objects located farther than this distance"
  // Better don't touch these, there are hard to tweak!
  set bot_ai_aimskill_order_mix_1st 0.01 "Amount of the 1st filter output to apply to the aiming angle"
- set bot_ai_aimskill_order_mix_2nd 0.1 "Amount of the 1st filter output to apply to the aiming angle"
- set bot_ai_aimskill_order_mix_3th 0.01 "Amount of the 1st filter output to apply to the aiming angle"
- set bot_ai_aimskill_order_mix_4th 0.05 "Amount of the 1st filter output to apply to the aiming angle"
- set bot_ai_aimskill_order_mix_5th 0.01 "Amount of the 1st filter output to apply to the aiming angle"
+ set bot_ai_aimskill_order_mix_2nd 0.1 "Amount of the 2nd filter output to apply to the aiming angle"
+ set bot_ai_aimskill_order_mix_3th 0.01 "Amount of the 3th filter output to apply to the aiming angle"
+ set bot_ai_aimskill_order_mix_4th 0.05 "Amount of the 4th filter output to apply to the aiming angle"
+ set bot_ai_aimskill_order_mix_5th 0.01 "Amount of the 5th filter output to apply to the aiming angle"
  set bot_ai_aimskill_order_filter_1st 0.4 "Position filter"
  set bot_ai_aimskill_order_filter_2nd 0.4 "Movement filter"
  set bot_ai_aimskill_order_filter_3th 0.2 "Acceleration filter"
@@@ -786,13 -791,9 +791,13 @@@ seta g_waypointsprite_tactical 1 "tacti
  seta cl_damagetext "1" "Draw damage dealt where you hit the enemy"
  seta cl_damagetext_format "-{total}" "How to format the damage text. {health}, {armor}, {total}, {potential}: full damage not capped to target's health, {potential_health}: health damage not capped to target's health"
  seta cl_damagetext_format_verbose 0 "{health} shows {potential_health} too when they differ; {total} shows {potential} too when they differ"
 +seta cl_damagetext_format_hide_redundant 0 "hide {armor} if 0; hide {potential} and {potential_health} when same as actual"
  seta cl_damagetext_color "1 1 0" "Damage text color"
  seta cl_damagetext_color_per_weapon "0" "Damage text uses weapon color"
 -seta cl_damagetext_size "8" "Damage text font size"
 +seta cl_damagetext_size_min 8 "Damage text font size for small damage"
 +seta cl_damagetext_size_min_damage 0 "How much damage is considered small"
 +seta cl_damagetext_size_max 16 "Damage text font size for large damage"
 +seta cl_damagetext_size_max_damage 100 "How much damage is considered large"
  seta cl_damagetext_alpha_start "1" "Damage text initial alpha"
  seta cl_damagetext_alpha_lifetime "3" "Damage text lifetime in seconds"
  seta cl_damagetext_velocity "0 0 20" "Damage text move direction"
@@@ -802,6 -803,13 +807,13 @@@ seta cl_damagetext_accumulate_alpha_re
  seta cl_damagetext_friendlyfire "1" "Show damage text for friendlyfire too"
  seta cl_damagetext_friendlyfire_color "1 0 0" "Damage text color for friendlyfire"
  
+ seta cl_vehicles_alarm 1 "Play an alarm sound when the vehicle you are driving is heavily damaged"
+ seta cl_vehicles_hud_tactical 1
+ seta cl_vehicles_hudscale 0.5
+ seta cl_vehicles_notify_time 15
+ seta cl_vehicles_crosshair_size 0.5
+ seta cl_vehicles_crosshair_colorize 1
  set sv_itemstime 1 "enable networking of time left until respawn for items such as mega health/armor and powerups"
  
  // so it can be stuffcmd-ed still
@@@ -1064,7 -1072,7 +1076,7 @@@ alias gl_flashblend_update "_gl_flashbl
  
  set sv_clones 0       "number of clones a player may make (reset by the \"kill\" command)"
  
- set cl_handicap 1     "the higher, the more damage you will receive (client setting) NOTE: reconnect or use sendcvar command to update the choice."
+ set cl_handicap 1     "multiplies damage received and divides damage dealt NOTE: reconnect or use 'sendcvar cl_handicap' to update the choice."
  
  seta cl_clippedspectating 1 "movement collision for spectators so that you can't pass through walls and such. (client setting) NOTE: reconnect or use sendcvar command to update the choice."
  
@@@ -1227,6 -1235,10 +1239,10 @@@ set _campaign_testrun 0 "To verify the 
  // debug
  set _independent_players 0 "DO NOT TOUCH"
  set _notarget 0 "NO, REALLY, DON'T"
+ set debugdraw 0
+ set debugdraw_filter ""
+ set debugdraw_filterout ""
+ set debugtrace 0
  
  // define some engine cvars that we need even on dedicated server
  set r_showbboxes 0
@@@ -1382,8 -1394,12 +1398,12 @@@ set g_frozen_revive_falldamage_health 4
  set g_frozen_damage_trigger 1 "if 1, frozen players falling into the void will die instead of teleporting to spawn"
  set g_frozen_force 0.6 "How much to multiply the force on a frozen player with"
  
- // player statistics server URI
+ // player statistics
  set g_playerstats_gamereport_uri "http://stats.xonotic.org/stats/submit" "Output player statistics information to either: URL (with ://), console (with a dash like this: -), or supply a filename to output to data directory."
+ set g_playerstats_gamereport_ladder ""
+ set g_playerstats_playerbasic_uri "http://stats.xonotic.org"
+ set g_playerstats_playerdetail_uri "http://stats.xonotic.org/player/me"
+ set g_playerstats_playerdetail_autoupdatetime 1800 // automatically update every 30 minutes anyway
  
  // autoscreenshots
  set g_max_info_autoscreenshot 3 "how many info_autoscreenshot entities are allowed"
@@@ -12,26 -12,18 +12,27 @@@ const int DTFLAG_NO_POTENTIAL = BIT(5)
  
  REGISTER_MUTATOR(damagetext, true);
  
- #if defined(CSQC) || defined(MENUQC)
+ // || defined(MENUQC)
+ #if defined(CSQC)
  // no translatable cvar description please
  AUTOCVAR_SAVE(cl_damagetext,                        bool,   true,       "Draw damage dealt where you hit the enemy");
  AUTOCVAR_SAVE(cl_damagetext_format,                 string, "-{total}", "How to format the damage text. {health}, {armor}, {total}, {potential}: full damage not capped to target's health, {potential_health}: health damage not capped to target's health");
  AUTOCVAR_SAVE(cl_damagetext_format_verbose,         bool,   false,      "{health} shows {potential_health} too when they differ; {total} shows {potential} too when they differ");
 +AUTOCVAR_SAVE(cl_damagetext_format_hide_redundant,  bool,   false,      "hide {armor} if 0; hide {potential} and {potential_health} when same as actual");
  STATIC_INIT(DamageText_LegacyFormat) {
 -    if (strstrofs(autocvar_cl_damagetext_format, "{", 0) < 0) autocvar_cl_damagetext_format = "-{total}";
 +    // damagetext used to be off by default and the cvar got saved in people's configs along with the old format
 +    // enable damagetext while updating the format for a one time effect
 +    if (strstrofs(autocvar_cl_damagetext_format, "{", 0) < 0) {
 +        localcmd("\nseta cl_damagetext 1\n");
 +        localcmd("\nseta cl_damagetext_format -{total}\n");
 +    };
  }
  AUTOCVAR_SAVE(cl_damagetext_color,                  vector, '1 1 0',    "Damage text color");
  AUTOCVAR_SAVE(cl_damagetext_color_per_weapon,       bool,   false,      "Damage text uses weapon color");
 -AUTOCVAR_SAVE(cl_damagetext_size,                   float,  8,          "Damage text font size");
 +AUTOCVAR_SAVE(cl_damagetext_size_min,               float,  8,          "Damage text font size for small damage");
 +AUTOCVAR_SAVE(cl_damagetext_size_min_damage,        float,  0,          "How much damage is considered small");
 +AUTOCVAR_SAVE(cl_damagetext_size_max,               float,  16,         "Damage text font size for large damage");
 +AUTOCVAR_SAVE(cl_damagetext_size_max_damage,        float,  100,        "How much damage is considered large");
  AUTOCVAR_SAVE(cl_damagetext_alpha_start,            float,  1,          "Damage text initial alpha");
  AUTOCVAR_SAVE(cl_damagetext_alpha_lifetime,         float,  3,          "Damage text lifetime in seconds");
  AUTOCVAR_SAVE(cl_damagetext_velocity,               vector, '0 0 20',   "Damage text move direction");
@@@ -46,18 -38,17 +47,18 @@@ AUTOCVAR_SAVE(cl_damagetext_friendlyfir
  CLASS(DamageText, Object)
      ATTRIB(DamageText, m_color, vector, autocvar_cl_damagetext_color);
      ATTRIB(DamageText, m_color_friendlyfire, vector, autocvar_cl_damagetext_friendlyfire_color);
 -    ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size);
 +    ATTRIB(DamageText, m_size, float, autocvar_cl_damagetext_size_min);
      ATTRIB(DamageText, alpha, float, autocvar_cl_damagetext_alpha_start);
      ATTRIB(DamageText, fade_rate, float, 1 / autocvar_cl_damagetext_alpha_lifetime);
      ATTRIB(DamageText, velocity, vector, autocvar_cl_damagetext_velocity);
      ATTRIB(DamageText, m_group, int, 0);
      ATTRIB(DamageText, m_friendlyfire, bool, false);
 -    ATTRIB(DamageText, m_damage, int, 0);
 +    ATTRIB(DamageText, m_healthdamage, int, 0);
      ATTRIB(DamageText, m_armordamage, int, 0);
      ATTRIB(DamageText, m_potential_damage, int, 0);
      ATTRIB(DamageText, m_deathtype, int, 0);
      ATTRIB(DamageText, time_prev, float, time);
 +    ATTRIB(DamageText, text, string, string_null);
  
      void DamageText_draw2d(DamageText this) {
          float dt = time - this.time_prev;
              vector rgb;
              if (this.m_friendlyfire) {
                  rgb = this.m_color_friendlyfire;
 -            }
 -            else {
 +            } else {
                  rgb = this.m_color;
              }
              if (autocvar_cl_damagetext_color_per_weapon) {
                  Weapon w = DEATH_WEAPONOF(this.m_deathtype);
                  if (w != WEP_Null) rgb = w.wpcolor;
              }
 -            int health = rint(this.m_damage / DAMAGETEXT_PRECISION_MULTIPLIER);
 -            int total = rint((this.m_damage + this.m_armordamage) / DAMAGETEXT_PRECISION_MULTIPLIER);
 -            int potential = rint(this.m_potential_damage / DAMAGETEXT_PRECISION_MULTIPLIER);
 -            int potential_health = rint((this.m_potential_damage - this.m_armordamage) / DAMAGETEXT_PRECISION_MULTIPLIER);
 -
 -            string s = autocvar_cl_damagetext_format;
 -            s = strreplace("{armor}",  sprintf("%d", rint(this.m_armordamage / DAMAGETEXT_PRECISION_MULTIPLIER)), s);
 -            s = strreplace("{potential}",  sprintf("%d", potential), s);
 -            s = strreplace("{potential_health}",  sprintf("%d", potential_health), s);
 -
 -            s = strreplace("{health}", (
 -                              (health == potential_health || !autocvar_cl_damagetext_format_verbose)
 -                              ? sprintf("%d",      health)
 -                              : sprintf("%d (%d)", health, potential_health)
 -              ), s);
 -            s = strreplace("{total}", (
 -                              (total == potential || !autocvar_cl_damagetext_format_verbose)
 -                              ? sprintf("%d",      total)
 -                              : sprintf("%d (%d)", total, potential)
 -              ), s);
 -            drawcolorcodedstring2_builtin(pos, s, this.m_size * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL);
 +
 +            vector drawfontscale_save = drawfontscale;
 +            drawfontscale = (this.m_size / autocvar_cl_damagetext_size_max) * '1 1 0';
 +            drawcolorcodedstring2_builtin(pos, this.text, autocvar_cl_damagetext_size_max * '1 1 0', rgb, this.alpha, DRAWFLAG_NORMAL);
 +            drawfontscale = drawfontscale_save;
          }
      }
      ATTRIB(DamageText, draw2d, void(DamageText), DamageText_draw2d);
  
      void DamageText_update(DamageText this, vector _origin, int _health, int _armor, int _potential_damage, int _deathtype) {
 -        this.m_damage = _health;
 +        this.m_healthdamage = _health;
          this.m_armordamage = _armor;
          this.m_potential_damage = _potential_damage;
          this.m_deathtype = _deathtype;
          setorigin(this, _origin);
          this.alpha = autocvar_cl_damagetext_alpha_start;
 +
 +        int health = rint(this.m_healthdamage / DAMAGETEXT_PRECISION_MULTIPLIER);
 +        int armor = rint(this.m_armordamage / DAMAGETEXT_PRECISION_MULTIPLIER);
 +        int total = rint((this.m_healthdamage + this.m_armordamage) / DAMAGETEXT_PRECISION_MULTIPLIER);
 +        int potential = rint(this.m_potential_damage / DAMAGETEXT_PRECISION_MULTIPLIER);
 +        int potential_health = rint((this.m_potential_damage - this.m_armordamage) / DAMAGETEXT_PRECISION_MULTIPLIER);
 +
 +        string s = autocvar_cl_damagetext_format;
 +        s = strreplace("{armor}", (
 +            (this.m_armordamage == 0 && autocvar_cl_damagetext_format_hide_redundant)
 +                ? ""
 +                : sprintf("%d", armor)
 +            ), s);
 +        s = strreplace("{potential}", (
 +            (this.m_potential_damage == this.m_healthdamage + this.m_armordamage && autocvar_cl_damagetext_format_hide_redundant)
 +                ? ""
 +                : sprintf("%d", potential)
 +            ), s);
 +        s = strreplace("{potential_health}", (
 +            (this.m_potential_damage - this.m_armordamage == this.m_healthdamage && autocvar_cl_damagetext_format_hide_redundant)
 +                ? ""
 +                : sprintf("%d", potential_health)
 +            ), s);
 +
 +        s = strreplace("{health}", (
 +            (health == potential_health || !autocvar_cl_damagetext_format_verbose)
 +                ? sprintf("%d",      health)
 +                : sprintf("%d (%d)", health, potential_health)
 +            ), s);
 +        s = strreplace("{total}", (
 +            (total == potential || !autocvar_cl_damagetext_format_verbose)
 +                ? sprintf("%d",      total)
 +                : sprintf("%d (%d)", total, potential)
 +            ), s);
 +
 +        // futureproofing: remove any remaining (unknown) format strings in case we add new ones in the future
 +        // so players can use them on new servers and still have working damagetext on old ones
 +        while (true) {
 +            int opening_pos = strstrofs(s, "{", 0);
 +            if (opening_pos == -1) break;
 +            int closing_pos = strstrofs(s, "}", opening_pos);
 +            if (closing_pos == -1 || closing_pos <= opening_pos) break;
 +            s = strcat(
 +                substring(s, 0, opening_pos),
 +                substring_range(s, closing_pos + 1, strlen(s))
 +            );
 +        }
 +
 +        if (this.text) strunzone(this.text);
 +        this.text = strzone(s);
 +
 +        float size_range = autocvar_cl_damagetext_size_max - autocvar_cl_damagetext_size_min;
 +        float damage_range = autocvar_cl_damagetext_size_max_damage - autocvar_cl_damagetext_size_min_damage;
 +        float scale_factor = size_range / damage_range;
 +        this.m_size = bound(
 +            autocvar_cl_damagetext_size_min,
 +            (potential - autocvar_cl_damagetext_size_min_damage) * scale_factor + autocvar_cl_damagetext_size_min,
 +            autocvar_cl_damagetext_size_max);
      }
  
      CONSTRUCTOR(DamageText, int _group, vector _origin, int _health, int _armor, int _potential_damage, int _deathtype, bool _friendlyfire) {
          DamageText_update(this, _origin, _health, _armor, _potential_damage, _deathtype);
                IL_PUSH(g_drawables_2d, this);
      }
 +
 +    DESTRUCTOR(DamageText) {
 +        if (this.text) strunzone(this.text);
 +    }
  ENDCLASS(DamageText)
  #endif
  
  REGISTER_NET_TEMP(damagetext)
  
  #ifdef SVQC
- AUTOCVAR(sv_damagetext, int, 2, _("<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players"));
+ AUTOCVAR(sv_damagetext, int, 2, "<= 0: disabled, >= 1: spectators, >= 2: players, >= 3: all players");
  #define SV_DAMAGETEXT_DISABLED()        (autocvar_sv_damagetext <= 0 /* disabled */)
  #define SV_DAMAGETEXT_SPECTATORS_ONLY() (autocvar_sv_damagetext >= 1 /* spectators only */)
  #define SV_DAMAGETEXT_PLAYERS()         (autocvar_sv_damagetext >= 2 /* players */)
@@@ -256,7 -202,7 +257,7 @@@ NET_HANDLE(damagetext, bool isNew
          if (autocvar_cl_damagetext_accumulate_range) {
              for (entity e = findradius(location, autocvar_cl_damagetext_accumulate_range); e; e = e.chain) {
                  if (e.instanceOfDamageText && e.m_group == group && e.alpha > autocvar_cl_damagetext_accumulate_alpha_rel * autocvar_cl_damagetext_alpha_start) {
 -                    DamageText_update(e, location, e.m_damage + health, e.m_armordamage + armor, e.m_potential_damage + potential_damage, deathtype);
 +                    DamageText_update(e, location, e.m_healthdamage + health, e.m_armordamage + armor, e.m_potential_damage + potential_damage, deathtype);
                      return;
                  }
              }
@@@ -284,14 -230,9 +285,14 @@@ CLASS(XonoticDamageTextSettings, Xonoti
          this.gotoRC(this, 0, 1); this.setFirstColumn(this, this.currentColumn);
              this.TD(this, 1, 3, makeXonoticCheckBox(0, "cl_damagetext", _("Draw damage numbers")));
          this.TR(this);
 -            this.TD(this, 1, 1, e = makeXonoticTextLabel(0, _("Font size:")));
 +            this.TD(this, 1, 1, e = makeXonoticTextLabel(0, _("Font size minimum:")));
 +                setDependent(e, "cl_damagetext", 1, 1);
 +            this.TD(this, 1, 2, e = makeXonoticSlider(0, 50, 1, "cl_damagetext_size_min"));
 +                setDependent(e, "cl_damagetext", 1, 1);
 +        this.TR(this);
 +            this.TD(this, 1, 1, e = makeXonoticTextLabel(0, _("Font size maximum:")));
                  setDependent(e, "cl_damagetext", 1, 1);
 -            this.TD(this, 1, 2, e = makeXonoticSlider(0, 50, 1, "cl_damagetext_size"));
 +            this.TD(this, 1, 2, e = makeXonoticSlider(0, 50, 1, "cl_damagetext_size_max"));
                  setDependent(e, "cl_damagetext", 1, 1);
          this.TR(this);
              this.TD(this, 1, 1, e = makeXonoticTextLabel(0, _("Accumulate range:")));