]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'drjaska/run-genmod' into 'master'
authorbones_was_here <bones_was_here@xa.org.au>
Wed, 13 Apr 2022 06:29:51 +0000 (06:29 +0000)
committerbones_was_here <bones_was_here@xa.org.au>
Wed, 13 Apr 2022 06:29:51 +0000 (06:29 +0000)
updated _mod. files with qcsrc\tools\genmod.sh shell script

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

32 files changed:
.tx/merge-base
common.es.po
common.fr.po
common.ja_JP.po
common.pt_BR.po
common.ru.po
languages.txt
qcsrc/client/announcer.qc
qcsrc/client/hud/panel/centerprint.qc
qcsrc/client/hud/panel/centerprint.qh
qcsrc/client/main.qc
qcsrc/client/view.qc
qcsrc/common/mutators/mutator/hook/_mod.inc
qcsrc/common/mutators/mutator/hook/_mod.qh
qcsrc/common/mutators/mutator/hook/cl_hook.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/hook/cl_hook.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/hook/sv_hook.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/melee_only/sv_melee_only.qc
qcsrc/common/mutators/mutator/nades/nades.qc
qcsrc/common/mutators/mutator/offhand_blaster/_mod.inc
qcsrc/common/mutators/mutator/offhand_blaster/_mod.qh
qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qc [new file with mode: 0644]
qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/offhand_blaster/sv_offhand_blaster.qc
qcsrc/common/playerstats.qh
qcsrc/common/util.qc
qcsrc/common/util.qh
qcsrc/menu/xonotic/dialog_multiplayer_create_mutators.qc
qcsrc/server/client.qc
qcsrc/server/scores.qh
qcsrc/server/world.qc

index a734f5abdd8069a1cb49c0e7c1469c23456c8b71..4493fd934b88149c7e59ccf845168bbe15fedeb0 100644 (file)
@@ -1 +1 @@
-Mon Apr 11 07:24:09 CEST 2022
+Wed Apr 13 07:23:07 CEST 2022
index 4c1e8fdca81ee12b5a1a3325a5aa7a28d4c32728..b1e9d1ef8610623fd1dab85f2ea4759d48025ae8 100644 (file)
@@ -33,7 +33,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2022-04-10 07:22+0200\n"
 "PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: LegendGuard, 2020-2022\n"
+"Last-Translator: Yllelder, 2016\n"
 "Language-Team: Spanish (http://www.transifex.com/team-xonotic/xonotic/"
 "language/es/)\n"
 "Language: es\n"
index 277bfaa8de63970f4636e57229e1b1032ce56017..82c6655508575caa19844e31cd2eaa7b250dc80a 100644 (file)
@@ -7453,7 +7453,7 @@ msgstr "Informations sur le serveur"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfotab.qc:24
 msgid "Hostname:"
-msgstr "Nom de l'hôte :"
+msgstr "Nom d'hôte :"
 
 #: qcsrc/menu/xonotic/dialog_multiplayer_join_serverinfotab.qc:43
 msgid "Map:"
index 9656f7b31c9f7999f85242790ec9cdbfb212d394..30d03ac835e82f7bfa52f64771decae932be10d2 100644 (file)
@@ -8249,12 +8249,12 @@ msgstr "全て"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:192
 msgid "Realtime dynamic lights"
-msgstr ""
+msgstr "リアルタイムダイナミックライト"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:193
 msgid ""
 "Temporary realtime light sources such as explosions, rockets and powerups"
-msgstr ""
+msgstr "爆発、ロケット、パワーアップなどの一時的なリアルタイムライト源"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:195
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:201
@@ -8263,21 +8263,23 @@ msgstr "影"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:196
 msgid "Shadows cast by realtime dynamic lights"
-msgstr ""
+msgstr "リアルタイムダイナミックライトによって投げかけられる影"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:199
 msgid "Realtime world lights"
-msgstr ""
+msgstr "リアルタイムワールドライト"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:200
 msgid ""
 "Realtime light sources included in certain maps. May have a big impact on "
 "performance."
 msgstr ""
+"特定のマップに含まれるリアルタイムライト源。 パフォーマンスに大きな影響を与え"
+"る可能性がある。"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:202
 msgid "Shadows cast by realtime world lights"
-msgstr ""
+msgstr "リアルタイムワールドライトによって投げかけられる影"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:206
 msgid "Use normal maps"
@@ -8288,6 +8290,8 @@ msgid ""
 "Directional shading of certain textures to simulate interaction of realtime "
 "light with a bumpy surface"
 msgstr ""
+"リアルタイムライトとでこぼこの表面との相互作用をシミュレートするための特定の"
+"テクスチャの指向性シェーディング"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:209
 msgid "Soft shadows"
@@ -8299,7 +8303,7 @@ msgstr "コロナの明るさ:"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:214
 msgid "Flare effects around certain lights, default 1"
-msgstr ""
+msgstr "特定のライト周辺のフレア効果、デフォルト: 1"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:217
 msgid "Fade coronas according to visibility"
@@ -8307,7 +8311,7 @@ msgstr "可視性に応じてフェードコロナ"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:218
 msgid "Corona fading using occlusion queries"
-msgstr ""
+msgstr "オクルージョンクエリを使用しているコロナフェージング"
 
 #: qcsrc/menu/xonotic/dialog_settings_effects.qc:222
 msgid "Bloom"
@@ -9121,15 +9125,15 @@ msgstr "パケットサイズとその他の情報のグラフを表示する"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:36
 msgid "Packet loss compensation"
-msgstr ""
+msgstr "パケット損失補償"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:37
 msgid "Each packet includes a copy of the previous message"
-msgstr ""
+msgstr "各パケットには前のメッセージのコピーが含まれている"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:39
 msgid "Movement prediction error compensation"
-msgstr ""
+msgstr "動きの予測のエラー補償"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:43
 msgid "Use encryption (AES) when available"
