]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Ask player if they want to forfeit on F3 press while playing. Allow F3 to switch...
authorterencehill <piuntn@gmail.com>
Sat, 14 Sep 2024 21:53:05 +0000 (23:53 +0200)
committerterencehill <piuntn@gmail.com>
Fri, 20 Sep 2024 16:41:24 +0000 (18:41 +0200)
The F3 key now consistently works while playing and while spectating another player

commands.cfg
qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc
qcsrc/common/gamemodes/gamemode/survival/sv_survival.qc
qcsrc/menu/xonotic/_mod.inc
qcsrc/menu/xonotic/_mod.qh
qcsrc/menu/xonotic/dialog_forfeit.qc [new file with mode: 0644]
qcsrc/menu/xonotic/dialog_forfeit.qh [new file with mode: 0644]
qcsrc/menu/xonotic/mainwindow.qc
qcsrc/server/command/cmd.qc
qcsrc/server/mutators/events.qh

index ae8719a0f5edd5743fa2a93093caac31d5a82c56..748f2aecd1ebd48c341a4961ae62b7878b2a007e 100644 (file)
@@ -129,6 +129,7 @@ alias menu_showhudoptions "menu_cmd directpanelhudmenu ${* ?}"
 alias menu_showsandboxtools "menu_cmd directmenu SandboxTools"
 alias menu_showquitdialog "menu_cmd directmenu Quit"
 alias menu_showgamemenudialog "menu_cmd directmenu GameMenu"
+alias menu_showforfeitdialog "menu_cmd directmenu Forfeit"
 alias menu_showmonstertools "menu_cmd directmenu MonsterTools"
 
 // command executed before loading a map by the menu
index 5315d1e88f017e05ae6aea4246000abad13a2936..b77e1b052733ecee8ffcfa6f2bcb23a75f11ca9a 100644 (file)
@@ -634,7 +634,7 @@ MUTATOR_HOOKFUNCTION(ca, ClientCommand_Spectate)
        {
                // they're going to spec, we can do other checks
                if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player)))
-                       Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_LEAVE);
+                       return MUT_SPECCMD_RETURN_FORFEIT;
                return MUT_SPECCMD_FORCE;
        }
 
index deaae435c1b6e7289e826e1fa3965eb15bf8304b..8252769801e15427ab99ce75dce1bc3a4a38ee64 100644 (file)
@@ -483,7 +483,7 @@ MUTATOR_HOOKFUNCTION(surv, ClientCommand_Spectate)
        {
                // they're going to spec, we can do other checks
                if (autocvar_sv_spectate && (IS_SPEC(player) || IS_OBSERVER(player)))
-                       Send_Notification(NOTIF_ONE_ONLY, player, MSG_INFO, INFO_CA_LEAVE);
+                       return MUT_SPECCMD_RETURN_FORFEIT;
                return MUT_SPECCMD_FORCE;
        }
 
index 96287299d70af00054664583d628a686fef5b549..8d2c3e8a4f09684be94f1d6a0acbc117f3010b89 100644 (file)
@@ -20,6 +20,7 @@
 #include <menu/xonotic/dialog.qc>
 #include <menu/xonotic/dialog_credits.qc>
 #include <menu/xonotic/dialog_firstrun.qc>
+#include <menu/xonotic/dialog_forfeit.qc>
 #include <menu/xonotic/dialog_gamemenu.qc>
 #include <menu/xonotic/dialog_hudpanel_ammo.qc>
 #include <menu/xonotic/dialog_hudpanel_centerprint.qc>
index c8941bbd6eda7b6f7e326303ffcdceb9e56265d2..a9a94c9c10b2532c35a7ebf2de6cb26f73ccd8d1 100644 (file)
@@ -20,6 +20,7 @@
 #include <menu/xonotic/dialog.qh>
 #include <menu/xonotic/dialog_credits.qh>
 #include <menu/xonotic/dialog_firstrun.qh>
+#include <menu/xonotic/dialog_forfeit.qh>
 #include <menu/xonotic/dialog_gamemenu.qh>
 #include <menu/xonotic/dialog_hudpanel_ammo.qh>
 #include <menu/xonotic/dialog_hudpanel_centerprint.qh>
