]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'drjaska/new-defaults' into 'master'
authorLegendaryGuard <rootuser999@gmail.com>
Mon, 12 Jun 2023 00:27:50 +0000 (00:27 +0000)
committerLegendaryGuard <rootuser999@gmail.com>
Mon, 12 Jun 2023 00:27:50 +0000 (00:27 +0000)
Refined default values for mouse `sensitivity` (halved from 6 to 3) and `mastervolume` (9.0 to 7.0).

See merge request xonotic/xonotic-data.pk3dir!1192

29 files changed:
.tx/merge-base
commands.cfg
common.la.po
common.zh_CN.po
common.zh_HK.po
common.zh_TW.po
languages.txt
models/relics/sign_invisible.tga
models/relics/sign_speed.tga
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/ent_cs.qc
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/freezetag/sv_freezetag.qc
qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc
qcsrc/common/gamemodes/gamemode/survival/survival.qc
qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc
qcsrc/common/minigames/sv_minigames.qc
qcsrc/server/bot/default/bot.qc
qcsrc/server/client.qc
qcsrc/server/command/banning.qc
qcsrc/server/command/banning.qh
qcsrc/server/command/sv_cmd.qc
qcsrc/server/command/vote.qc
qcsrc/server/damage.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/weaponsystem.qc
qcsrc/server/world.qc
scripts/relics.shader
xonotic-server.cfg

index 398912c6b5e4886a1da6879749ae8c262765ce5a..6df328b856fe5f3c70154d317071f2418658565c 100644 (file)
@@ -1 +1 @@
-Sat 03 Jun 2023 07:22:57 AM CEST
+Sun 11 Jun 2023 07:22:57 AM CEST
index ea4a41396fcfad5a4619661232e016c036350490..308cd0b8e281dbb3245c5c21c830d11bc69d6d6f 100644 (file)
@@ -282,6 +282,8 @@ alias unmute               "qc_cmd_sv     unmute               ${* ?}" // Unmute
 alias bans      "qc_cmd_sv banlist ${* ?}"
 alias muteban   "qc_cmd_sv mute    ${* ?}"
 alias unmuteban "qc_cmd_sv unmute  ${* ?}"
+alias chatban   "qc_cmd_sv mute    ${* ?}"
+alias unchatban "qc_cmd_sv unmute  ${* ?}"
 
 
 
@@ -297,7 +299,8 @@ alias voteban                 "qc_cmd_sv     voteban              ${* ?}" // Ban
 alias unvoteban               "qc_cmd_sv     unvoteban            ${* ?}" // Remove an existing vote ban client
 
 // other aliases for muteban, playban and voteban lists
-alias mutebans  "g_muteban_list ${* ?}"
+alias mutebans  "g_chatban_list ${* ?}"
+alias chatbans  "g_chatban_list ${* ?}"
 alias playbans  "g_playban_list ${* ?}"
 alias votebans  "g_voteban_list ${* ?}"
 
index 2d4217afcb666985f3dbfd1b3c23fdb35b3831f6..b8925fbdf2a1e8041750aea9f0943f5924dfc848 100644 (file)
@@ -695,11 +695,11 @@ msgstr "SCO^pilport"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "Number of hunts (Survival)"
-msgstr ""
+msgstr "Quotiens venatus est (Superstites)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "SCO^hunts"
-msgstr ""
+msgstr "venatus"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:145
 msgid "Number of keys carrier kills"
@@ -847,11 +847,11 @@ msgstr "SCO^quot vicit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:164
 msgid "Number of rounds played"
-msgstr ""
+msgstr "Quot temporibus lusit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:164
 msgid "SCO^rounds played"
-msgstr ""
+msgstr "quot lusit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:165
 msgid "SCO^score"
@@ -879,11 +879,11 @@ msgstr "summa"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "Number of survivals"
-msgstr ""
+msgstr "Quotiens superstes fuit"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "SCO^survivals"
-msgstr ""
+msgstr "superstes"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:169
 msgid "Number of domination points taken (Domination)"
@@ -1639,19 +1639,21 @@ msgstr "Circumitus:"
 
 #: qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc:16
 msgid "Hunter"
-msgstr ""
+msgstr "Venator"
 
 #: qcsrc/common/gamemodes/gamemode/survival/cl_survival.qc:22
 msgid "Survivor"
-msgstr ""
+msgstr "Superstes"
 
 #: qcsrc/common/gamemodes/gamemode/survival/survival.qh:12
 msgid "Identify and eliminate all the hunters before all your allies are gone"
 msgstr ""
+"Supertites et venatores discerne, posteriores occide, ne omnes collegae tui "
+"moriantur"
 
 #: qcsrc/common/gamemodes/gamemode/survival/survival.qh:12
 msgid "Survival"
-msgstr ""
+msgstr "Supertites"
 
 #: qcsrc/common/gamemodes/gamemode/tdm/tdm.qh:9
 msgid "Help your team score the most frags against the enemy team"
@@ -1663,11 +1665,11 @@ msgstr "Manuum interfectio"
 
 #: qcsrc/common/gamemodes/gamemode/tka/tka.qh:13
 msgid "Keep the ball in your team's possession to get points for kills"
-msgstr ""
+msgstr "Age ut manus tua pilam teneat, ut rationi addetur cum interficies"
 
 #: qcsrc/common/gamemodes/gamemode/tka/tka.qh:13
 msgid "Team Keepaway"
-msgstr ""
+msgstr "Manuum Abhibitio"
 
 #: qcsrc/common/gamemodes/gamemode/tmayhem/tmayhem.qh:10
 msgid ""
@@ -2452,7 +2454,7 @@ msgstr "^1Moderatri notae:"
 
 #: qcsrc/common/notifications/all.inc:234
 msgid "^F4NOTE: ^BGChat is currently disabled on this server"
-msgstr ""
+msgstr "^F4NOTA: ^BGLocutorium hoc moderatro nunc vetatur"
 
 #: qcsrc/common/notifications/all.inc:235
 msgid "^F4NOTE: ^BGSpectator chat is not sent to players during the match"
@@ -2461,15 +2463,15 @@ msgstr ""
 
 #: qcsrc/common/notifications/all.inc:236
 msgid "^F4NOTE: ^BGPrivate chat is currently disabled on this server"