@@ -9170,7 +9174,7 @@ msgstr "同時ダウロード:"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:66
 msgid "Maximum number of concurrent HTTP downloads"
-msgstr ""
+msgstr "同時HTTPダウンロードの最大数"
 
 #: qcsrc/menu/xonotic/dialog_settings_misc.qc:82
 msgid "Framerate"
@@ -9406,6 +9410,8 @@ msgid ""
 "Vsync prevents tearing, but increases latency and caps your fps at the "
 "screen refresh rate"
 msgstr ""
+"VSYNCはティアリングを防ぎますが、レイテンシーを増加させ、画面のリフレッシュ"
+"レートでfpsを制限する"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:64
 msgid "High-quality frame buffer"
@@ -9446,6 +9452,8 @@ msgid ""
 "Screen or window size multiplier, above 1x does antialiasing, below 1x may "
 "help slow GPUs"
 msgstr ""
+"画面またはウィンドウサイズの乗数、1xを超えるとアンチエイリアスが実行され、1x"
+"を下回るとGPUの速度が低下する可能性がある"
 
 #: qcsrc/menu/xonotic/dialog_settings_video.qc:90
 msgid "Anisotropy:"
index 3867b9a319c8b4848e7620be1726da2818acbdb1..b157965b0b96d69e529e43dee02668ddcee2dac1 100644 (file)
@@ -18,7 +18,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2022-04-10 07:22+0200\n"
 "PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: yy0zz, 2021-2022\n"
+"Last-Translator: zerowhy . <anymailz@tutanota.com>, 2021\n"
 "Language-Team: Portuguese (Brazil) (http://www.transifex.com/team-xonotic/"
 "xonotic/language/pt_BR/)\n"
 "Language: pt_BR\n"
index 853e0f46d61fe48117677d31ab461ed31c1e85e8..773c512fc231c21df3e983b59cb256c849efeb69 100644 (file)
@@ -22,7 +22,7 @@ msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2022-04-10 07:22+0200\n"
 "PO-Revision-Date: 2013-09-12 16:53+0000\n"
-"Last-Translator: Andrei Stepanov, 2014-2022\n"
+"Last-Translator: Simple88, 2016\n"
 "Language-Team: Russian (http://www.transifex.com/team-xonotic/xonotic/"
 "language/ru/)\n"
 "Language: ru\n"
index 524b834ae9110641d64ffb7f5db49dc522b05741..e1218eb3b6cc557067499a3ecb246663bd9cf007 100644 (file)
@@ -25,5 +25,5 @@ sr    "Serbian" "Српски" 60%
 uk    "Ukrainian" "Українська" 48%
 zh_CN "Chinese (China)" "中文" 58%
 zh_TW "Chinese (Taiwan)" "國語" 58%
-ja_JP "Japanese" "日本語" 99%
+ja_JP "Japanese" "日本語" 100%
 ko    "Korean" "한국의" 37%
index 59f977818748240387cc9cca1bc569093a9623d4..e86702afa086a8314ee12ba92540f605929a6b7d 100644 (file)
@@ -42,8 +42,7 @@ void Announcer_Duel()
        strcpy(prev_pl2_name, pl2_name);
 
        // There are new duelers, update title
-       float offset = stringwidth(pl2_name, true, hud_fontsize) - stringwidth(pl1_name, true, hud_fontsize) - 1;
-       centerprint_SetTitle(sprintf("^BG%s^BG  %s  %s", pl1_name, _("vs"), pl2_name), offset / 2);
+       centerprint_SetDuelTitle(pl1_name, pl2_name, _("vs"));
 }
 
 void Announcer_ClearTitle()
@@ -150,7 +149,7 @@ void Announcer_Gamestart()
                                if (gametype.m_1v1)
                                        Announcer_Duel();
                                else
-                                       centerprint_SetTitle(strcat("^BG", MapInfo_Type_ToText(gametype)), 0); // Show game type as title
+                                       centerprint_SetTitle(strcat("^BG", MapInfo_Type_ToText(gametype))); // Show game type as title
 
                                if(time + 5.0 < startTime) // if connecting to server while restart was active don't always play prepareforbattle
                                        Local_Notification(MSG_ANNCE, ANNCE_PREPARE);
index 307e3c899a52504a30b464dfcd5c3ee45ff70308..1436f2ef6a9d48e8675976e190ee76c542847329 100644 (file)
@@ -46,7 +46,8 @@ int centerprint_countdown_num[CENTERPRINT_MAX_MSGS];
 bool centerprint_showing;
 
 string centerprint_title;
-float centerprint_title_offset;
+string centerprint_title_left;
+string centerprint_title_right;
 
 void centerprint_Add(int new_id, string strMessage, float duration, int countdown_num)
 {
@@ -150,18 +151,24 @@ void centerprint_KillAll()
        }
 }
 
-void centerprint_ClearTitle()
+void centerprint_SetDuelTitle(string left, string right, string div)
 {
-       strfree(centerprint_title);
-       centerprint_title_offset = 0;
+       strcpy(centerprint_title_left, left);
+       strcpy(centerprint_title_right, right);
+       centerprint_SetTitle(sprintf("^BG%s^BG  %s  %s", left, div, right));
 }
 
-void centerprint_SetTitle(string title, float offset)
+void centerprint_SetTitle(string title)
 {
-       if(title != centerprint_title) {
+       if(title != centerprint_title)
                strcpy(centerprint_title, CCR(title));
-               centerprint_title_offset = offset;
-       }
+}
+
+void centerprint_ClearTitle()
+{
+       strfree(centerprint_title);
+       strfree(centerprint_title_left);
+       strfree(centerprint_title_right);
 }
 
 float hud_configure_cp_generation_time;
