Merge branch 'master' into terencehill/lms_updates 808/head
authorterencehill <piuntn@gmail.com>
Wed, 6 Jul 2022 13:28:34 +0000 (15:28 +0200)
committerterencehill <piuntn@gmail.com>
Wed, 6 Jul 2022 13:28:34 +0000 (15:28 +0200)
# Conflicts:
# gamemodes-server.cfg
# notifications.cfg
# qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
# qcsrc/common/notifications/all.inc

1  2 
gamemodes-server.cfg
notifications.cfg
qcsrc/common/gamemodes/gamemode/lms/cl_lms.qc
qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc
qcsrc/common/notifications/all.inc

index 41744478cec0b66f9eb8c094dcfd01372e031585,318749021fe8d329ae55e6cbb58de4eafb3486ef..a57c8f135c70aa561cf68ee2a0e52bb02aa80947
@@@ -445,24 -445,13 +445,27 @@@ set g_keyhunt_team_spawns 0 "when 1, pl
  set g_lms 0 "Last Man Standing: everyone starts with a certain amount of lives, and the survivor wins"
  set g_lms_lives_override -1
  set g_lms_extra_lives 0
- set g_lms_regenerate 0
+ set g_lms_regenerate 0 "health and/or armor regeneration, according to g_balance_health_regen and g_balance_armor_regen"
+ set g_lms_rot 0 "health and/or armor rotting, according to g_balance_health_rot and g_balance_armor_rot"
  set g_lms_last_join 3 "if g_lms_join_anytime is 0, new players can only join if the worst active player has (fraglimit - g_lms_last_join) or more lives; in other words, new players can no longer join once the worst player loses more than g_lms_last_join lives"
  set g_lms_join_anytime 1      "1: new players can join, but get same amount of lives as the worst player; 0: new players can only join if the worst active player has (fraglimit - g_lms_last_join) or more lives"
+ set g_lms_items 0 "enables items to spawn, weaponarena still disables weapons and ammo (to force all items to spawn, use g_pickup_items 1 instead)"
  set g_lms_weaponarena "most_available" "starting weapons - takes the same options as g_weaponarena"
 +set g_lms_leader_lives_diff 2 "players leading by at least this number of lives are considered leaders and are more visible"
 +set g_lms_leader_minpercent 0.5 "leading players are not considered leaders only if they are more than this percentage of total players"
 +set g_lms_leader_wp_time 5 "show waypoints for leaders only for this amount of time"
 +set g_lms_leader_wp_interval 25 "periodically show again waypoints for leaders after this amount of time"
 +set g_lms_leader_wp_interval_jitter 10 "jitter waypoint interval by this amount of time"
 +set g_lms_dynamic_respawn_delay 1 "increase player respawn delay based on the number of lives less than the leader (NOTE: delay doesn't increase when only 2 players are left alive)"
 +set g_lms_dynamic_respawn_delay_base 2 "base player respawn delay"
 +set g_lms_dynamic_respawn_delay_increase 3 "increase base player respawn delay by this amount of time for each life less than the leader"
 +set g_lms_dynamic_respawn_delay_max 20 "max player respawn delay"
 +set g_lms_dynamic_vampire 1 "attackers receive a fraction of health removed from enemies based on the number of lives less than the enemy"
 +set g_lms_dynamic_vampire_factor_base 0.1 "base vampire factor"
 +set g_lms_dynamic_vampire_factor_increase 0.1 "increase vampire factor by this fraction for each life less than the enemy"
 +set g_lms_dynamic_vampire_factor_max 0.5 "max vampire factor"
 +set g_lms_dynamic_vampire_min_lives_diff 2 "number of lives the attacker must have less than the enemy to receive the base fraction of health"
+ set g_lms_forfeit_min_match_time 30 "end the match early if at least this many seconds have elapsed and less than 2 players are playing due to forfeits"
  
  
  // =========
index 131b3060cccd6ad49179734cde3c98d32a439496,ecd6c0b24004e455cb9fd608aecb764defa4b506..732ed5faec28f19209e3f12cb1fdd1d9270df378
@@@ -480,8 -480,7 +480,9 @@@ seta notification_CENTER_KEYHUNT_ROUNDS
  seta notification_CENTER_KEYHUNT_SCAN "1" "0 = off, 1 = centerprint"
  seta notification_CENTER_KEYHUNT_START "1" "0 = off, 1 = centerprint"
  seta notification_CENTER_LMS_NOLIVES "1" "0 = off, 1 = centerprint"