-msgstr ""
+msgstr "^F4NOTA: ^BGLocutorium privatum hoc moderatro nunc vetatur"
 
 #: qcsrc/common/notifications/all.inc:237
 msgid "^F4NOTE: ^BGSpectator chat is currently disabled on this server"
-msgstr ""
+msgstr "^F4NOTA: ^BGSpectatorum locutorium hoc moderatro nunc vetatur"
 
 #: qcsrc/common/notifications/all.inc:238
 msgid "^F4NOTE: ^BGTeam chat is currently disabled on this server"
-msgstr ""
+msgstr "^F4NOTA: ^BGManus locutorium hoc moderatro nunc vetatur"
 
 #: qcsrc/common/notifications/all.inc:240
 #, c-format
@@ -3354,7 +3356,7 @@ msgstr "^BG%s^F3 expulsus est quia manus collegas nimis interficiebat"
 #: qcsrc/common/notifications/all.inc:429
 #, c-format
 msgid "^BG%s^F3 was forced to spectate for excessive teamkilling"
-msgstr ""
+msgstr "^BG%s^F3 spectare debet quia manus collegas nimis interficiebat"
 
 #: qcsrc/common/notifications/all.inc:430
 #, c-format
@@ -3437,12 +3439,12 @@ msgstr "^BG%s^K1 Perarma tenet"
 #: qcsrc/common/notifications/all.inc:450
 #: qcsrc/common/notifications/all.inc:789
 msgid "^K1Hunters^BG win the round"
-msgstr ""
+msgstr "^K1Venatores^BG tempore vincunt"
 
 #: qcsrc/common/notifications/all.inc:451
 #: qcsrc/common/notifications/all.inc:791
 msgid "^F1Survivors^BG win the round"
-msgstr ""
+msgstr "^F1Superstites^BG tempore vincunt"
 
 #: qcsrc/common/notifications/all.inc:453
 msgid "^BGYou cannot change to a larger team"
@@ -3717,7 +3719,7 @@ msgstr ""
 #, c-format
 msgid ""
 "^BG%s^K1 blew themself up with their Overkill Rocket Propelled Chainsaw%s%s"
-msgstr ""
+msgstr "^BG%s^K1 Missilium Pellentium Serra Immoderata sua se rupit%s%s"
 
 #: qcsrc/common/notifications/all.inc:507
 #, c-format
@@ -3782,7 +3784,7 @@ msgstr ""
 #: qcsrc/common/notifications/all.inc:519
 #, c-format
 msgid "^BG%s^K1 is now thinking with portals%s%s"
-msgstr ""
+msgstr "^BG%s^K1 cum teleportis nunc cogitat%s%s"
 
 #: qcsrc/common/notifications/all.inc:520
 #, c-format
@@ -4414,6 +4416,8 @@ msgid ""
 "^K1You aren't allowed to play because you are banned in this server, but you "
 "can play minigames"
 msgstr ""
+"^K1Te ludere vetatur quia hoc moderatro expulsus es, sed ludos parvos ludere "
+"potes"
 
 #: qcsrc/common/notifications/all.inc:720
 msgid "^BGYou picked up the ball"
@@ -4421,7 +4425,7 @@ msgstr "^BGPilam cepisti"
 
 #: qcsrc/common/notifications/all.inc:721
 msgid "^BGGet the ball to score points for frags!"
-msgstr ""
+msgstr "^BGPilam cape ut rationi addetur cum interficies!"
 
 #: qcsrc/common/notifications/all.inc:723
 msgid ""
@@ -4655,7 +4659,7 @@ msgstr "^F2Invisibilitas evanuit"
 msgid ""
 "^K1You are forced to spectate and you aren't allowed to play because you are "
 "banned in this server"
-msgstr ""
+msgstr "^K1Spectare debes et te ludere vetatur quia hoc moderatro expulsus es"
 
 #: qcsrc/common/notifications/all.inc:778
 msgid "^F2The race is over, finish your lap!"
@@ -4690,11 +4694,11 @@ msgstr "^F2Perarma tenes"
 msgid ""
 "^BGYou are a ^K1hunter^BG! Eliminate the survivor(s) without raising "
 "suspicion!"
-msgstr ""
+msgstr "^BGEs ^K1venator^BG! Superstites occide, age ut ei non suspicentur!"
 
 #: qcsrc/common/notifications/all.inc:790
 msgid "^BGYou are a ^F1survivor^BG! Identify and eliminate the hunter(s)!"
-msgstr ""
+msgstr "^BGEs ^F1superstes^BG! Venatores discerne et occide!"
 
 #: qcsrc/common/notifications/all.inc:793
 msgid "^K1Changing to ^TC^TT^K1 in ^COUNT"
@@ -4754,11 +4758,11 @@ msgstr "^F2Irrumpens visus, scuta detrahuntur!"
 #: qcsrc/common/notifications/all.inc:809
 msgid ""
 "^K1You aren't allowed to call a vote because you are banned in this server"
-msgstr ""
+msgstr "^K1Te suffragia diribere vetatur quia hoc moderatro expulsus es"
 
 #: qcsrc/common/notifications/all.inc:810
 msgid "^K1You aren't allowed to vote because you are banned in this server"
-msgstr ""
+msgstr "^K1Suffragio privaris quia hoc moderatro expulsus es"
 
 #: qcsrc/common/notifications/all.qh:420 qcsrc/common/notifications/all.qh:421
 #, c-format
@@ -6067,7 +6071,7 @@ msgstr "Sinica (Sina)"
 
 #: qcsrc/menu/xonotic/credits.qc:180
 msgid "Chinese (Hong Kong)"
-msgstr ""
+msgstr "Sinica (Hong Cong)"
 
 #: qcsrc/menu/xonotic/credits.qc:193
 msgid "Chinese (Taiwan)"
@@ -6107,7 +6111,7 @@ msgstr "Hungarica"
 
 #: qcsrc/menu/xonotic/credits.qc:275
 msgid "Indonesian"
-msgstr ""
+msgstr "Indonesica"
 
 #: qcsrc/menu/xonotic/credits.qc:280
 msgid "Irish"
@@ -6131,7 +6135,7 @@ msgstr "Coreana"
 
 #: qcsrc/menu/xonotic/credits.qc:307
 msgid "Latin"