@@ -187,7 +194,7 @@ void HUD_CenterPrint()
                {
                        if(highlightedPanel == HUD_PANEL(CENTERPRINT))
                        {
-                               centerprint_SetTitle(sprintf(_("Title at %s"), seconds_tostring(hud_configure_cp_generation_time)), 0);
+                               centerprint_SetTitle(sprintf(_("Title at %s"), seconds_tostring(hud_configure_cp_generation_time)));
 
                                float r;
                                r = random();
@@ -268,8 +275,8 @@ void HUD_CenterPrint()
 
                if (autocvar_hud_panel_centerprint_flip)
                        pos.y -= fontsize.y;
-               if (centerprint_title_offset && align == 0.5)
-                       pos.x += centerprint_title_offset * CENTERPRINT_BASE_SIZE * autocvar_hud_panel_centerprint_fontscale_title;
+               if (centerprint_title_left != "" && align == 0.5) // Center line at the main word (for duels)
+                       pos.x += (stringwidth(centerprint_title_right, true, fontsize) - stringwidth(centerprint_title_left, true, fontsize)) / 2;
 
                drawcolorcodedstring(pos, centerprint_title, fontsize, 1, DRAWFLAG_NORMAL);
 
index b1d52cf0adc06d4e14be1e837ac4f1ecd7dd7a41..02a046a6a140015eae8167254f1ff670e2354854 100644 (file)
@@ -23,5 +23,6 @@ void centerprint_AddStandard(string strMessage);
 void centerprint_Kill(int id);
 void centerprint_KillAll();
 
+void centerprint_SetDuelTitle(string left, string right, string div);
+void centerprint_SetTitle(string title);
 void centerprint_ClearTitle();
-void centerprint_SetTitle(string title, float offset);
index 0892bb6bf2bf0bd67a21ce4fa727a3c22ff988f5..5beca00bef44dd88d0d05ef17464ba8a7510e455 100644 (file)
@@ -1316,6 +1316,55 @@ NET_HANDLE(TE_CSQC_WEAPONCOMPLAIN, bool isNew)
        }
 }
 
+string translate_modifications(string s)
+{
+       return build_mutator_list(s);
+}
+
+string translate_weaponarena(string s)
+{
+       if (s == "") return s;
+       if (s == "All Weapons Arena") return _("All Weapons Arena");
+       if (s == "All Available Weapons Arena") return _("All Available Weapons Arena");
+       if (s == "Most Weapons Arena") return _("Most Weapons Arena");
+       if (s == "Most Available Weapons Arena") return _("Most Available Weapons Arena");
+       if (s == "Dev All Weapons Arena") return s; // development option, do not translate
+       if (s == "Dev All Available Weapons Arena") return s; // development option, do not translate
+       if (s == "No Weapons Arena") return _("No Weapons Arena");
+
+       int n = tokenizebyseparator(s, " & ");
+       string wpn_list = "";
+       for (int i = 0; i < n; i++)
+       {
+               Weapon wep = Weapon_from_name(argv(i));
+               if (wep == WEP_Null)
+                       LOG_INFO("^3Warning: ^7server sent an invalid weapon name\n");
+               wpn_list = cons_mid(wpn_list, " & ", wep.m_name);
+       }
+       if (wpn_list != "")
+               return sprintf(_("%s Arena"), wpn_list);
+       else
+               return _("No Weapons Arena");
+}
+
+string GetVersionMessage(string hostversion, bool version_mismatch, bool version_check)
+{
+       string xonotic_hostversion = strcat("Xonotic ", hostversion);
+       if (version_mismatch)
+       {
+               if(!version_check)
+                       return strcat(sprintf(_("This is %s"), xonotic_hostversion), "\n^3",
+                               _("Your client version is outdated."), "\n\n\n",
+                               _("### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###"), "\n\n\n",
+                               _("Please update!"));
+               else
+                       return strcat(sprintf(_("This is %s"), xonotic_hostversion), "\n^3",
+                               _("This server is using an outdated Xonotic version."), "\n\n\n",
+                               _("### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###"));
+       }
+       return sprintf(_("Welcome to %s"), xonotic_hostversion);
+}
+
 bool net_handle_ServerWelcome()
 {
        bool campaign = ReadByte();
@@ -1339,20 +1388,32 @@ bool net_handle_ServerWelcome()
 
        welcome_msg_force_centerprint = ReadByte();
        strcpy(hostname, ReadString());
-       string ver = ReadString();
-       string modifications = ReadString();
+
+       string hostversion = ReadString();
+       bool version_mismatch = ReadByte();
+       bool version_check = ReadByte();
+       string ver = GetVersionMessage(hostversion, version_mismatch, version_check);
+
+       string modifications = translate_modifications(ReadString());
+       string weaponarena_list = translate_weaponarena(ReadString());
        string cache_mutatormsg = ReadString();
-       string mutator_msg = ReadString();
        string motd = ReadString();
 
        string msg = "";
        msg = strcat(msg, ver);
        msg = strcat(msg, "^8\n\n", strcat(_("Gametype:"), " ^1", MapInfo_Type_ToText(gametype)), "^8\n");
+
+       modifications = cons_mid(modifications, ", ", weaponarena_list);
        if(modifications != "")
                msg = strcat(msg, "^8\n", _("Active modifications:"), " ^3", modifications, "^8\n");
+
        if (cache_mutatormsg != "")
                msg = strcat(msg, "\n\n^8", _("Special gameplay tips:"), " ^7", cache_mutatormsg);
+       string mutator_msg = "";
+       MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
+       mutator_msg = M_ARGV(0, string);
        msg = strcat(msg, mutator_msg); // trust that the mutator will do proper formatting
+
        if (motd != "")
                msg = strcat(msg, "\n\n^8", _("MOTD:"), " ^7", motd);
 
index 0a1772fc47d8aa501aa90f13e21655d214e52d94..855d20f818fbf7d04028cd255ec5067f42ab25f8 100644 (file)
@@ -1591,7 +1591,6 @@ void CSQC_UpdateView(entity this, float w, float h)
                current_player = player_localnum;
        myteam = entcs_GetTeam(current_player);
 
-       // abused multiple places below
        entity local_player = ((csqcplayer) ? csqcplayer : CSQCModel_server2csqc(player_localentnum - 1));
        if(!local_player)
                local_player = this; // fall back!
@@ -1675,7 +1674,6 @@ void CSQC_UpdateView(entity this, float w, float h)
        // Draw the World (and sky)
        setproperty(VF_DRAWWORLD, 1);
 
-       // Set the console size vars
        vid_conwidth = autocvar_vid_conwidth;
        vid_conheight = autocvar_vid_conheight;
        vid_pixelheight = autocvar_vid_pixelheight;
@@ -1684,18 +1682,8 @@ void CSQC_UpdateView(entity this, float w, float h)
 
        View_DemoCamera();
 
-       // Draw the Crosshair
-       setproperty(VF_DRAWCROSSHAIR, 0); //Make sure engine crosshairs are always hidden
-
-       // Draw the Engine Status Bar (the default Quake HUD)
-       setproperty(VF_DRAWENGINESBAR, 0);
-
-       // Update the mouse position
-       /*
-          mousepos_x = vid_conwidth;
-          mousepos_y = vid_conheight;
-          mousepos = mousepos*0.5 + getmousepos();
-        */
+       setproperty(VF_DRAWCROSSHAIR, 0); // hide engine crosshair
+       setproperty(VF_DRAWENGINESBAR, 0); // hide engine status bar
 
        IL_EACH(g_drawables, it.draw, it.draw(it));
 
index e5e68b6106fed48992f8d3d743eb9f087ac168c6..626c4cffa673fed98b3a14f972594068a0eaca51 100644 (file)
@@ -1,4 +1,7 @@
 // generated file; do not modify
+#ifdef CSQC
+    #include <common/mutators/mutator/hook/cl_hook.qc>
+#endif
 #ifdef SVQC
     #include <common/mutators/mutator/hook/sv_hook.qc>
 #endif
index 5a5d26e8172fd5ee077fc200e18a519b64acca0c..1216e36e8bacd8feb26deba268219a1c334c921d 100644 (file)
@@ -1,4 +1,7 @@
 // generated file; do not modify
+#ifdef CSQC
+    #include <common/mutators/mutator/hook/cl_hook.qh>
+#endif
 #ifdef SVQC
     #include <common/mutators/mutator/hook/sv_hook.qh>
 #endif
diff --git a/qcsrc/common/mutators/mutator/hook/cl_hook.qc b/qcsrc/common/mutators/mutator/hook/cl_hook.qc
new file mode 100644 (file)
index 0000000..be88853
--- /dev/null
@@ -0,0 +1,16 @@
+#include "cl_hook.qh"
+
+#ifdef CSQC
+REGISTER_MUTATOR(cl_hook, true);
+
+MUTATOR_HOOKFUNCTION(cl_hook, BuildGameplayTipsString)
+{
+       if (mut_is_active(MUT_GRAPPLING_HOOK))
+       {
+               string key = getcommandkey(_("off-hand hook"), "+hook");
+               M_ARGV(0, string) = strcat(M_ARGV(0, string),
+                       "\n\n", sprintf(_("^3grappling hook^8 is enabled, press ^3%s^8 to use it"), key), "\n");
+       }
+}
+
+#endif
diff --git a/qcsrc/common/mutators/mutator/hook/cl_hook.qh b/qcsrc/common/mutators/mutator/hook/cl_hook.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
index c6a595363c3a272f64b4a4e0f89de37c7e94e9c6..94379cbb2828410315ee8312c1f42844a32dcdb1 100644 (file)
@@ -30,11 +30,6 @@ MUTATOR_HOOKFUNCTION(hook, BuildMutatorsPrettyString)
     M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Hook");
 }
 