diff --git a/qcsrc/menu/xonotic/dialog_forfeit.qc b/qcsrc/menu/xonotic/dialog_forfeit.qc
new file mode 100644 (file)
index 0000000..c6e2bca
--- /dev/null
@@ -0,0 +1,18 @@
+#include "dialog_forfeit.qh"
+
+#include "button.qh"
+#include "commandbutton.qh"
+#include "textlabel.qh"
+
+void XonoticForfeitDialog_fill(entity me)
+{
+       entity e;
+       me.TR(me);
+               me.TD(me, 1, 2, makeXonoticTextLabel(0.5, _("Are you sure you want to observe and quit current match?")));
+       me.TR(me);
+       me.TR(me);
+               me.TD(me, 1, 1, e = makeXonoticCommandButton(_("Yes"), '1 0 0', "spec \"\" FORFEIT", COMMANDBUTTON_CLOSE));
+               me.TD(me, 1, 1, e = makeXonoticButton(_("No"), '0 1 0'));
+                       e.onClick = Dialog_Close;
+                       e.onClickEntity = me;
+}
diff --git a/qcsrc/menu/xonotic/dialog_forfeit.qh b/qcsrc/menu/xonotic/dialog_forfeit.qh
new file mode 100644 (file)
index 0000000..7e8ecb3
--- /dev/null
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "dialog.qh"
+CLASS(XonoticForfeitDialog, XonoticRootDialog)
+       METHOD(XonoticForfeitDialog, fill, void(entity));
+       ATTRIB(XonoticForfeitDialog, title, string, _("Forfeit"));
+       ATTRIB(XonoticForfeitDialog, name, string, "Forfeit");
+       ATTRIB(XonoticForfeitDialog, color, vector, SKINCOLOR_DIALOG_QUIT);
+       ATTRIB(XonoticForfeitDialog, intendedWidth, float, 0.5);
+       ATTRIB(XonoticForfeitDialog, rows, float, 3);
+       ATTRIB(XonoticForfeitDialog, columns, float, 2);
+ENDCLASS(XonoticForfeitDialog)
index 039d3452fd0038762f728159950f26807c1ee9ae..3eacbed8c0a441038292a97e1573a1d713ff2c5b 100644 (file)
@@ -6,6 +6,7 @@
 #include "inputbox.qh"
 #include "dialog_termsofservice.qh"
 #include "dialog_firstrun.qh"
+#include "dialog_forfeit.qh"
 #include "dialog_hudsetup_exit.qh"
 #include "dialog_hudpanel_notification.qh"
 #include "dialog_hudpanel_ammo.qh"
@@ -268,6 +269,10 @@ void MainWindow_configureMainWindow(entity me)
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
 
+       i = NEW(XonoticForfeitDialog);
+       i.configureDialog(i);
+       me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z);
+
        i = NEW(XonoticMonsterToolsDialog);
        i.configureDialog(i);
        me.addItemCentered(me, i, i.intendedWidth * eX + i.intendedHeight * eY, SKINALPHAS_MAINMENU_z * SKINALPHA_DIALOG_SANDBOXTOOLS);
index 25a8c1b67676dd0ee5bbb383bea2e36233208689..e527029b53aa35b4bf1efa015952ac073049a6d3 100644 (file)
@@ -710,10 +710,42 @@ void ClientCommand_spectate(entity caller, int request)
                                        return;
                                }
 
+                               bool caller_wants_to_forfeit = false;
+                               if (argv(2) == "FORFEIT" || warmup_stage)
+                                       caller_wants_to_forfeit = true; // player replied that they want to forfeit
+
+                               if (IS_PLAYER(caller) && !caller_wants_to_forfeit)
+                               {
+                                       // ask player if they want to forfeit
+                                       stuffcmd(caller, "menu_showforfeitdialog\n");
+                                       return;
+                               }
+
+                               if (IS_SPEC(caller) && (!observe_blocked_if_eliminated || !INGAME(caller)))
+                               {
+                                       // turn spectator into observer
+                                       caller.would_spectate = false;
+                                       TRANSMUTE(Observer, caller);
+                                       PutClientInServer(caller);
+                                       caller.flags |= FL_CLIENT | FL_NOTARGET;
+                                       return;
+                               }
+
                                int mutator_returnvalue = MUTATOR_CALLHOOK(ClientCommand_Spectate, caller);
 
                                if (mutator_returnvalue == MUT_SPECCMD_RETURN) return;
 
+                               if (mutator_returnvalue == MUT_SPECCMD_RETURN_FORFEIT)
+                               {
+                                       if (caller_wants_to_forfeit)
+                                               mutator_returnvalue = MUT_SPECCMD_FORCE;
+                                       else
+                                       {
+                                               stuffcmd(caller, "menu_showobservedialog\n");
+                                               return;
+                                       }
+                               }
+
                                if ((IS_PLAYER(caller) || mutator_returnvalue == MUT_SPECCMD_FORCE || caller.wants_join))
                                if (autocvar_sv_spectate)
                                        ClientKill_TeamChange(caller, -2); // observe
@@ -726,8 +758,10 @@ void ClientCommand_spectate(entity caller, int request)
                default:
                case CMD_REQUEST_USAGE:
                {
-                       sprint(caller, "\nUsage:^3 cmd spectate [<client>]\n");
+                       sprint(caller, "\nUsage:^3 cmd spectate [<client>] [FORFEIT]\n");
                        sprint(caller, "  Where <client> can be the player to spectate.\n");
+                       sprint(caller, "  If <client> is \"\" or not specified, caller becomes observer.\n");
+                       sprint(caller, "  If <client> is \"\", FORFEIT makes so that caller forcedly quits current game.\n");
                        return;
                }
        }
index 34155a4d3c908335832d2f245073f92bebe033b8..53a09a9e3b6bfe3a9e1c70818de3992afe4c6ad4 100644 (file)
@@ -992,6 +992,7 @@ MUTATOR_HOOKABLE(ClientCommand_Spectate, EV_ClientCommand_Spectate);
 enum {
     MUT_SPECCMD_CONTINUE, // return this flag to make the function continue as normal
     MUT_SPECCMD_RETURN, // return this flag to make the function return (don't spectate)
+    MUT_SPECCMD_RETURN_FORFEIT, // like MUT_SPECCMD_RETURN and ask player if they want to forfeit
     MUT_SPECCMD_FORCE // return this flag to force the player to spectate, even if they're not a player
 };