-msgstr ""
+msgstr "Latina"
 
 #: qcsrc/menu/xonotic/credits.qc:310
 msgid "Polish"
index 85d3c5f1f0fbc7217c7203611ca009a317ebfabe..9e9606387134b2237e06a272444c2ef6171dab81 100644 (file)
@@ -712,11 +712,11 @@ msgstr "进球"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "Number of hunts (Survival)"
-msgstr "ç\8c\8eæ\9d\80数(生存模式)"
+msgstr "ç\8b©ç\8c\8e次数(生存模式)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "SCO^hunts"
-msgstr "ç\8c\8eæ\9d\80"
+msgstr "ç\8b©ç\8c\8e"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:145
 msgid "Number of keys carrier kills"
@@ -896,7 +896,7 @@ msgstr "总和"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "Number of survivals"
-msgstr "生还数"
+msgstr "ç\94\9fè¿\98次æ\95°"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "SCO^survivals"
index d954d65063beac2efa21e550e4ffa674717ade27..43f1734b5d2615bd0122d00ec783dd371babe39c 100644 (file)
@@ -706,11 +706,11 @@ msgstr "進球"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "Number of hunts (Survival)"
-msgstr "ç\8dµæ®º數(生存模式)"
+msgstr "ç\8b©ç\8dµæ¬¡數(生存模式)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "SCO^hunts"
-msgstr "ç\8dµæ®º"
+msgstr "ç\8b©ç\8dµ"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:145
 msgid "Number of keys carrier kills"
@@ -890,7 +890,7 @@ msgstr "總和"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "Number of survivals"
-msgstr "生還數"
+msgstr "ç\94\9fé\82\84次æ\95¸"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "SCO^survivals"
index 5d076b141d2c982723717ab4f808bc560cbc195e..7aff493c4fc3cea642a1af7c70598aae20a238bc 100644 (file)
@@ -714,11 +714,11 @@ msgstr "進球"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "Number of hunts (Survival)"
-msgstr "ç\8dµæ®º數(生存模式)"
+msgstr "ç\8b©ç\8dµæ¬¡數(生存模式)"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:144
 msgid "SCO^hunts"
-msgstr "ç\8dµæ®º"
+msgstr "ç\8b©ç\8dµ"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:145
 msgid "Number of keys carrier kills"
@@ -898,7 +898,7 @@ msgstr "總和"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "Number of survivals"
-msgstr "生還數"
+msgstr "ç\94\9fé\82\84次æ\95¸"
 
 #: qcsrc/client/hud/panel/scoreboard.qc:168
 msgid "SCO^survivals"
index 6d62da3576f11f6ee565e5a6a5170129e8975745..ecac5aeb3b94758e962080512741e633a7f23be1 100644 (file)
@@ -8,7 +8,7 @@ es    "Spanish" "Español" 99%
 fr    "French" "Français" 100%
 ga    "Irish" "Irish" 29%
 it    "Italian" "Italiano" 100%
-la    "Latin" "Lingua Latina" 62%
+la    "Latin" "Lingua Latina" 63%
 hu    "Hungarian" "Magyar" 43%
 nl    "Dutch" "Nederlands" 61%
 pl    "Polish" "Polski" 79%
index de1745b09d168a21ab641ce439e51fc0b7ee419b..28b31a0b2eb386f3638fe0fb3325155ef64b9d8a 100644 (file)
Binary files a/models/relics/sign_invisible.tga and b/models/relics/sign_invisible.tga differ
index bca09682511e360c5e72fdb1827e577fb006326c..4deadbe34907b8c35d3318fa1ef7c7e9aeb9f761 100644 (file)
Binary files a/models/relics/sign_speed.tga and b/models/relics/sign_speed.tga differ
index f8b302b98737ad5a6b65ebf7e7ec94eb59f1a4dc..adcadb00df337aff2d15a23c9de42e855c1014a6 100644 (file)
@@ -735,13 +735,14 @@ void Cmd_Scoreboard_Help()
 // e.g. -teams,rc,cts,lms/kills ?+rc/kills
 #define SCOREBOARD_DEFAULT_COLUMNS \
 "ping pl fps name |" \
-" -teams,rc,cts,inv,lms/kills +ft,tdm,tmayhem/kills ?+rc,inv/kills" \
-" -teams,lms/deaths +ft,tdm,tmayhem/deaths" \
+" -teams,rc,cts,surv,inv,lms/kills +ft,tdm,tmayhem/kills ?+rc,inv/kills" \
+" -teams,surv,lms/deaths +ft,tdm,tmayhem/deaths" \
 " +tdm/sum" \
-" -teams,lms,rc,cts,inv,ka/suicides +ft,tdm,tmayhem/suicides ?+rc,inv/suicides" \
-" -cts,dm,tdm,ka,ft,mayhem,tmayhem/frags" /* tdm already has this in "score" */ \
+" -teams,lms,rc,cts,surv,inv,ka/suicides +ft,tdm,tmayhem/suicides ?+rc,inv/suicides" \
+" -cts,dm,tdm,surv,ka,ft,mayhem,tmayhem/frags" /* tdm already has this in "score" */ \
 " +tdm,ft,dom,ons,as,tmayhem/teamkills"\
-" -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
+" -rc,cts,surv,nb/dmg -rc,cts,surv,nb/dmgtaken" \
+" +surv/survivals +surv/hunts" \
 " +ctf/pickups +ctf/fckills +ctf/returns +ctf/caps +ons/takes +ons/caps" \
 " +lms/lives +lms/rank" \
 " +kh/kckills +kh/losses +kh/caps" \