-MUTATOR_HOOKFUNCTION(hook, BuildGameplayTipsString)
-{
-    M_ARGV(0, string) = strcat(M_ARGV(0, string), "\n\n^3grappling hook^8 is enabled, press 'e' (+hook) to use it\n");
-}
-
 MUTATOR_HOOKFUNCTION(hook, SetStartItems)
 {
     if(autocvar_g_grappling_hook_useammo)
index 2abb0b5967483dcf11383b5b417bd367f89a6c29..2131228ebf2e47a13a7676b0e09d5c9fad16caac 100644 (file)
@@ -453,7 +453,7 @@ MUTATOR_HOOKFUNCTION(mutator_instagib, BuildMutatorsString)
 
 MUTATOR_HOOKFUNCTION(mutator_instagib, BuildMutatorsPrettyString)
 {
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", instagib");
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", InstaGib");
 }
 
 MUTATOR_HOOKFUNCTION(mutator_instagib, SetModname)
index 2596770daa57be0c2b595873d79f18ecb40ee66f..ec031730e5ee60e1b94e642bec059657f53644db 100644 (file)
@@ -48,5 +48,5 @@ MUTATOR_HOOKFUNCTION(melee_only, BuildMutatorsString)
 
 MUTATOR_HOOKFUNCTION(melee_only, BuildMutatorsPrettyString)
 {
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Melee Only Arena");
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Melee only Arena");
 }
index 7a00bd686b5b122b4b481e42fced7119becc67ce..5ea4cb49cfb9a4d4deb6802d8bf8e82d1cad3491 100644 (file)
@@ -117,6 +117,17 @@ MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile)
        else
                proj.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
 }
