From ef827efbf098705169dc94f3688ce627f4c46d9c Mon Sep 17 00:00:00 2001 From: greenmarine Date: Sat, 24 May 2008 16:22:19 +0000 Subject: [PATCH] new feature: g_tourney - splits the game into warmup and match stage - After a new map is loaded the game is automatically in warmup-stage. Players are able to get from warmup- to match-stage by reading up. During warmup-stage the players automatically have all weapons (with appropriate ammo) and much health and armor. The amount of health, armor and ammunition is defined in the g_tourney_start_xxxx variables. However, the map also has all the items like health, ammo and weapons that can be picked up. - spectator chat can be limited so that only specs can talk to each other, so players won't be disturbed during the match - admin can forbid spectators to call a vote git-svn-id: svn://svn.icculus.org/nexuiz/trunk@3657 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- data/defaultNexuiz.cfg | 12 +++++ data/qcsrc/server/clientcommands.qc | 74 ++++++++++++++++++++++++++--- data/qcsrc/server/defs.qh | 3 ++ data/qcsrc/server/g_world.qc | 6 +++ data/qcsrc/server/miscfunctions.qc | 23 ++++++--- data/qcsrc/server/teamplay.qc | 13 +++++ 6 files changed, 117 insertions(+), 14 deletions(-) diff --git a/data/defaultNexuiz.cfg b/data/defaultNexuiz.cfg index e6b104098..f54b8a326 100644 --- a/data/defaultNexuiz.cfg +++ b/data/defaultNexuiz.cfg @@ -127,6 +127,18 @@ set teamplay_lockonrestart 0 set g_maxplayers 0 //maximum number of players allowed to play at the same time, set to 0 to all players to join the game set g_maxplayers_spectator_blocktime 5 //if the players voted for the "nospectators" command, this setting defines the number of seconds a observer/spectator has time to join the game before he gets kicked +//tournament mod +set g_tourney 0 //enables tourney mode which splits the game into a warmup- and match-stage +set g_tourney_warmup_unlimited_time 1 //if set the warmup-stage is not affected by any timelimit, otherwise the usual timelimit also affects warmup-stage +set g_tourney_disable_spec_chat 1 //if set the chat sent by spectators or observers while being in match-stage can only seen by other specs/observers +set g_tourney_disable_spec_vote 1 //if set only players can call a vote during the match-stage (thus spectators and observers can't call a vote then) +set g_tourney_start_health 250 //starting values when being in warmup-stage +set g_tourney_start_armor 100 +set g_tourney_start_ammo_shells 50 +set g_tourney_start_ammo_nails 150 +set g_tourney_start_ammo_rockets 50 +set g_tourney_start_ammo_cells 50 + // use default physics exec physicsQBR.cfg diff --git a/data/qcsrc/server/clientcommands.qc b/data/qcsrc/server/clientcommands.qc index f2c9b18a7..92566aee4 100644 --- a/data/qcsrc/server/clientcommands.qc +++ b/data/qcsrc/server/clientcommands.qc @@ -123,7 +123,15 @@ void Say(entity source, float teamsay, string msgin) } else { - bprint(msgstr); + //when g_tourney is active and g_tourney_disable_spec_chat is set and game is in matchstage + //don't print the text from specs/observers to the players but only the other spectators + if(g_tourney && cvar("g_tourney_disable_spec_chat") && tourneyInMatchStage && source.classname != "player") { + FOR_EACH_REALCLIENT(head) if(head.classname != "player") { + sprint(head, msgstr); + } + } + else + bprint(msgstr); //ServerConsoleEcho(substring(msgstr, 1, strlen(msgstr) - 2), TRUE); } @@ -231,7 +239,10 @@ void SV_ParseClientCommand(string s) { } } else if(argv(1) == "call") { if(cvar("sv_vote_call")) { - if(votecalled) { + if(tourneyInMatchStage && cvar("g_tourney_disable_spec_vote") && self.classname != "player") { + sprint(self, "^1Error: Only players can call a vote during the match-stage.\n"); + } + else if(votecalled) { sprint(self, "^1There is already a vote called.\n"); } else { local string vote; @@ -701,7 +712,17 @@ void VoteAccept() { { votecaller.vote_master = 1; } else { - localcmd(strcat(votecalledvote, "\n")); + //in g_tourney mode and if the vote is a timelimit-change, don't change it immediately but after restart + if(cvar("g_tourney") && substring(votecalledvote, 0, 10) == "timelimit ") { + if( stof(substring(votecalledvote, 10, strlen(votecalledvote) - 10)) > 0 ) { + timelimit_orig = stof(substring(votecalledvote, 10, strlen(votecalledvote) - 10)); + bprint(strcat("The timelimit will be set to ", ftos(timelimit_orig), " minutes after the next restart!\n")); + } + else //calls like "timelimit -1" can pass immediately + localcmd(strcat(votecalledvote, "\n")); + } + else + localcmd(strcat(votecalledvote, "\n")); } votecaller.vote_next = 0; // people like your votes, no wait for next vote VoteReset(); @@ -763,6 +784,12 @@ void VoteCount() { local float abstaincount; abstaincount = 0; local entity player; + //same for real players + local float realplayercount; + local float realplayeryescount; + local float realplayernocount; + local float realplayerabstaincount; + realplayercount = realplayernocount = realplayerabstaincount = realplayeryescount = 0; FOR_EACH_REALCLIENT(player) { @@ -774,8 +801,28 @@ void VoteCount() { abstaincount++; } playercount++; + //do the same for real players + if(player.classname == "player") { + if(player.vote_vote == -1) { + realplayernocount++; + } else if(player.vote_vote == 1) { + realplayeryescount++; + } else if(player.vote_vote == -2) { + realplayerabstaincount++; + } + realplayercount++; + } + } + + //in tournament mode, if we have at least one player then don't make the vote dependent on spectators (so specs don't have to press F1) + if( cvar("g_tourney") && (realplayercount > 0) ) { + yescount = realplayeryescount; + nocount = realplayernocount; + abstaincount = realplayerabstaincount; + playercount = realplayercount; } + if((playercount == 1) && votecalledmaster) { // if only one player is on the server becoming vote // master is not allowed. This could be used for @@ -820,8 +867,6 @@ void VoteCount() { } } -float timelimit_orig; - /** * Counts how many players are ready. If not enough players are ready, the function * does nothing. If all players are ready, the timelimit will be extended and the @@ -867,6 +912,19 @@ void ReadyCount() remove(readyNagger); } + if(g_tourney) { + tourneyInMatchStage = 1; //once the game is restarted the game is in match stage + //reset weapons and ammo, health and armor to default: + start_items = IT_LASER | IT_SHOTGUN; + start_switchweapon = WEP_SHOTGUN; + start_ammo_shells = cvar("g_start_ammo_shells"); + start_ammo_nails = cvar("g_start_ammo_nails"); + start_ammo_rockets = cvar("g_start_ammo_rockets"); + start_ammo_cells = cvar("g_start_ammo_cells"); + start_health = cvar("g_balance_health_start"); + start_armorvalue = cvar("g_balance_armor_start"); + } + restart_countdown = time + RESTART_COUNTDOWN; restart_mapalreadyrestarted = 0; //reset this var, needed when cvar sv_ready_restart_repeatable is in use //reset the .ready status of all players (also spectators) @@ -874,12 +932,14 @@ void ReadyCount() { e.ready = 0; } - if(0