+ seta notification_CENTER_LMS_SPECWARN "1" "0 = off, 1 = centerprint"
 +seta notification_CENTER_LMS_VISIBLE_LEADER "1" "0 = off, 1 = centerprint"
 +seta notification_CENTER_LMS_VISIBLE_OTHER "1" "0 = off, 1 = centerprint"
  seta notification_CENTER_MISSING_PLAYERS "1" "0 = off, 1 = centerprint"
  seta notification_CENTER_MISSING_TEAMS "1" "0 = off, 1 = centerprint"
  seta notification_CENTER_MOTD "1" "0 = off, 1 = centerprint"
@@@ -748,4 -748,4 +750,4 @@@ seta notification_show_sprees_info "3" 
  seta notification_show_sprees_info_newline "1" "Show attacker spree information for MSG_INFO messages on a separate line than the death notification itself"
  seta notification_show_sprees_info_specialonly "1" "Don't show attacker spree information in MSG_INFO messages if it isn't an achievement"
  
- // Notification counts (total = 841): MSG_ANNCE = 80, MSG_INFO = 334, MSG_CENTER = 243, MSG_MULTI = 156, MSG_CHOICE = 28
 -// Notification counts (total = 841): MSG_ANNCE = 80, MSG_INFO = 335, MSG_CENTER = 241, MSG_MULTI = 157, MSG_CHOICE = 28
++// Notification counts (total = 843): MSG_ANNCE = 80, MSG_INFO = 335, MSG_CENTER = 243, MSG_MULTI = 157, MSG_CHOICE = 28
index 571528c069475d37736086cbe57d84d528b5125c,9a210262b68e80b8b1c8b323a81739f8f8111f94..e3ebfefd31fc9a6562590a1650ffc9b506b1e5d9
@@@ -7,29 -7,12 +7,32 @@@
  #include <server/items/items.qh>
  
  int autocvar_g_lms_extra_lives;
+ float autocvar_g_lms_forfeit_min_match_time;
  bool autocvar_g_lms_join_anytime;
  int autocvar_g_lms_last_join;
+ bool autocvar_g_lms_items;
  bool autocvar_g_lms_regenerate;
 +int autocvar_g_lms_leader_lives_diff = 2;
 +float autocvar_g_lms_leader_minpercent = 0.5;
 +float autocvar_g_lms_leader_wp_interval = 25;
 +float autocvar_g_lms_leader_wp_interval_jitter = 10;
 +float autocvar_g_lms_leader_wp_time = 5;
 +float autocvar_g_lms_dynamic_respawn_delay = 1;
 +float autocvar_g_lms_dynamic_respawn_delay_base = 2;
 +float autocvar_g_lms_dynamic_respawn_delay_increase = 3;
 +float autocvar_g_lms_dynamic_respawn_delay_max = 20;
 +bool autocvar_g_lms_dynamic_vampire = 1;
 +float autocvar_g_lms_dynamic_vampire_factor_base = 0.1;
 +float autocvar_g_lms_dynamic_vampire_factor_increase = 0.1;
 +float autocvar_g_lms_dynamic_vampire_factor_max = 0.5;
 +int autocvar_g_lms_dynamic_vampire_min_lives_diff = 2;
 +
 +.float lms_leader;
 +int lms_leaders;
 +float lms_visible_leaders_time;
 +bool lms_visible_leaders = true; // triggers lms_visible_leaders_time update in the first frame
 +bool lms_visible_leaders_prev;
+ bool autocvar_g_lms_rot;
  
  // main functions
  int LMS_NewPlayerLives()