+
+MUTATOR_HOOKFUNCTION(cl_nades, BuildGameplayTipsString)
+{
+       if (mut_is_active(MUT_NADES))
+       {
+               string key = getcommandkey(_("drop weapon / throw nade"), "dropweapon");
+               M_ARGV(0, string) = strcat(M_ARGV(0, string),
+                       "\n\n", sprintf(_("^3nades^8 are enabled, press ^3%s^8 to use them"), key), "\n");
+       }
+}
+
 bool Projectile_isnade(int p)
 {
        return Nade_FromProjectile(p) != NADE_TYPE_Null;
@@ -1564,14 +1575,14 @@ MUTATOR_HOOKFUNCTION(nades, SpectateCopy)
        STAT(VEIL_ORB_ALPHA, client) = STAT(VEIL_ORB_ALPHA, spectatee);
 }
 
-MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString)
+MUTATOR_HOOKFUNCTION(nades, BuildMutatorsPrettyString)
 {
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Nades");
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), "Nades");
 }
 
-MUTATOR_HOOKFUNCTION(nades, BuildGameplayTipsString)
+MUTATOR_HOOKFUNCTION(nades, BuildMutatorsString)
 {
-       M_ARGV(0, string) = strcat(M_ARGV(0, string), "\n\n^3nades^8 are enabled, press 'g' (dropweapon) to use them\n");
+       M_ARGV(0, string) = strcat(M_ARGV(0, string), ":Nades");
 }
 
 #endif
index 41bb01e55eeaee272278e8ede77ab4f8c05be397..0a555570d1d6f6b83db21e4ee1275425cfde8542 100644 (file)
@@ -1,4 +1,7 @@
 // generated file; do not modify
+#ifdef CSQC
+    #include <common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qc>
+#endif
 #ifdef SVQC
     #include <common/mutators/mutator/offhand_blaster/sv_offhand_blaster.qc>
 #endif
index 5e11096a532644d671eb7bd409b0519e08d3c3bd..2c4587f417b2e1e3820e3f4b1facd22e55b1d772 100644 (file)
@@ -1,4 +1,7 @@
 // generated file; do not modify
+#ifdef CSQC
+    #include <common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qh>
+#endif
 #ifdef SVQC
     #include <common/mutators/mutator/offhand_blaster/sv_offhand_blaster.qh>
 #endif
diff --git a/qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qc b/qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qc
new file mode 100644 (file)
index 0000000..f6b15ae
--- /dev/null
@@ -0,0 +1,13 @@
+#include "cl_offhand_blaster.qh"
+
+REGISTER_MUTATOR(cl_offhand_blaster, true);
+
+MUTATOR_HOOKFUNCTION(cl_offhand_blaster, BuildGameplayTipsString)
+{
+       if (mut_is_active(MUT_OFFHAND_BLASTER))
+       {
+               string key = getcommandkey(_("off-hand hook"), "+hook");
+               M_ARGV(0, string) = strcat(M_ARGV(0, string),
+                       "\n\n", sprintf(_("^3offhand blaster^8 is enabled, press ^3%s^8 to use it"), key), "\n");
+       }
+}
diff --git a/qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qh b/qcsrc/common/mutators/mutator/offhand_blaster/cl_offhand_blaster.qh
new file mode 100644 (file)
index 0000000..6f70f09
--- /dev/null
@@ -0,0 +1 @@
+#pragma once
index fbffa8a439cd241d5977bde45d876661fdcb9c7e..931ab1ad9991f517cde5ab95e56f5f4dd53a9db7 100644 (file)
@@ -14,11 +14,6 @@ MUTATOR_HOOKFUNCTION(offhand_blaster, BuildMutatorsPrettyString)
        M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Offhand blaster");
 }
 
-MUTATOR_HOOKFUNCTION(offhand_blaster, BuildGameplayTipsString)
-{
-    M_ARGV(0, string) = strcat(M_ARGV(0, string), "\n\n^3offhand blaster^8 is enabled, press 'e' (+hook) to use it\n");
-}
-
 MUTATOR_HOOKFUNCTION(offhand_blaster, PlayerSpawn)
 {
        entity player = M_ARGV(0, entity);
index 4e52b83e0951f7d76ddd001c0216da8e770675e3..06feced27bc5ca66305f999f86d2a9eacf884a46 100644 (file)
@@ -86,6 +86,7 @@ void PlayerStats_GameReport(float finished);
 void PlayerStats_GameReport_Handler(entity fh, entity pass, float status);
 
 .string playerstats_id;
+.float scoreboard_pos;
 
 //string autocvar_g_playerstats_uri;
 
index 469ab50d8c809bc4d52d6d4d27e3cc70693b7722..1dc444b3ec3181e8012bfcb9182416d996cd7512 100644 (file)
@@ -210,6 +210,70 @@ string draw_UseSkinFor(string pic)
        else
                return strcat(draw_currentSkin, "/", pic);
 }