@@ -972,7 +973,13 @@ string Scoreboard_GetName(entity pl)
        }
        else if(!teamplay)
        {
-               int f = entcs_GetClientColors(pl.sv_entnum);
+               int f;
+               // NOTE: always adding 1024 allows saving the colormap 0 as a value != 0
+               if (playerslots[pl.sv_entnum].colormap >= 1024)
+                       f = playerslots[pl.sv_entnum].colormap - 1024; // override server-side player colors
+               else
+                       f = entcs_GetClientColors(pl.sv_entnum);
+
                {
                        sbt_field_icon0 = "gfx/scoreboard/playercolor_base";
                        sbt_field_icon1 = "gfx/scoreboard/playercolor_shirt";
index b84a98ca6d3c9d1f723eec988d7cb89bb2de9918..85119de08825c52ab9c6692d87d4d9a3eb9fd83b 100644 (file)
@@ -157,11 +157,6 @@ ENTCS_PROP(SOLID, true, sv_solid, solid, ENTCS_SET_NORMAL,
        { WriteByte(chan, ent.sv_solid); },
        { ent.sv_solid = ReadByte(); })
 
-// gamemode specific player survival status (independent of score and frags)
-ENTCS_PROP(SURVIVAL_STATUS, true, survival_status, survival_status, ENTCS_SET_NORMAL,
-       { WriteShort(chan, ent.survival_status); },
-       { ent.survival_status = ReadShort(); })
-
 #ifdef SVQC
 
        int ENTCS_PUBLICMASK = 0, ENTCS_PRIVATEMASK = 0;
index 7a16141fc8ebbe89409b947cdfd9b979da571233..f0a793afd50f4d39aa2d28fe1e3bfc313e438e43 100644 (file)
@@ -270,6 +270,9 @@ MUTATOR_HOOKFUNCTION(ca, PutClientInServer)
                        Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE);
                }
        }
+
+       if (!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
 }
 
 MUTATOR_HOOKFUNCTION(ca, reset_map_players)
index f1e6b1ce2ec0f5b7fb3f361f9674806459d525e6..77fbfc231633cda534ad78aeca6e3484cb2cfdbf 100644 (file)
@@ -429,6 +429,11 @@ MUTATOR_HOOKFUNCTION(ft, PlayerSpawn)
        return true;
 }
 