@@@ -426,65 -375,15 +449,67 @@@ MUTATOR_HOOKFUNCTION(lms, PlayerPreThin
                player.deadflag = DEAD_RESPAWNING;
  }
  
 +MUTATOR_HOOKFUNCTION(lms, SV_StartFrame)
 +{
 +      float leader_time = autocvar_g_lms_leader_wp_time;
 +      float leader_interval = leader_time + autocvar_g_lms_leader_wp_interval;
 +      lms_visible_leaders_prev = lms_visible_leaders;
 +      lms_visible_leaders = (time > lms_visible_leaders_time && time < lms_visible_leaders_time + leader_time);
 +      if (lms_visible_leaders_prev && !lms_visible_leaders)
 +              lms_visible_leaders_time = time + leader_interval + random() * autocvar_g_lms_leader_wp_interval_jitter;
 +
 +      lms_leaders = 0;
 +      FOREACH_CLIENT(true, {
 +              STAT(OBJECTIVE_STATUS, it) = lms_visible_leaders;
 +              if (IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME)
 +              {
 +                      if (it.lms_leader)
 +                      {
 +                              if (!it.waypointsprite_attachedforcarrier)
 +                              {
 +                                      WaypointSprite_AttachCarrier(WP_LmsLeader, it, RADARICON_FLAGCARRIER);
 +                                      it.waypointsprite_attachedforcarrier.waypointsprite_visible_for_player = lms_waypointsprite_visible_for_player;
 +                                      WaypointSprite_UpdateRule(it.waypointsprite_attachedforcarrier, 0, SPRITERULE_DEFAULT);
 +                                      vector pl_color = colormapPaletteColor(it.clientcolors & 0x0F, false);
 +                                      WaypointSprite_UpdateTeamRadar(it.waypointsprite_attachedforcarrier, RADARICON_FLAGCARRIER, pl_color);
 +                                      WaypointSprite_Ping(it.waypointsprite_attachedforcarrier);
 +                              }
 +                              if (!lms_visible_leaders_prev && lms_visible_leaders && IS_REAL_CLIENT(it))
 +                                      Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_LMS_VISIBLE_LEADER);
 +                              lms_leaders++;
 +                      }
 +                      else // if (!it.lms_leader)
 +                      {
 +                              if (IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME)
 +                              {
 +                                      if (!lms_visible_leaders_prev && lms_visible_leaders && IS_REAL_CLIENT(it))
 +                                              Send_Notification(NOTIF_ONE, it, MSG_CENTER, CENTER_LMS_VISIBLE_OTHER);
 +                              }
 +                              if (it.waypointsprite_attachedforcarrier)
 +                                      WaypointSprite_Kill(it.waypointsprite_attachedforcarrier);
 +                      }
 +              }
 +      });
 +}
 +
  MUTATOR_HOOKFUNCTION(lms, PlayerRegen)
  {
-       if(autocvar_g_lms_regenerate)
-               return false;
-       return true;
+       if(!autocvar_g_lms_regenerate)
+               M_ARGV(2, float) = 0;
+       if(!autocvar_g_lms_rot)
+               M_ARGV(3, float) = 0;
+       return (!autocvar_g_lms_regenerate && !autocvar_g_lms_rot);
  }
  
 +MUTATOR_HOOKFUNCTION(lms, PlayerPowerups)
 +{
 +      entity player = M_ARGV(0, entity);
 +      if (player.waypointsprite_attachedforcarrier)
 +              player.effects |= (EF_ADDITIVE | EF_FULLBRIGHT);
 +      else
 +              player.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT);
 +}
 +
  MUTATOR_HOOKFUNCTION(lms, ForbidThrowCurrentWeapon)
  {
        // forbode!
index 382fd367dee48a1e70ffed26ca7aae14d8217db5,92b4c8f16f8358ab64947820cf73596cce5fff26..69483bfc3c075b19427b39d1eb808c7b4d857075
@@@ -703,8 -704,7 +704,9 @@@ string multiteam_info_sprintf(string in
      MULTITEAM_CENTER(KEYHUNT_START,                     N_ENABLE,    0, 0, "",               CPID_KEYHUNT,           "0 0",  _("^BGYou are starting with the ^TC^TT Key"), "", KEY)
  
      MSG_CENTER_NOTIF(LMS_NOLIVES,                       N_ENABLE,    0, 0, "",               CPID_LMS,               "0 0",  _("^BGYou have no lives left, you must wait until the next match"), "")
+     MSG_CENTER_NOTIF(LMS_SPECWARN,                      N_ENABLE,    0, 0, "",               CPID_LMS,               "0 0",  _("^F4WARNING:^BG you can't rejoin this match after spectating.\nUse the same command again to spectate anyway."), "")
 +    MSG_CENTER_NOTIF(LMS_VISIBLE_LEADER,                N_ENABLE,    0, 0, "",               CPID_LMS,               "0 0",  _("^BGEnemies can now see you on radar!"), "")
 +    MSG_CENTER_NOTIF(LMS_VISIBLE_OTHER,                 N_ENABLE,    0, 0, "",               CPID_LMS,               "0 0",  _("^BGLeaders can now be seen by enemies on radar!"), "")
  
      MSG_CENTER_NOTIF(MISSING_TEAMS,                     N_ENABLE,    0, 1, "missing_teams",  CPID_MISSING_TEAMS,     "-1 0", _("^BGWaiting for players to join...\nNeed active players for: %s"), "")
      MSG_CENTER_NOTIF(MISSING_PLAYERS,                   N_ENABLE,    0, 1, "f1",             CPID_MISSING_PLAYERS,   "-1 0", _("^BGWaiting for %s player(s) to join..."), "")