+
+void mut_set_active(int mut)
+{
+       if (mut >= 24)
+               active_mutators[1] |= BIT(mut - 24);
+       else
+               active_mutators[0] |= BIT(mut);
+}
+
+bool mut_is_active(int mut)
+{
+       if (mut >= 24)
+               return (active_mutators[1] & (BIT(mut - 24)));
+       else
+               return (active_mutators[0] & BIT(mut));
+}
+
+// if s == "" (MENUQC) builds the mutator list for the Mutators dialog based on local cvar values
+// otherwise (CSQC) translates the mutator list (s) that client has received from server
+// NOTE: this function merges MENUQC and CSQC code in order to avoid duplicating and separating strings
+string build_mutator_list(string s)
+{
+       int i = -1, n = 0; // allow only 1 iteration in the following for loop if (s == "")
+       if (s != "")
+       {
+               i = 0;
+               n = tokenizebyseparator(s, ", ");
+       }
+       string s2 = "";
+       for (string arg = ""; i < n; i++)
+       {
+               if (i >= 0) arg = argv(i);
+               // cond is the condition for showing the mutator enabled in the menu
+               #define X(name, translated_name, mut, cond) \
+                       if(arg == name || (!n && (cond))) { s2 = cons_mid(s2, ", ", translated_name); mut_set_active(mut); }
+               X("Dodging"                   , _("Dodging")                   , MUT_DODGING                   , cvar("g_dodging"))
+               X("InstaGib"                  , _("InstaGib")                  , MUT_INSTAGIB                  , cvar("g_instagib"))
+               X("New Toys"                  , _("New Toys")                  , MUT_NEW_TOYS                  , cvar("g_new_toys"))
+               X("NIX"                       , _("NIX")                       , MUT_NIX                       , cvar("g_nix"))
+               X("Rocket Flying"             , _("Rocket Flying")             , MUT_ROCKET_FLYING             , cvar("g_rocket_flying"))
+               X("Invincible Projectiles"    , _("Invincible Projectiles")    , MUT_INVINCIBLE_PROJECTILES    , cvar("g_invincible_projectiles"))
+               X("Low gravity"               , _("Low gravity")               , MUT_GRAVITY                   , cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
+               X("Cloaked"                   , _("Cloaked")                   , MUT_CLOAKED                   , cvar("g_cloaked"))
+               X("Hook"                      , _("Hook")                      , MUT_GRAPPLING_HOOK            , cvar("g_grappling_hook"))
+               X("Midair"                    , _("Midair")                    , MUT_MIDAIR                    , cvar("g_midair"))
+               X("Melee only Arena"          , _("Melee only Arena")          , MUT_MELEE_ONLY                , cvar("g_melee_only"))
+               X("Vampire"                   , _("Vampire")                   , MUT_VAMPIRE                   , cvar("g_vampire"))
+               X("Piñata"                    , _("Piñata")                    , MUT_PINATA                    , cvar("g_pinata"))
+               X("Weapons stay"              , _("Weapons stay")              , MUT_WEAPON_STAY               , cvar("g_weapon_stay"))
+               X("Blood loss"                , _("Blood loss")                , MUT_BLOODLOSS                 , cvar("g_bloodloss") > 0)
+               X("Jetpack"                   , _("Jetpack")                   , MUT_JETPACK                   , cvar("g_jetpack"))
+               X("Buffs"                     , _("Buffs")                     , MUT_BUFFS                     , cvar("g_buffs") > 0)
+               X("Overkill"                  , _("Overkill")                  , MUT_OVERKILL                  , cvar("g_overkill"))
+               X("No powerups"               , _("No powerups")               , MUT_NO_POWERUPS               , cvar("g_powerups") == 0)
+               X("Powerups"                  , _("Powerups")                  , MUT_POWERUPS                  , cvar("g_powerups") > 0)
+               X("Touch explode"             , _("Touch explode")             , MUT_TOUCHEXPLODE              , cvar("g_touchexplode") > 0)
+               X("Wall jumping"              , _("Wall jumping")              , MUT_WALLJUMP                  , cvar("g_walljump"))
+               X("No start weapons"          , _("No start weapons")          , MUT_NO_START_WEAPONS          , cvar_string("g_weaponarena") == "0" && cvar("g_balance_blaster_weaponstartoverride") == 0)
+               X("Nades"                     , _("Nades")                     , MUT_NADES                     , cvar("g_nades"))
+               X("Offhand blaster"           , _("Offhand blaster")           , MUT_OFFHAND_BLASTER           , cvar("g_offhand_blaster"))
+               #undef X
+       }
+       return s2;
+}
 #endif
 
 void wordwrap_cb(string s, float l, void(string) callback)
index 1334f5ec35c392d41be44559cade95dc561931c7..3ca09994ac3be97da0b957c4c512138255b832bd 100644 (file)
@@ -44,6 +44,40 @@ void wordwrap_cb(string s, float l, void(string) callback);
 #ifndef SVQC
 string draw_currentSkin;
 string draw_UseSkinFor(string pic);
+
+// NOTE they aren't all registered mutators, e.g. jetpack, low gravity
+// TODO add missing "mutators"
+const int MUT_DODGING = 0;
+const int MUT_INSTAGIB = 1;
+const int MUT_NEW_TOYS = 2;
+const int MUT_NIX = 3;
+const int MUT_ROCKET_FLYING = 4;
+const int MUT_INVINCIBLE_PROJECTILES = 5;
+const int MUT_GRAVITY = 6;
+const int MUT_CLOAKED = 7;
+const int MUT_GRAPPLING_HOOK = 8;
+const int MUT_MIDAIR = 9;
+const int MUT_MELEE_ONLY = 10;
+const int MUT_VAMPIRE = 11;
+const int MUT_PINATA = 12;
+const int MUT_WEAPON_STAY = 13;
+const int MUT_BLOODLOSS = 14;
+const int MUT_JETPACK = 15;
+const int MUT_BUFFS = 16;
+const int MUT_OVERKILL = 17;
+const int MUT_NO_POWERUPS = 18;
+const int MUT_POWERUPS = 19;
+const int MUT_TOUCHEXPLODE = 20;
+const int MUT_WALLJUMP = 21;
+const int MUT_NO_START_WEAPONS = 22;
+const int MUT_NADES = 23;
+const int MUT_OFFHAND_BLASTER = 24;
+
+const int MUT_MAX = 47;
+
+int active_mutators[2];
+bool mut_is_active(int mut);
+string build_mutator_list(string s);
 #endif
 
 // iterative depth-first search, with fields that go "up", "down left" and "right" in a tree
index 7473e8e8da66619524e0abdfefd2592f6fb85c36..564ffc5ae578e37bea3e8ddf63adc35c39b4522c 100644 (file)
@@ -22,12 +22,13 @@ string WeaponArenaString()
        string s;
        float n;
        s = cvar_string("g_weaponarena");
-       if(s == "0")
-               return "";
-       if(s == "all" || s == "1")
-               return _("All Weapons Arena");
-       if(s == "most")
-               return _("Most Weapons Arena");
+       if(s == "0" || s == "") return "";
+       if(s == "all" || s == "1") return _("All Weapons Arena");
+       if(s == "all_available") return _("All Available Weapons Arena");
+       if(s == "most") return _("Most Weapons Arena");
+       if(s == "most_available") return _("Most Available Weapons Arena");
+       if(s == "devall") return "Dev All Weapons Arena"; // development option, do not translate
+       if(s == "devall_available") return "Dev All Available Weapons Arena"; // development option, do not translate
        if(s == weaponarenastring_cvar)
                return weaponarenastring;
 
@@ -43,7 +44,10 @@ string WeaponArenaString()
                        s = cons_mid(s, " & ", wep.m_name);
                }
        }