+MUTATOR_HOOKFUNCTION(ft, PutClientInServer)
+{
+       eliminatedPlayers.SendFlags |= 1;
+}
+
 MUTATOR_HOOKFUNCTION(ft, reset_map_players)
 {
        FOREACH_CLIENT(IS_PLAYER(it), {
index 02d0907abccf0a40b28a6c388455fd962cd8f2ad..01e6a60068decec87730d3f522e74c2f97e19d8d 100644 (file)
@@ -3,14 +3,65 @@
 #include <client/draw.qh>
 #include <client/hud/panel/modicons.qh>
 
+NET_HANDLE(ENT_CLIENT_SURVIVALSTATUSES, bool isnew)
+{
+       make_pure(this);
+       int sf = 0;
+       serialize(byte, 0, sf);
+       if (sf & BIT(1)) // make all players survivors
+       {
+               for (int j = 0; j < maxclients; ++j)
+                       if (playerslots[j])
+                               playerslots[j].survival_status = SURV_STATUS_PREY;
+       }
+       if (sf & BIT(0)) // reveal hunters (to hunters)
+       {
+               for (int i = 1; i <= maxclients; i += 8)
+               {
+                       int f = 0;
+                       serialize(byte, 0, f);
+                       for (int b = 0; b < 8; ++b)
+                       {
+                               if (!(f & BIT(b))) continue;
+                               int j = i - 1 + b;
+                               if (playerslots[j])
+                                       playerslots[j].survival_status = SURV_STATUS_HUNTER;
+                       }
+               }
+       }
+
+       // we could check STAT(GAME_STOPPED) instead of this dedicated flag,
+       // unfortunately STAT(GAME_STOPPED) is still false right when we receive this
+       bool reveal_hunters_to_survivors = (sf & BIT(2)); // when a round ends
+
+       int mystatus = playerslots[player_localnum].survival_status;
+       for (int i = 1; i <= maxclients; ++i)
+       {
+               entity e = playerslots[i - 1];
+               if (!e) continue;
+
+               int plcolor = SURV_COLOR_PREY;
+               if(e.survival_status == SURV_STATUS_HUNTER && (mystatus == SURV_STATUS_HUNTER || reveal_hunters_to_survivors))
+                       plcolor = SURV_COLOR_HUNTER;
+
+               e.colormap = 1024 + plcolor; // override scoreboard and player model colors
+       }
+
+       return true;
+}
+
 void HUD_Mod_Survival(vector pos, vector mySize)
 {
        mod_active = 1; // survival should always show the mod HUD
 
-       int mystatus = entcs_receiver(player_localnum).survival_status;
+       int mystatus = playerslots[player_localnum].survival_status;
        string player_text = "";
        vector player_color = '1 1 1';
        //string player_icon = "";
+
+       if(STAT(GAMESTARTTIME) > time || STAT(ROUNDSTARTTIME) > time || entcs_IsSpectating(player_localnum))
+               return;
+
        if(mystatus == SURV_STATUS_HUNTER)
        {
                player_text = _("Hunter");
@@ -23,11 +74,6 @@ void HUD_Mod_Survival(vector pos, vector mySize)
                player_color = '0 1 0';
                //player_icon = "player_neutral";
        }
-       else
-       {
-               // if the player has no valid status, don't draw anything
-               return;
-       }
 
        drawstring_aspect(pos, player_text, vec2(mySize.x, mySize.y), player_color, panel_fg_alpha, DRAWFLAG_NORMAL);
 }
@@ -40,15 +86,11 @@ MUTATOR_HOOKFUNCTION(cl_surv, ForcePlayercolors_Skip, CBC_ORDER_LAST)
                return false;
 
        entity player = M_ARGV(0, entity);
-       entity e = entcs_receiver(player.entnum - 1);
-       int surv_status = ((e) ? e.survival_status : 0);
-       int mystatus = entcs_receiver(player_localnum).survival_status;
-
-       int plcolor = SURV_COLOR_PREY; // default to survivor
-       if((mystatus == SURV_STATUS_HUNTER || intermission || STAT(GAME_STOPPED)) && surv_status == SURV_STATUS_HUNTER)
-               plcolor = SURV_COLOR_HUNTER;
-
-       player.colormap = 1024 + plcolor;
+       entity e = playerslots[player.entnum - 1];
+       if (e && e.colormap)
+               player.colormap = e.colormap;
+       else
+               player.colormap = 1024 + SURV_COLOR_PREY;
        return true;
 }
 
index 1f2d1440224a593013f901868d688cd10424e5e3..a8a67ad44efe5e76395c1587fe1b13c4ea2ff201 100644 (file)
@@ -1 +1,2 @@
 #include "survival.qh"
+REGISTER_NET_LINKED(ENT_CLIENT_SURVIVALSTATUSES)
index 6414686e0bcc67638503f6aaeda15ecb9e67754b..dea924772d8d1b0e0ec330e9b86d82c070876000 100644 (file)
@@ -8,6 +8,61 @@ bool autocvar_g_survival_reward_survival = true;
 
 void nades_Clear(entity player);
 
+entity survivalStatuses;
+void SurvivalStatuses_Init();
+
+void SurvivalStatuses_Send()
+{
+       // SendFlags can be set to anything != 0, SurvivalStatuses_SendEntity won't use its value
+       survivalStatuses.SendFlags = 1;
+       survivalStatuses.nextthink = 0; // clear delayed send
+}
+
+void SurvivalStatuses_Send_Delayed()
+{
+       survivalStatuses.think = SurvivalStatuses_Send;
+       survivalStatuses.nextthink = time + 0.2;
+}
+
+bool SurvivalStatuses_SendEntity(entity this, entity dest, float sendflags)
+{
+       Stream out = MSG_ENTITY;
+       WriteHeader(out, ENT_CLIENT_SURVIVALSTATUSES);
+
+       sendflags |= BIT(1); // make all players survivors
+
+       if (dest.survival_status == SURV_STATUS_HUNTER);
+               sendflags |= BIT(0); // send hunter statuses
+
+       if (round_handler_AwaitingNextRound())
+               sendflags |= (BIT(0) | BIT(2)); // send hunter statuses and reveal hunters to survivors
+
+       serialize(byte, out, sendflags);
+       if (sendflags & BIT(0)) {
+               for (int i = 1; i <= maxclients; i += 8) {
+                       int f = 0;
+                       entity e = edict_num(i);
+                       for (int b = 0; b < 8; ++b, e = nextent(e)) {
+                               bool is_hunter = (INGAME(e) && e.survival_status == SURV_STATUS_HUNTER);
+                               if (is_hunter)
+                                       f |= BIT(b);
+                       }
+                       serialize(byte, out, f);
+               }
+       }
+       return true;
+}
+
+void SurvivalStatuses_Init()
+{
+       if(survivalStatuses)
+       {
+               backtrace("Can't spawn survivalStatuses again!");
+               return;
+       }
+       Net_LinkEntity(survivalStatuses = new_pure(survivalStatuses), false, 0, SurvivalStatuses_SendEntity);
+}
+
 void Surv_UpdateScores(bool timed_out)
 {
        // give players their hard-earned kills now that the round is over
@@ -48,6 +103,7 @@ float Surv_CheckWinner()
                allowed_to_spawn = false;
                game_stopped = true;
                round_handler_Init(5, autocvar_g_survival_warmup, autocvar_g_survival_round_timelimit);
+               SurvivalStatuses_Send();
                return 1;
        }
 
@@ -85,6 +141,7 @@ float Surv_CheckWinner()
        allowed_to_spawn = false;
        game_stopped = true;
        round_handler_Init(5, autocvar_g_survival_warmup, autocvar_g_survival_round_timelimit);
+       SurvivalStatuses_Send();
 
        FOREACH_CLIENT(true,
        {
@@ -119,6 +176,7 @@ void Surv_RoundStart()
                total_hunters++;
                it.survival_status = SURV_STATUS_HUNTER;
        });
+       SurvivalStatuses_Send();
 
        FOREACH_CLIENT(IS_PLAYER(it) && !IS_DEAD(it),
        {
@@ -181,6 +239,7 @@ void surv_Initialize() // run at the start of a match, initiates game mode
        round_handler_Spawn(Surv_CheckPlayers, Surv_CheckWinner, Surv_RoundStart);
        round_handler_Init(5, autocvar_g_survival_warmup, autocvar_g_survival_round_timelimit);
        EliminatedPlayers_Init(surv_isEliminated);
+       SurvivalStatuses_Init();
 }
 
 
@@ -207,21 +266,6 @@ MUTATOR_HOOKFUNCTION(surv, ClientObituary)
                M_ARGV(5, bool) = true; // anonymous attacker
 }
 
-MUTATOR_HOOKFUNCTION(surv, PlayerPreThink)
-{
-       entity player = M_ARGV(0, entity);
-
-       if(IS_PLAYER(player) || INGAME_JOINED(player))
-       {
-               // update the scoreboard colour display to out the real killer at the end of the round
-               // running this every frame to avoid cheats
-               int plcolor = SURV_COLOR_PREY;
-               if(player.survival_status == SURV_STATUS_HUNTER && game_stopped)
-                       plcolor = SURV_COLOR_HUNTER;
-               setcolor(player, plcolor);
-       }
-}
-
 MUTATOR_HOOKFUNCTION(surv, PlayerSpawn)
 {
        entity player = M_ARGV(0, entity);
@@ -258,6 +302,13 @@ MUTATOR_HOOKFUNCTION(surv, PutClientInServer)
                        Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_JOIN_LATE);
                }
        }
+
+       if (!warmup_stage)
+               eliminatedPlayers.SendFlags |= 1;
+       // send statuses with a small delay to make sure a playerslot exists, otherwise
+       // personal colors for this player won't be overriden
+       // it also reduces network traffic when multiple clients join the server at once (at map start)
+       SurvivalStatuses_Send_Delayed();
 }
 
 MUTATOR_HOOKFUNCTION(surv, reset_map_players)
@@ -273,6 +324,8 @@ MUTATOR_HOOKFUNCTION(surv, reset_map_players)
                }
        });
        bot_relinkplayerlist();
+       // this will also clear scheduled SurvivalStatuses_Send set by PutClientInServer
+       SurvivalStatuses_Send();
        return true;
 }
 
@@ -330,7 +383,7 @@ MUTATOR_HOOKFUNCTION(surv, PlayerDies)
 
        // killed an ally! punishment is death
        if(autocvar_g_survival_punish_teamkill && frag_attacker != frag_target && IS_PLAYER(frag_attacker) && IS_PLAYER(frag_target) && frag_attacker.survival_status == frag_target.survival_status && !ITEM_DAMAGE_NEEDKILL(frag_deathtype))
