]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Implement basic spectator support for the minigames
authorMario <mario.mario@y7mail.com>
Mon, 13 Sep 2021 00:43:12 +0000 (10:43 +1000)
committerMario <mario.mario@y7mail.com>
Mon, 13 Sep 2021 00:43:12 +0000 (10:43 +1000)
qcsrc/common/minigames/minigame/bd.qc
qcsrc/common/minigames/minigame/c4.qc
qcsrc/common/minigames/minigame/nmm.qc
qcsrc/common/minigames/minigame/pong.qc
qcsrc/common/minigames/minigame/pp.qc
qcsrc/common/minigames/minigame/ps.qc
qcsrc/common/minigames/minigame/ttt.qc

index 50054edb96b53d73f4693b8ee74e9351c6a43820..635d1b8d5328e7dfcdb34582f4ac887d4fa67e8b 100644 (file)
@@ -21,6 +21,7 @@ const int BD_NUM_CNT = 20;
 const int BD_TILE_SIZE = 20;
 
 const int BD_TEAMS = 1;
+const int BD_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
 
 .int bd_dir;
 
@@ -881,30 +882,44 @@ int bd_server_event(entity minigame, string event, ...)
                {
                        int pl_num = minigame_count_players(minigame);
 
-                       if(pl_num >= BD_TEAMS) { return false; }
+                       if(pl_num >= BD_TEAMS) { return BD_SPECTATOR_TEAM; }
 
                        return 1;
                }
                case "cmd":
                {
+                       entity player = ...(0,entity);
+                       bool event_blocked = (player.team == BD_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "move":
+                                       if(event_blocked)
+                                               return true;
                                        bd_do_move(minigame, ...(0,entity), ((...(1,int)) >= 2 ? argv(1) : string_null), ((...(1,int)) >= 3 ? argv(2) : string_null), ((...(1,int)) >= 4 ? argv(3) : string_null));
                                        return true;
                                case "next":
+                                       if(event_blocked)
+                                               return true;
                                        bd_next_match(minigame,...(0,entity), ((...(1,int) >= 2 ? argv(1) : string_null)));
                                        return true;
                                case "restart":
+                                       if(event_blocked)
+                                               return true;
                                        bd_restart_match(minigame,...(0,entity));
                                        return true;
                                case "edit":
+                                       if(event_blocked)
+                                               return true;
                                        bd_activate_editor(minigame,...(0,entity));
                                        return true;
                                case "save":
+                                       if(event_blocked)
+                                               return true;
                                        bd_close_editor(minigame,...(0,entity));
                                        return true;
                                case "fill":
+                                       if(event_blocked)
+                                               return true;
                                        bd_do_fill(minigame, ...(0,entity), ((...(1,int)) >= 2 ? argv(1) : string_null), ((...(1,int)) >= 3 ? argv(2) : string_null));
                                        return true;
                        }
@@ -1124,15 +1139,18 @@ void bd_hud_status(vector pos, vector mySize)
        vector mypos;
        vector tile_size = '48 48 0';
 
-       mypos = pos;
-       drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-       mypos_y += player_fontsize_y;
-       drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       if(minigame_self.team != BD_SPECTATOR_TEAM)
+       {
+               mypos = pos;
+               drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+               mypos_y += player_fontsize_y;
+               drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       }
 
        entity e;
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != BD_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
@@ -1159,6 +1177,9 @@ void bd_hud_status(vector pos, vector mySize)
 // Turn a set of flags into a help message
 string bd_turn_to_string(int turnflags)
 {
+       if(minigame_self.team == BD_SPECTATOR_TEAM)
+               return _("You are spectating");
+
        if ( turnflags & BD_TURN_LOSS )
                return _("Better luck next time!");
 
@@ -1253,7 +1274,7 @@ int bd_client_event(entity minigame, string event, ...)
                case "key_released":
                {
                        bool event_blocked = ((event == "key_released")
-                               || !(minigame.minigame_flags & BD_TURN_MOVE));
+                               || !(minigame.minigame_flags & BD_TURN_MOVE) || (minigame_self.team == BD_SPECTATOR_TEAM));
                        if (!(minigame.minigame_flags & BD_TURN_WIN) && !(minigame.minigame_flags & BD_TURN_LOSS))
                        {
                                switch ( ...(0,int) )
@@ -1347,7 +1368,7 @@ int bd_client_event(entity minigame, string event, ...)
                }
                case "mouse_pressed":
                {
-                       if(minigame.minigame_flags & BD_TURN_EDIT)
+                       if((minigame.minigame_flags & BD_TURN_EDIT) && minigame_self.team != BD_SPECTATOR_TEAM)
                        {
                                if(...(0,int) == K_MOUSE1)
                                {
@@ -1368,7 +1389,7 @@ int bd_client_event(entity minigame, string event, ...)
                }
                case "mouse_moved":
                {
-                       if(minigame.minigame_flags & BD_TURN_EDIT)
+                       if((minigame.minigame_flags & BD_TURN_EDIT) && minigame_self.team != BD_SPECTATOR_TEAM)
                        {
                                vector mouse_pos = minigame_hud_normalize(mousepos,bd_boardpos,bd_boardsize);
                                bd_set_curr_pos(minigame_tile_name(mouse_pos,BD_LET_CNT,BD_NUM_CNT));
index 01adebea9f2a4509ec3c0d30ac38c9e4aaf3900f..6727655bc52853836e8b081d11e11980f056ec47 100644 (file)
@@ -18,6 +18,7 @@ const int C4_MAX_TILES = 42;
 const int C4_TILE_SIZE = 8;
 
 const int C4_TEAMS = 2;
+const int C4_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
 
 .int c4_npieces; // (minigame) number of pieces on the board (simplifies checking a draw)
 .int c4_nexteam; // (minigame) next team (used to change the starting team on following matches)
@@ -211,7 +212,7 @@ int c4_server_event(entity minigame, string event, ...)
                        int pl_num = minigame_count_players(minigame);
 
                        // Don't allow more than 2 players
-                       if(pl_num >= C4_TEAMS) { return false; }
+                       if(pl_num >= C4_TEAMS) { return C4_SPECTATOR_TEAM; }
 
                        // Get the right team
                        if(minigame.minigame_players)
@@ -222,9 +223,13 @@ int c4_server_event(entity minigame, string event, ...)
                }
                case "cmd":
                {
+                       entity player = ...(0,entity);
+                       bool event_blocked = (player.team == C4_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "move":
+                                       if(event_blocked)
+                                               return true;
                                        c4_move(minigame, ...(0,entity), ...(1,int) == 2 ? argv(1) : string_null );
                                        return true;
                        }
@@ -337,17 +342,20 @@ void c4_hud_status(vector pos, vector mySize)
        vector mypos;
        vector tile_size = '48 48 0';
 
-       mypos = pos;
-       if ( (active_minigame.minigame_flags&C4_TURN_TEAM) == 2 )
-               mypos_y  += player_fontsize_y + ts_y;
-       drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-       mypos_y += player_fontsize_y;
-       drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       if(minigame_self.team != C4_SPECTATOR_TEAM)
+       {
+               mypos = pos;
+               if ( (active_minigame.minigame_flags&C4_TURN_TEAM) == 2 )
+                       mypos_y  += player_fontsize_y + ts_y;
+               drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+               mypos_y += player_fontsize_y;
+               drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       }
 
        entity e;
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != C4_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        if ( e.team == 2 )
@@ -369,6 +377,9 @@ void c4_hud_status(vector pos, vector mySize)
 // Turn a set of flags into a help message
 string c4_turn_to_string(int turnflags)
 {
+       if(minigame_self.team == C4_SPECTATOR_TEAM)
+               return _("You are spectating");
+
        if ( turnflags & C4_TURN_DRAW )
                return _("Draw");
 
index ab35deaf9656fa35842c4ca53acd1182df2cb16f..ea7f3b42c76e97626100b7207f65b579a5b645c4 100644 (file)
@@ -17,6 +17,8 @@ const int NMM_PIECE_DEAD  = 0x0; // captured by the enemy
 const int NMM_PIECE_HOME  = 0x1; // not yet placed
 const int NMM_PIECE_BOARD = 0x2; // placed on the board
 
+const int NMM_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
+
 .int  nmm_tile_distance;
 .entity nmm_tile_piece;
 .string nmm_tile_hmill;
@@ -244,7 +246,7 @@ int nmm_server_event(entity minigame, string event, ...)
                for ( e = minigame.minigame_players; e; e = e.list_next )
                        n++;
                if ( n >= 2 )
-                       return 0;
+                       return NMM_SPECTATOR_TEAM;
                if ( minigame.minigame_players && minigame.minigame_players.team == 1 )
                        return 2;
                return 1;
@@ -517,16 +519,19 @@ void nmm_hud_status(vector pos, vector mySize)
        float piece_light = 1;
        entity e = NULL;
 
-       mypos = pos;
-       if ( (active_minigame.minigame_flags&NMM_TURN_TEAM) == 2 )
-               mypos_y  += player_fontsize_y + ts_y;
-       drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-       mypos_y += player_fontsize_y;
-       drawfill(mypos,eX*mySize_x+eY*piece_sz_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       if(minigame_self.team != NMM_SPECTATOR_TEAM)
+       {
+               mypos = pos;
+               if ( (active_minigame.minigame_flags&NMM_TURN_TEAM) == 2 )
+                       mypos_y  += player_fontsize_y + ts_y;
+               drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+               mypos_y += player_fontsize_y;
+               drawfill(mypos,eX*mySize_x+eY*piece_sz_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       }
 
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != NMM_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        if ( e.team == 2 )
@@ -596,6 +601,9 @@ void nmm_make_move(entity minigame)
 
 string nmm_turn_to_string(int turnflags)
 {
+       if( minigame_self.team == NMM_SPECTATOR_TEAM )
+               return _("You are spectating");
+
        if ( turnflags & NMM_TURN_WIN )
        {
                if ( (turnflags&NMM_TURN_TEAM) != minigame_self.team )
index 30bdd80665ff739f8e97daa4f6c640db8efc233a..412273d90b9fa19e2a95fe6ddae07f4004912dd3 100644 (file)
@@ -18,6 +18,7 @@ const int PONG_KEY_BOTH     = 0x03; // Player jamming keys at ramdom
 
 // fields
 const int PONG_MAX_PLAYERS = 4;
+const int PONG_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
 .int    pong_score;                    // (minigame_player) number of goals
 .int    pong_keys;                     // (client) pressed keys
 .entity pong_paddles[PONG_MAX_PLAYERS];// (minigame) paddles
@@ -352,7 +353,7 @@ int pong_server_event(entity minigame, string event, ...)
                {
                        // Don't allow joining a match that is already running
                        if ( minigame.minigame_flags & PONG_STATUS_PLAY )
-                               return false;
+                               return PONG_SPECTATOR_TEAM;
 
                        entity player = ...(0,entity);
                        int i;
@@ -365,7 +366,7 @@ int pong_server_event(entity minigame, string event, ...)
                                }
                        }
 
-                       return false;
+                       return PONG_SPECTATOR_TEAM;
                }
                case "part":
                {
@@ -389,9 +390,12 @@ int pong_server_event(entity minigame, string event, ...)
                case "cmd":
                {
                        entity player = ...(0,entity);
+                       bool event_blocked = (player.team == PONG_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "throw":
+                                       if(event_blocked)
+                                               return true;
                                        if ( minigame.minigame_flags & PONG_STATUS_WAIT )
                                        {
                                                minigame.minigame_flags = PONG_STATUS_PLAY |
@@ -410,23 +414,35 @@ int pong_server_event(entity minigame, string event, ...)
                                        }
                                        return true;
                                case "+movei":
+                                       if(event_blocked)
+                                               return true;
                                        player.pong_keys |= PONG_KEY_INCREASE;
                                        return true;
                                case "+moved":
+                                       if(event_blocked)
+                                               return true;
                                        player.pong_keys |= PONG_KEY_DECREASE;
                                        return true;
                                case "-movei":
+                                       if(event_blocked)
+                                               return true;
                                        player.pong_keys &= ~PONG_KEY_INCREASE;
                                        return true;
                                case "-moved":
+                                       if(event_blocked)
+                                               return true;
                                        player.pong_keys &= ~PONG_KEY_DECREASE;
                                        return true;
                                case "move":
+                                       if(event_blocked)
+                                               return true;
                                        if(argv(1))
                                                player.pong_keys = stoi(argv(1));
                                        return true;
                                case "pong_aimore":
                                {
+                                       if(event_blocked)
+                                               return true;
                                        // keep declaration here, moving it into for() reverses weapon order
                                        // potentially compiler bug
                                        int j;
@@ -445,6 +461,8 @@ int pong_server_event(entity minigame, string event, ...)
                                }
                                case "pong_ailess":
                                {
+                                       if(event_blocked)
+                                               return true;
                                        if ( minigame.minigame_flags & PONG_STATUS_WAIT )
                                        {
                                                entity paddle;
@@ -578,7 +596,7 @@ void pong_hud_status(vector pos, vector mySize)
        entity e;
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" || e.classname == "pong_ai" )
+               if ( (e.classname == "minigame_player" || e.classname == "pong_ai") && e.team != PONG_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        mypos_y  += (e.team-1) * (player_fontsize_y + ts_y);
@@ -602,7 +620,9 @@ void pong_hud_status(vector pos, vector mySize)
 string pong_message(int mgflags)
 {
        string rmessage = "";
-       if (mgflags & PONG_STATUS_WAIT)
+       if(minigame_self.team == PONG_SPECTATOR_TEAM)
+               rmessage = _("You are spectating");
+       else if (mgflags & PONG_STATUS_WAIT)
                rmessage = _("Press ^1Start Match^7 to start the match with the current players");
        return rmessage;
 }
@@ -621,7 +641,7 @@ int pong_client_event(entity minigame, string event, ...)
                }
                case "key_pressed":
                case "key_released":
-                       if ((minigame.minigame_flags & PONG_STATUS_PLAY))
+                       if ((minigame.minigame_flags & PONG_STATUS_PLAY) && minigame_self.team != PONG_SPECTATOR_TEAM)
                                switch ( ...(0,int) )
                                {
                                        case K_UPARROW:
index 4a445fa45c3a356f93d54e1367f84f1facd279cd..1c755b64065de1c5e8678d4e1c6b9193f2fd1ef7 100644 (file)
@@ -11,7 +11,7 @@ const int PP_TURN_TEAM1 = 0x0001;
 const int PP_TURN_TEAM2 = 0x0002;
 const int PP_TURN_TEAM  = 0x000f; // turn team mask
 
-const int PP_BLOCKED_TEAM = 5; // there won't ever be a 5th team, so we can abuse this
+const int PP_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
 
 const int PP_LET_CNT = 7;
 const int PP_NUM_CNT = 7;
@@ -225,7 +225,7 @@ int pp_server_event(entity minigame, string event, ...)
                        int pl_num = minigame_count_players(minigame);
 
                        // Don't allow more than 2 players
-                       if(pl_num >= 2) { return false; }
+                       if(pl_num >= 2) { return PP_SPECTATOR_TEAM; }
 
                        // Get the right team
                        if(minigame.minigame_players)
@@ -236,12 +236,18 @@ int pp_server_event(entity minigame, string event, ...)
                }
                case "cmd":
                {
+                       entity player = ...(0,entity);
+                       bool event_blocked = (player.team == PP_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "move":
+                                       if(event_blocked)
+                                               return true;
                                        pp_move(minigame, ...(0,entity), ...(1,int) == 2 ? argv(1) : string_null );
                                        return true;
                                case "next":
+                                       if(event_blocked)
+                                               return true;
                                        pp_next_match(minigame,...(0,entity));
                                        return true;
                        }
@@ -388,17 +394,20 @@ void pp_hud_status(vector pos, vector mySize)
        vector mypos;
        vector tile_size = '48 48 0';
 
-       mypos = pos;
-       if ( (active_minigame.minigame_flags&PP_TURN_TEAM) == 2 )
-               mypos_y  += player_fontsize_y + ts_y;
-       drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-       mypos_y += player_fontsize_y;
-       drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       if(minigame_self.team != PP_SPECTATOR_TEAM)
+       {
+               mypos = pos;
+               if ( (active_minigame.minigame_flags&PP_TURN_TEAM) == 2 )
+                       mypos_y  += player_fontsize_y + ts_y;
+               drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+               mypos_y += player_fontsize_y;
+               drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       }
 
        entity e;
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != PP_SPECTATOR_TEAM )
                {
                        vector tile_color = '1 1 1';
                        switch(e.team)
@@ -434,6 +443,9 @@ void pp_hud_status(vector pos, vector mySize)
 // Turn a set of flags into a help message
 string pp_turn_to_string(int turnflags)
 {
+       if(minigame_self.team == PP_SPECTATOR_TEAM)
+               return _("You are spectating");
+
        if ( turnflags & PP_TURN_DRAW )
                return _("Draw");
 
index c976819dc4dfe2afff2f4baf0cce03cb1ada5570..97bdfa6124b686c4dd466a9bc3faee686d1db98e 100644 (file)
@@ -6,6 +6,8 @@ const float PS_TURN_WIN   = 0x0200; // player has won
 const float PS_TURN_DRAW  = 0x0400; // player can make no more moves
 const float PS_TURN_TYPE  = 0x0f00; // turn type mask
 
+const int PS_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
+
 const int PS_LET_CNT = 7;
 const int PS_NUM_CNT = 7;
 
@@ -23,15 +25,14 @@ entity ps_find_piece(entity minig, string tile)
 
 bool ps_draw(entity minigame)
 {
-       int valid = 0;
        entity e = NULL;
        while( ( e = findentity(e,owner,minigame) ) )
                if( e.classname == "minigame_board_piece" )
                {
-                       ++valid;
+                       return true;
                }
 
-       return ((valid > 0) ? true : false);
+       return false;
 }
 
 bool ps_tile_blacklisted(string tile)
@@ -156,7 +157,7 @@ bool ps_move_piece(entity minigame, entity piece, string pos, int leti, int numb
 // make a move
 void ps_move(entity minigame, entity player, string thepiece, string pos )
 {
-       if ( minigame.minigame_flags & PS_TURN_MOVE )
+       if ( (minigame.minigame_flags & PS_TURN_MOVE) )
        if ( pos )
        {
                if ( ps_valid_tile(pos) )
@@ -245,17 +246,20 @@ int ps_server_event(entity minigame, string event, ...)
                        int pl_num = minigame_count_players(minigame);
 
                        // Don't allow more than 1 player
-                       if(pl_num >= 1) { return false; }
+                       if(pl_num >= 1) { return PS_SPECTATOR_TEAM; }
 
                        // Team 1 by default
                        return 1;
                }
                case "cmd":
                {
+                       entity player = ...(0,entity);
+                       bool event_blocked = (player.team == PS_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "move":
-
+                                       if(event_blocked)
+                                               return true;
                                        ps_move(minigame, ...(0,entity), (...(1,int) == 3 ? argv(1) : string_null), (...(1,int) == 3 ? argv(2) : string_null));
                                        return true;
                        }
@@ -447,10 +451,13 @@ void ps_hud_status(vector pos, vector mySize)
        vector mypos;
        vector tile_size = '48 48 0';
 
-       mypos = pos;
-       drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
-       mypos_y += player_fontsize_y;
-       drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       if(minigame_self.team != PS_SPECTATOR_TEAM)
+       {
+               mypos = pos;
+               drawfill(mypos,eX*mySize_x+eY*player_fontsize_y,'1 1 1',0.5,DRAWFLAG_ADDITIVE);
+               mypos_y += player_fontsize_y;
+               drawfill(mypos,eX*mySize_x+eY*tile_size_y,'1 1 1',0.25,DRAWFLAG_ADDITIVE);
+       }
 
        int remaining = 0;
        entity e;
@@ -464,7 +471,7 @@ void ps_hud_status(vector pos, vector mySize)
 
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != PS_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        minigame_drawcolorcodedstring_trunc(mySize_x,mypos,
@@ -487,6 +494,9 @@ void ps_hud_status(vector pos, vector mySize)
 // Turn a set of flags into a help message
 string ps_turn_to_string(int turnflags)
 {
+       if(minigame_self.team == PS_SPECTATOR_TEAM)
+               return _("You are spectating");
+
        if (turnflags & PS_TURN_DRAW )
                return _("No more valid moves");
 
@@ -543,7 +553,7 @@ int ps_client_event(entity minigame, string event, ...)
                case "key_pressed":
                case "key_released":
                {
-                       bool event_blocked = (event == "key_released");
+                       bool event_blocked = (event == "key_released" || minigame_self.team == PS_SPECTATOR_TEAM);
                        if (!(minigame.minigame_flags & PS_TURN_WIN) && !(minigame.minigame_flags & PS_TURN_DRAW))
                        {
                                switch ( ...(0,int) )
@@ -610,7 +620,7 @@ int ps_client_event(entity minigame, string event, ...)
                case "mouse_moved":
                {
                        vector mouse_pos = minigame_hud_normalize(mousepos,ps_boardpos,ps_boardsize);
-                       if ( minigame.minigame_flags == PS_TURN_MOVE )
+                       if ( minigame.minigame_flags == PS_TURN_MOVE && minigame_self.team != PS_SPECTATOR_TEAM )
                        {
                                ps_set_curr_pos(minigame_tile_name(mouse_pos,PS_NUM_CNT,PS_LET_CNT));
                        }
index 530243dc3a870f1bc58e6255320813ca71b85a9e..73fa4c6e99805bb20b9a581b0350f76ceda364ad 100644 (file)
@@ -15,6 +15,8 @@ const int TTT_TURN_TEAM  = 0x000f; // turn team mask
 const int TTT_SF_PLAYERSCORE  = MINIG_SF_CUSTOM;   // send minigame_player scores (won matches)
 const int TTT_SF_SINGLEPLAYER = MINIG_SF_CUSTOM<<1;// send minigame.ttt_ai
 
+const int TTT_SPECTATOR_TEAM = 255; // must be above max teams and equal to or below 255
+
 const int TTT_LET_CNT = 3;
 const int TTT_NUM_CNT = 3;
 const int TTT_TILE_SIZE = 3;
@@ -161,7 +163,7 @@ int ttt_server_event(entity minigame, string event, ...)
                                return false;
 
                        // Don't allow more than 2 players
-                       if(pl_num >= 2) { return false; }
+                       if(pl_num >= 2) { return TTT_SPECTATOR_TEAM; }
 
                        // Get the right team
                        if(minigame.minigame_players)
@@ -172,15 +174,23 @@ int ttt_server_event(entity minigame, string event, ...)
                }
                case "cmd":
                {
+                       entity player = ...(0,entity);
+                       bool event_blocked = (player.team == TTT_SPECTATOR_TEAM);
                        switch(argv(0))
                        {
                                case "move":
+                                       if(event_blocked)
+                                               return true;
                                        ttt_move(minigame, ...(0,entity), ...(1,int) == 2 ? argv(1) : string_null );
                                        return true;
                                case "next":
+                                       if(event_blocked)
+                                               return true;
                                        ttt_next_match(minigame,...(0,entity));
                                        return true;
                                case "singleplayer":
+                                       if(event_blocked)
+                                               return true;
                                        if ( minigame_count_players(minigame) == 1 )
                                        {
                                                minigame.ttt_ai = minigame_next_team(minigame.minigame_players.team, 2);
@@ -290,7 +300,7 @@ void ttt_hud_status(vector pos, vector mySize)
        entity e;
        FOREACH_MINIGAME_ENTITY(e)
        {
-               if ( e.classname == "minigame_player" )
+               if ( e.classname == "minigame_player" && e.team != TTT_SPECTATOR_TEAM )
                {
                        mypos = pos;
                        if ( e.team == 2 )
@@ -315,6 +325,9 @@ void ttt_hud_status(vector pos, vector mySize)
 // Turn a set of flags into a help message
 string ttt_turn_to_string(int turnflags)
 {
+       if(minigame_self.team == TTT_SPECTATOR_TEAM)
+               return _("You are spectating");
+
        if ( turnflags & TTT_TURN_DRAW )
                return _("Draw");