-       s = sprintf(_("%s Arena"), s);
+       if (s != "")
+               s = sprintf(_("%s Arena"), s);
+       else
+               s = _("No Weapons Arena");
 
        strcpy(weaponarenastring, s);
 
@@ -52,55 +56,9 @@ string WeaponArenaString()
 
 string XonoticMutatorsDialog_toString(entity me)
 {
-       string s = "";
-       if(cvar("g_dodging"))
-               s = cons_mid(s, ", ", _("Dodging"));
-       if(cvar("g_instagib"))
-               s = cons_mid(s, ", ", _("InstaGib"));
-       if(cvar("g_new_toys"))
-               s = cons_mid(s, ", ", _("New Toys"));
-       if(cvar("g_nix"))
-               s = cons_mid(s, ", ", _("NIX"));
-       if(cvar("g_rocket_flying"))
-               s = cons_mid(s, ", ", _("Rocket Flying"));
-       if(cvar("g_invincible_projectiles"))
-               s = cons_mid(s, ", ", _("Invincible Projectiles"));
+       string s = build_mutator_list("");
        if(cvar_string("g_weaponarena") != "0")
                s = cons_mid(s, ", ", WeaponArenaString());
-       else if(cvar("g_balance_blaster_weaponstartoverride") == 0)
-               s = cons_mid(s, ", ", _("No start weapons"));
-       if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
-               s = cons_mid(s, ", ", _("Low gravity"));
-       if(cvar("g_cloaked"))
-               s = cons_mid(s, ", ", _("Cloaked"));
-       if(cvar("g_grappling_hook"))
-               s = cons_mid(s, ", ", _("Hook"));
-       if(cvar("g_midair"))
-               s = cons_mid(s, ", ", _("Midair"));
-       if(cvar("g_melee_only"))
-               s = cons_mid(s, ", ", _("Melee only"));
-       if(cvar("g_vampire"))
-               s = cons_mid(s, ", ", _("Vampire"));
-       if(cvar("g_pinata"))
-               s = cons_mid(s, ", ", _("Piñata"));
-       if(cvar("g_weapon_stay"))
-               s = cons_mid(s, ", ", _("Weapons stay"));
-       if(cvar("g_bloodloss") > 0)
-               s = cons_mid(s, ", ", _("Blood loss"));
-       if(cvar("g_jetpack"))
-               s = cons_mid(s, ", ", _("Jetpack"));
-       if(cvar("g_buffs") > 0)
-               s = cons_mid(s, ", ", _("Buffs"));
-       if(cvar("g_overkill"))
-               s = cons_mid(s, ", ", _("Overkill"));
-       if(cvar("g_powerups") == 0)
-               s = cons_mid(s, ", ", _("No powerups"));
-       if(cvar("g_powerups") > 0)
-               s = cons_mid(s, ", ", _("Powerups"));
-       if(cvar("g_touchexplode") > 0)
-               s = cons_mid(s, ", ", _("Touch explode"));
-       if(cvar("g_walljump"))
-               s = cons_mid(s, ", ", _("Wall jumping"));
        if(s == "")
                return ZCTX(_("MUT^None"));
        else
index 2c3bdc25ccf07e90931e1c0704cd09c44a0ffc71..bacb82e071429c219127ce07e5cc15888d39ff57 100644 (file)
@@ -1018,21 +1018,6 @@ void ClientPreConnect(entity this)
 }
 #endif
 
-string GetClientVersionMessage(entity this)
-{
-       if (CS(this).version_mismatch) {
-               if(CS(this).version < autocvar_gameversion) {
-                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
-                               "\n^3Your client version is outdated.\n\n\n### YOU WON'T BE ABLE TO PLAY ON THIS SERVER ###\n\n\nPlease update!!!^8");
-               } else {
-                       return strcat("This is Xonotic ", autocvar_g_xonoticversion,
-                               "\n^3This server is using an outdated Xonotic version.\n\n\n ### THIS SERVER IS INCOMPATIBLE AND THUS YOU CANNOT JOIN ###.^8");
-               }
-       } else {
-               return strcat("Welcome to Xonotic ", autocvar_g_xonoticversion);
-       }
-}
-
 void SendWelcomemessage(entity this, bool force_centerprint)
 {
        msg_entity = this;
@@ -1040,6 +1025,9 @@ void SendWelcomemessage(entity this, bool force_centerprint)
        SendWelcomemessage_msg_type(this, force_centerprint, MSG_ONE);
 }
 
