From: terencehill Date: Wed, 6 Jul 2022 13:28:34 +0000 (+0200) Subject: Merge branch 'master' into terencehill/lms_updates X-Git-Tag: xonotic-v0.8.6~426^2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=8738750fed941e32330bc7d92bf0847e0fff02c2;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into terencehill/lms_updates # Conflicts: # gamemodes-server.cfg # notifications.cfg # qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc # qcsrc/common/notifications/all.inc --- 8738750fed941e32330bc7d92bf0847e0fff02c2 diff --cc gamemodes-server.cfg index 41744478c,318749021..a57c8f135 --- a/gamemodes-server.cfg +++ b/gamemodes-server.cfg @@@ -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" // ========= diff --cc notifications.cfg index 131b3060c,ecd6c0b24..732ed5fae --- a/notifications.cfg +++ b/notifications.cfg @@@ -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 diff --cc qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc index 571528c06,9a210262b..e3ebfefd3 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc @@@ -7,29 -7,12 +7,32 @@@ #include 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! diff --cc qcsrc/common/notifications/all.inc index 382fd367d,92b4c8f16..69483bfc3 --- a/qcsrc/common/notifications/all.inc +++ b/qcsrc/common/notifications/all.inc @@@ -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..."), "")