-       if(!warmup_stage && round_handler_IsActive() && round_handler_IsRoundStarted()) // don't autokill if the round hasn't
+       if(!warmup_stage && round_handler_IsActive() && round_handler_IsRoundStarted()) // don't autokill if the round hasn't started yet
                Damage(frag_attacker, frag_attacker, frag_attacker, 100000, DEATH_MIRRORDAMAGE.m_id, DMG_NOWEP, frag_attacker.origin, '0 0 0');
        return true;
 }
index 57f6f46b6153570fe0b4c276875d07664191b539..46f98959272627c1b52aeead334f03dff83277f9 100644 (file)
@@ -213,7 +213,7 @@ entity join_minigame(entity player, string game_id )
        return NULL;
 }
 
-void part_minigame(entity player )
+void part_minigame(entity player)
 {
        entity minig = CS(player).active_minigame;
 
@@ -268,6 +268,8 @@ string invite_minigame(entity inviter, entity player)
                return "Invalid player";
        if ( inviter == player )
                return "You can't invite yourself";
+       if (PlayerInList(player, autocvar_g_playban_list) && autocvar_g_playban_minigames) // playban
+               return "You can't invite a banned player";
        if ( CS(player).active_minigame == CS(inviter).active_minigame )
                return strcat(player.netname," is already playing");
 
@@ -312,6 +314,13 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command
                return;
        }
 