+// NOTE csqc uses the active mutators list sent by this function
+// to understand which mutators are enabled
+// also note that they aren't all registered mutators, e.g. jetpack, low gravity
 void SendWelcomemessage_msg_type(entity this, bool force_centerprint, int msg_type)
 {
        WriteByte(msg_type, boolean(autocvar_g_campaign));
@@ -1052,30 +1040,27 @@ void SendWelcomemessage_msg_type(entity this, bool force_centerprint, int msg_ty
        }
        WriteByte(msg_type, force_centerprint);
        WriteString(msg_type, autocvar_hostname);
-       WriteString(msg_type, GetClientVersionMessage(this));
+       WriteString(msg_type, autocvar_g_xonoticversion);
+       WriteByte(msg_type, CS(this).version_mismatch);
+       WriteByte(msg_type, (CS(this).version < autocvar_gameversion));
 
        MUTATOR_CALLHOOK(BuildMutatorsPrettyString, "");
        string modifications = M_ARGV(0, string);
 
-       if(g_weaponarena)
-       {
-               if(g_weaponarena_random)
-                       modifications = strcat(modifications, ", ", ftos(g_weaponarena_random), " of ", g_weaponarena_list, " Arena");
-               else
-                       modifications = strcat(modifications, ", ", g_weaponarena_list, " Arena");
-       }
-       else if(cvar("g_balance_blaster_weaponstartoverride") == 0)
+       if (!g_weaponarena && cvar("g_balance_blaster_weaponstartoverride") == 0)
                modifications = strcat(modifications, ", No start weapons");
        if(cvar("sv_gravity") < stof(cvar_defstring("sv_gravity")))
                modifications = strcat(modifications, ", Low gravity");
        if(g_weapon_stay && !g_cts)
                modifications = strcat(modifications, ", Weapons stay");
        if(autocvar_g_jetpack)
-               modifications = strcat(modifications, ", Jet pack");
+               modifications = strcat(modifications, ", Jetpack");
        modifications = substring(modifications, 2, strlen(modifications) - 2);
 
        WriteString(msg_type, modifications);
 
+       WriteString(msg_type, g_weaponarena_list);
+
        if(cache_lastmutatormsg != autocvar_g_mutatormsg)
        {
                strcpy(cache_lastmutatormsg, autocvar_g_mutatormsg);
@@ -1084,11 +1069,6 @@ void SendWelcomemessage_msg_type(entity this, bool force_centerprint, int msg_ty
 
        WriteString(msg_type, cache_mutatormsg);
 
-       string mutator_msg = "";
-       MUTATOR_CALLHOOK(BuildGameplayTipsString, mutator_msg);
-       mutator_msg = M_ARGV(0, string);
-
-       WriteString(msg_type, mutator_msg); // trust that the mutator will do proper formatting
        WriteString(msg_type, strreplace("\\n", "\n", autocvar_sv_motd));
 }
 
index 2287815f5acd2e43fc8c7b24d443344a83b28040..178181cbada248a0ee7e55f5da55b8583d09d6ea 100644 (file)
@@ -5,7 +5,6 @@
 bool autocvar_g_full_getstatus_responses;
 
 entity scores_initialized; // non-NULL when scores labels/rules have been set
-.float scoreboard_pos;
 
 /**
  * Attaches a PlayerScore entity to a player. Use that in ClientConnect.
index 5801fae88a3eb2fbd06d091e81bed09b779c38d4..9d4678ffd4814a04aed3a0185828e36dfbf8026a 100644 (file)
@@ -1884,25 +1884,25 @@ void readplayerstartcvars()
        else if (s == "all" || s == "1")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "All Weapons";
+               g_weaponarena_list = "All Weapons Arena";
                g_weaponarena_weapons = weapons_all();
        }
        else if (s == "devall")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "Dev All Weapons";
+               g_weaponarena_list = "Dev All Weapons Arena";
                g_weaponarena_weapons = weapons_devall();
        }
        else if (s == "most")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "Most Weapons";
+               g_weaponarena_list = "Most Weapons Arena";
                g_weaponarena_weapons = weapons_most();
        }
        else if (s == "all_available")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "All Available Weapons";
+               g_weaponarena_list = "All Available Weapons Arena";
 
                // this needs to run after weaponsInMapAll is initialized
                InitializeEntity(NULL, weaponarena_available_all_update, INITPRIO_FINDTARGET);
@@ -1910,7 +1910,7 @@ void readplayerstartcvars()
        else if (s == "devall_available")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "Dev All Available Weapons";
+               g_weaponarena_list = "Dev All Available Weapons Arena";
 
                // this needs to run after weaponsInMapAll is initialized
                InitializeEntity(NULL, weaponarena_available_devall_update, INITPRIO_FINDTARGET);
@@ -1918,7 +1918,7 @@ void readplayerstartcvars()
        else if (s == "most_available")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "Most Available Weapons";
+               g_weaponarena_list = "Most Available Weapons Arena";
 
                // this needs to run after weaponsInMapAll is initialized
                InitializeEntity(NULL, weaponarena_available_most_update, INITPRIO_FINDTARGET);
@@ -1926,7 +1926,7 @@ void readplayerstartcvars()
        else if (s == "none")
        {
                g_weaponarena = 1;
-               g_weaponarena_list = "No Weapons";
+               g_weaponarena_list = "No Weapons Arena";
        }
        else
        {
@@ -1940,10 +1940,13 @@ void readplayerstartcvars()
                        if(wep != WEP_Null)
                        {
                                g_weaponarena_weapons |= (wep.m_wepset);
-                               g_weaponarena_list = strcat(g_weaponarena_list, wep.m_name, " & ");
+                               g_weaponarena_list = strcat(g_weaponarena_list, wep.netname, " & ");
                        }
                }
-               g_weaponarena_list = strzone(substring(g_weaponarena_list, 0, strlen(g_weaponarena_list) - 3));
+               if (g_weaponarena_list != "") // remove trailing " & "
+                       g_weaponarena_list = substring(g_weaponarena_list, 0, strlen(g_weaponarena_list) - 3);
+               else // no valid weapon found
+                       g_weaponarena_list = "No Weapons Arena";
        }
 
        if (g_weaponarena)
@@ -1951,6 +1954,7 @@ void readplayerstartcvars()
                g_weapon_stay = 0; // incompatible
                start_weapons = g_weaponarena_weapons;
                start_items |= IT_UNLIMITED_AMMO | IT_UNLIMITED_SUPERWEAPONS;
+               g_weaponarena_list = strzone(g_weaponarena_list);
        }
        else
        {