+       if (PlayerInList(caller, autocvar_g_playban_list) && autocvar_g_playban_minigames) // playban
+       {
+               Send_Notification(NOTIF_ONE_ONLY, caller, MSG_CENTER, CENTER_JOIN_PLAYBAN);
+               sprint(caller, "You aren't allowed to play minigames because you are banned from them in this server.\n");
+               return;
+       }
+
        if (request == CMD_REQUEST_COMMAND )
        {
                string minig_cmd = argv(1);
index 2a663a10dc7e02b377704e7540ab6e730e32d526..07587befa8794a13bdeb6d0240828f611ce6f8ef 100644 (file)
@@ -73,12 +73,6 @@ void bot_think(entity this)
 
        if (!IS_PLAYER(this) || (autocvar_g_campaign && !campaign_bots_may_start))
        {
-               if (IS_PLAYER(this))
-               {
-                       .entity weaponentity = weaponentities[0];
-                       if(this.(weaponentity).m_weapon == WEP_Null)
-                               W_NextWeapon(this, 0, weaponentity);
-               }
                CS(this).movement = '0 0 0';
                this.bot_nextthink = time + 0.5;
                return;
@@ -124,9 +118,6 @@ void bot_think(entity this)
 
        if (time < game_starttime)
        {
-               .entity weaponentity = weaponentities[0];
-               if(this.(weaponentity).m_weapon == WEP_Null)
-                       W_NextWeapon(this, 0, weaponentity);
                // block the bot during the countdown to game start
                CS(this).movement = '0 0 0';
                return;
index c037662846bb66e28b2649e221282ec018f3ee5d..0a8846d5d166ee6750dc83fd4e0da570c8d4c0ab 100644 (file)
@@ -982,7 +982,7 @@ bool findinlist_abbrev(string tofind, string list)
                return false; // empty list or search, just return
 
        // this function allows abbreviated strings!
-       FOREACH_WORD(list, it == substring(tofind, 0, strlen(it)),
+       FOREACH_WORD(list, it != "" && it == substring(tofind, 0, strlen(it)),
        {
                return true;
        });
@@ -1010,6 +1010,8 @@ bool PlayerInIDList(entity p, string idlist)
 
 bool PlayerInList(entity player, string list)
 {
+       if (list == "")
+               return false;
        return boolean(PlayerInIDList(player, list) || PlayerInIPList(player, list));
 }
 
@@ -1192,7 +1194,7 @@ void ClientConnect(entity this)
        if (PlayerInList(this, autocvar_g_playban_list))
                TRANSMUTE(Observer, this);
 
-       if (PlayerInList(this, autocvar_g_muteban_list)) // muteban
+       if (PlayerInList(this, autocvar_g_chatban_list)) // chatban
                CS(this).muted = true;
 
        MUTATOR_CALLHOOK(ClientConnect, this);
@@ -2298,6 +2300,11 @@ void ObserverOrSpectatorThink(entity this)
                CS(this).autojoin_checked = true;
                TRANSMUTE(Player, this);
                PutClientInServer(this);
+
+               .entity weaponentity = weaponentities[0];
+               if(this.(weaponentity).m_weapon == WEP_Null)
+                       W_NextWeapon(this, 0, weaponentity);
+
                return;
        }
 
index 933eb3c83d8e85fc59ebb825136aa0e641d968cf..b4f0bb3082a4980bb4ed6e9c31f1b958a88b1246 100644 (file)
@@ -1,6 +1,7 @@
 #include "banning.qh"
 
 #include <common/command/_mod.qh>
+#include <common/minigames/sv_minigames.qh>
 #include <common/state.qh>
 #include <common/stats.qh>
 #include <common/util.qh>
@@ -133,13 +134,13 @@ void BanCommand_mute(int request, int argc, string command)
                                if (accepted > 0)
                                {
                                        string theid = "";
-                                       if(!PlayerInIPList(client, autocvar_g_muteban_list))
+                                       if(!PlayerInIPList(client, autocvar_g_chatban_list))
                                                theid = cons(theid, client.netaddress);
-                                       if(!PlayerInIDList(client, autocvar_g_muteban_list))
+                                       if(!PlayerInIDList(client, autocvar_g_chatban_list))
                                                theid = cons(theid, client.crypto_idfp);
                                        CS(client).muted = true;
                                        LOG_INFO(strcat("Mute-banning player ", GetCallerName(client), " (", argv(1), ")."));
-                                       cvar_set("g_muteban_list", cons(autocvar_g_muteban_list, theid));
+                                       cvar_set("g_chatban_list", cons(autocvar_g_chatban_list, theid));
 
                                        return;
                                }
@@ -156,7 +157,7 @@ void BanCommand_mute(int request, int argc, string command)
                {
                        LOG_HELP("Usage:^3 sv_cmd mute <client>");
                        LOG_HELP("  <client> is the entity number or name of the player to mute.");
-                       LOG_HELP("See also: ^2unmute, g_muteban_list^7");
+                       LOG_HELP("See also: ^2unmute, g_chatban_list^7");
                        return;
                }
        }
@@ -183,6 +184,8 @@ void BanCommand_playban(int request, int argc, string command)
 
                                        LOG_INFO(strcat("Play-banning player ", GetCallerName(client), " (", argv(1), ")."));
                                        PutObserverInServer(client, true, true);
+                                       if (autocvar_g_playban_minigames) 
+                                               part_minigame(client);
                                        cvar_set("g_playban_list", cons(autocvar_g_playban_list, theid));
 
                                        return;
@@ -267,14 +270,14 @@ void BanCommand_unmute(int request, int argc)
                                if (accepted > 0)
                                {
                                        string tmp_string = "";
-                                       FOREACH_WORD(autocvar_g_muteban_list, it != client.netaddress,
+                                       FOREACH_WORD(autocvar_g_chatban_list, it != client.netaddress,
                                        {
                                                if(client.crypto_idfp && it == substring(client.crypto_idfp, 0, strlen(it)))
                                                        continue;
                                                tmp_string = cons(tmp_string, it);
                                        });
 
-                                       cvar_set("g_muteban_list", tmp_string);
+                                       cvar_set("g_chatban_list", tmp_string);
                                        LOG_INFO(strcat("Unmuting player ", GetCallerName(client), " (", original_arg, ")."));
                                        CS(client).muted = false;
 
@@ -293,7 +296,7 @@ void BanCommand_unmute(int request, int argc)
                {
                        LOG_HELP("Usage:^3 sv_cmd unmute <client>");
                        LOG_HELP("  <client> is the entity number or name of the player to unmute.");
-                       LOG_HELP("See also: ^2mute, g_muteban_list^7");
+                       LOG_HELP("See also: ^2mute, g_chatban_list^7");
                        return;
                }
        }
index 6aa70c6a8028a7dcca41d5ea229c5e51f3d71424..4c373b52e2d946fd0950a975af6567a483190ec1 100644 (file)
@@ -10,9 +10,10 @@ string autocvar_g_ban_sync_uri;
 bool autocvar_g_ban_telluser = true;
 string autocvar_g_banned_list;
 bool autocvar_g_banned_list_idmode;
-string autocvar_g_muteban_list; // "List of banned players from chat"
-string autocvar_g_playban_list; // "List of banned players from playing (forced to spectate)"
-string autocvar_g_voteban_list; // "List of banned players from voting"
+string autocvar_g_chatban_list;
+string autocvar_g_playban_list;
+bool autocvar_g_playban_minigames;
+string autocvar_g_voteban_list;
 
 #define GET_BAN_ARG(v, d) if (argc > reason_arg) { if ((v = stof(argv(reason_arg))) != 0) ++reason_arg; else v = d; } else { v = d; }
 #define GET_BAN_REASON(v, d) if (argc > reason_arg) v = substring(command, argv_start_index(reason_arg), strlen(command) - argv_start_index(reason_arg)); else v = d;
index 7627e177b83e432e14d8bf44d58deba0ad49219d..61861acbb2ac47f7f8212b57c277f356899d27d6 100644 (file)
@@ -1069,7 +1069,7 @@ void GameCommand_moveplayer(int request, int argc)
                                        else if (destination == "spectator")
                                        {
                                                string pl_name = playername(client.netname, client.team, false);
-                                               if (!IS_SPEC(client) && !IS_OBSERVER(client))
+                                               if (!(IS_SPEC(client) || IS_OBSERVER(client)) || INGAME(client))
                                                {
                                                        PutObserverInServer(client, true, true);
 
index 02cb8e1cec9c730f967833becf5b93b14ea8308d..a3d146c75f7529cbe8a9e9689e717a983ceefe43 100644 (file)
@@ -25,6 +25,7 @@
 #include <server/scores.qh>
 #include <server/teamplay.qh>
 #include <server/weapons/accuracy.qh>
+#include <server/weapons/selection.qh>
 #include <server/world.qh>
 
 // =============================================
@@ -416,6 +417,13 @@ void reset_map(bool is_fake_round_start)
                        it.avelocity = '0 0 0';
                        CS(it).movement = '0 0 0';
                        PutClientInServer(it);
+
+                       if(IS_BOT_CLIENT(it))
+                       {
+                               .entity weaponentity = weaponentities[0];
+                               if(it.(weaponentity).m_weapon == WEP_Null)
+                                       W_NextWeapon(it, 0, weaponentity);
+                       }
                });
        }
 }
@@ -746,6 +754,29 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
 
        switch (first_command) // now go through and parse the proper commands to adjust as needed.
        {
+               case "movetoauto":
+               case "movetored":
+               case "movetoblue":
+               case "movetoyellow":
+               case "movetopink":
+               case "movetospec":
+               {
+                       entity victim = GetIndexedEntity(argc, (startpos + 1));
+                       float accepted = VerifyClientEntity(victim, true, false);
+                       if (accepted > 0)
+                       {
+                               vote_parsed_command = vote_command;
+                               vote_parsed_display = sprintf("^1%s #%d ^7%s", first_command, etof(victim), victim.netname);
+                       }
+                       else
+                       {
+                               print_to(caller, strcat("vcall: ", GetClientErrorString(accepted, argv(startpos + 1)), ".\n"));
+                               return 0;
+                       }
+
+                       break;
+               }
+
                case "kick":
                case "kickban":    // catch all kick/kickban commands
                {
@@ -798,6 +829,22 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
                        break;
                }
 
+               case "fraglimit": // include restrictions on the maximum votable frag limit
+               {
+                       float fraglimit_vote = stof(argv(startpos + 1));
+                       float fraglimit_min = 0;
+                       float fraglimit_max = 999999;
+                       if(fraglimit_vote > fraglimit_max || fraglimit_vote < fraglimit_min)
+                       {
+                               print_to(caller, strcat("Invalid fraglimit vote, accepted values are between ", ftos(fraglimit_min), " and ", ftos(fraglimit_max), "."));
+                               return -1;
+                       }
+                       vote_parsed_command = strcat("fraglimit ", ftos(fraglimit_vote));
+                       vote_parsed_display = strzone(strcat("^1", vote_parsed_command));
+
+                       break;
+               }
+
                case "timelimit": // include restrictions on the maximum votable time limit
                {
                        float timelimit_vote = stof(argv(startpos + 1));
@@ -806,7 +853,6 @@ int VoteCommand_parse(entity caller, string vote_command, string vote_list, floa
                                print_to(caller, strcat("Invalid timelimit vote, accepted values are between ", ftos(autocvar_timelimit_min), " and ", ftos(autocvar_timelimit_max), "."));
                                return -1;
                        }
-                       timelimit_vote = bound(autocvar_timelimit_min, timelimit_vote, autocvar_timelimit_max);
                        vote_parsed_command = strcat("timelimit ", ftos(timelimit_vote));
                        vote_parsed_display = strzone(strcat("^1", vote_parsed_command));
 
index 429d3e262568b56b77cab4cd76d86c73ea8de5d2..44bce18a823533eeaf494f6b0dc654d5903bec68 100644 (file)
@@ -245,8 +245,10 @@ void Obituary(entity attacker, entity inflictor, entity targ, int deathtype, .en
        if (MUTATOR_CALLHOOK(ClientObituary, inflictor, attacker, targ, deathtype, attacker.(weaponentity))) { CS(targ).killcount = 0; return; }
        notif_anonymous = M_ARGV(5, bool);
 
+       // TODO: Replace "???" with a translatable "Anonymous player" string
+       // https://gitlab.com/xonotic/xonotic-data.pk3dir/-/issues/2839
        if(notif_anonymous)
-               attacker_name = "Anonymous player";
+               attacker_name = "???";
 
        #ifdef NOTIFICATIONS_DEBUG
        Debug_Notification(
index 0368f7f5f9cb9a51c2157793c8724e98713e510e..d2bb32c6fc27f925343f35617941c5b7f50a4e57 100644 (file)
@@ -102,6 +102,7 @@ bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andam
                return true;
        }
        if (complain)
+       if(IS_REAL_CLIENT(this))
        {
                // DRESK - 3/16/07
                // Report Proper Weapon Status / Modified Weapon Ownership Message
index df6490128aa993ac84239930a0a477336d078fc0..20e713c2a7db4c6b287f5f63792f02ed054d9310 100644 (file)
@@ -291,7 +291,7 @@ bool weapon_prepareattack_check(Weapon thiswep, entity actor, .entity weaponenti
                if (ATTACK_FINISHED(actor, weaponentity) > time + actor.(weaponentity).weapon_frametime * 0.5) return false;
                entity this = actor.(weaponentity);
                // don't fire while changing weapon
-               if (this.state != WS_READY) return false;
+               if (!actor.vehicle && this.state != WS_READY) return false;
        }
        return true;
 }
index 8b38b06fe2fe51af63cbf251d0504e4fb1827ac6..977f235715a90a90064d4a8f332f3dbd36595af1 100644 (file)
@@ -236,8 +236,9 @@ void cvar_changes_init()
                BADCVAR("timeformat");
                BADCVAR("timestamps");
                BADCVAR("g_require_stats");
-               BADCVAR("g_muteban_list");
+               BADCVAR("g_chatban_list");
                BADCVAR("g_playban_list");
+               BADCVAR("g_playban_minigames");
                BADCVAR("g_voteban_list");
                BADPREFIX("developer_");
                BADPREFIX("g_ban_");
index e070ea2b6c8bd673cb316aa5650370394264cdc1..a25c990f6c1013c29691bc325ec21d90089621fd 100644 (file)
@@ -89,7 +89,7 @@ models/relics/sign_invisible
        nopicmip
        {
                map models/relics/sign_invisible
-               blendfunc add
+               blendfunc blend
        }
 }
 
@@ -144,7 +144,7 @@ models/relics/sign_speed
        nopicmip
        {
                map models/relics/sign_speed
-               blendfunc add
+               blendfunc blend
        }
 }
 
index 6bc987f677eb37772c78ce4697b84c135383d7f3..4a374aa05b2beb990950e4b23e3efc5f47d94a43 100644 (file)
@@ -396,19 +396,20 @@ set sv_waypointsprite_limitedrange 5120 "default maximum viewing distance of way
 set sv_itemstime 1 "enable networking of time left until respawn for items such as mega health/armor and powerups"
 
 // bans
-set g_ban_default_bantime 5400 "90 minutes"
+set g_ban_default_bantime 5400 "default ban time in seconds"
 set g_ban_default_masksize 3 "masksize 0 means banning by UID only, 1 means banning by /8 (IPv6: /32) network, 2 means banning by /16 (IPv6: /48) network, 3 means banning by /24 (IPv6: /56) network, 4 means banning by single IP (IPv6: /64 network)"
 set g_ban_sync_uri "" "sync using this ban list provider (empty string to disable)"
-set g_ban_sync_interval 5 "sync every 5 minutes"
-set g_ban_sync_trusted_servers "" "request ban lists from these xonotic servers (do not include your own server there, or unbanning may fail)"
+set g_ban_sync_interval 5 "sync interval in minutes"
+set g_ban_sync_trusted_servers "" "request ban lists from these Xonotic servers (do not include your own server there, or unbanning may fail)"
 set g_ban_sync_timeout 45 "time out in seconds for the ban sync requests"
-set g_ban_sync_trusted_servers_verify 0 "when set to 1, additional bans sent by the servers are ignored, and only bans for the requested IP are used"
-set g_ban_telluser 1 "notify the banned player about it when they try to join"
-set g_banned_list "" "format: IP remainingtime IP remainingtime ..."
+set g_ban_sync_trusted_servers_verify 0 "ignore additional bans sent by the servers, and use only bans for the requested IP"
+set g_ban_telluser 1 "notify the banned player they are banned when they try to join"
+set g_banned_list "" "list of banned players; player format: IP remainingtime"
 set g_banned_list_idmode "1" "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)"
-set g_muteban_list "" "list of banned players from chat, format: IP playerkey ..."
-set g_playban_list "" "list of banned players from playing (forced to spectate), format: IP playerkey ..."
-set g_voteban_list "" "list of banned players from voting, format: IP playerkey ..."
+set g_chatban_list "" "list of banned players from chat; player format: IP or playerkey"
+set g_playban_list "" "list of banned players from playing (forced to spectate); player format: IP or playerkey"
+set g_playban_minigames 0 "disallow playbanned players (who are forced to spectate) from playing minigames"
+set g_voteban_list "" "list of banned players from voting; player format: IP or playerkey"
 
 // useful vote aliases
 set timelimit_increment 5 "number of minutes added to the timer when voting for extendmatchtime"