]> git.rm.cloudns.org Git - voretournament/voretournament.git/commitdiff
Use Xonotic's system for selecting teams and spectating
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Mon, 11 Jul 2011 15:35:10 +0000 (18:35 +0300)
committerMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>
Mon, 11 Jul 2011 15:35:10 +0000 (18:35 +0300)
data/defaultVT.cfg
data/qcsrc/server/cl_client.qc
data/qcsrc/server/clientcommands.qc
data/qcsrc/server/race.qc

index 419ddd8d37ccb0ed67373b82afae08788808460e..60e08cfa05fca25e92b5bcb87bcb7c54e2861170 100644 (file)
@@ -487,6 +487,7 @@ set g_rc_respawn_delay 0
 set g_cts_respawn_waves 0\r
 set g_cts_respawn_delay 0\r
 set g_cts_selfdamage 1 "0 = disable all selfdamage and falldamage in cts"\r
+set g_cts_finish_kill_delay 10 "prevent cheating by running back to the start line, and starting out with more speed than otherwise possible"\r
 set g_rpg_respawn_waves 0\r
 set g_rpg_respawn_delay 0\r
 \r
@@ -1262,7 +1263,8 @@ sv_gameplayfix_q2airaccelerate 1
 sv_gameplayfix_stepmultipletimes 1\r
 \r
 // delay for "kill" to prevent abuse\r
-set g_balance_kill_delay 5\r
+set g_balance_kill_delay 2\r
+set g_balance_kill_antispam 5\r
 \r
 // this feature is currently buggy in the engine (it appears to PREVENT any dropping in lots of maps, leading to weirdly aligned entities, and in some cases even CAUSES them to drop through solid, like in facing worlds nex)\r
 sv_gameplayfix_droptofloorstartsolid 0\r
index 702125d768da35fc2577ffdd187e688f9fbf818e..91d566f1b50a62634e706a9df3c292e3e3730571 100644 (file)
@@ -1119,6 +1119,7 @@ Called when a client types 'kill' in the console
 =============\r
 */\r
 \r
+.float clientkill_nexttime;\r
 void ClientKill_Now_TeamChange()\r
 {\r
        if(self.killindicator_teamchange == -1)\r
@@ -1126,24 +1127,32 @@ void ClientKill_Now_TeamChange()
                self.team = -1;\r
                JoinBestTeam( self, FALSE, FALSE );\r
        }\r
+       else if(self.killindicator_teamchange == -2)\r
+       {\r
+               if(g_ca)\r
+                       self.caplayer = 0;\r
+               if(blockSpectators)\r
+                       sprint(self, strcat("^7You have to become a player within the next ", ftos(cvar("g_maxplayers_spectator_blocktime")), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));\r
+               PutObserverInServer();\r
+       }\r
        else\r
                SV_ChangeTeam(self.killindicator_teamchange - 1);\r
 }\r
 \r
 void ClientKill_Now()\r
-{\r
+{      \r
+       if(self.killindicator && !wasfreed(self.killindicator))\r
+        remove(self.killindicator);\r
+       \r
+       self.killindicator = world;\r
+\r
        if(self.killindicator_teamchange)\r
                ClientKill_Now_TeamChange();\r
 \r
        // in any case:\r
        Damage(self, self, self, 100000, DEATH_KILL, self.origin, '0 0 0');\r
 \r
-       if(self.killindicator)\r
-       {\r
-               dprint("Cleaned up after a leaked kill indicator.\n");\r
-               remove(self.killindicator);\r
-               self.killindicator = world;\r
-       }\r
+       // now I am sure the player IS dead\r
 }\r
 void KillIndicator_Think()\r
 {\r
@@ -1160,6 +1169,11 @@ void KillIndicator_Think()
                ClientKill_Now(); // no oldself needed\r
                return;\r
        }\r
+    else if(g_cts && self.health == 1) // health == 1 means that it's silent\r
+    {\r
+        self.nextthink = time + 1;\r
+        self.cnt -= 1;\r
+    }\r
        else\r
        {\r
                if(self.cnt <= 10)\r
@@ -1172,6 +1186,8 @@ void KillIndicator_Think()
                        {\r
                                if(self.owner.killindicator_teamchange == -1)\r
                                        centerprint(self.owner, strcat("Changing team in ", ftos(self.cnt), " seconds"));\r
+                               else if(self.owner.killindicator_teamchange == -2)\r
+                                       centerprint(self.owner, strcat("Spectating in ", ftos(self.cnt), " seconds"));\r
                                else\r
                                        centerprint(self.owner, strcat("Changing to ", ColoredTeamName(self.owner.killindicator_teamchange), " in ", ftos(self.cnt), " seconds"));\r
                        }\r
@@ -1183,19 +1199,34 @@ void KillIndicator_Think()
        }\r
 }\r
 \r
-void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto\r
+void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec\r
 {\r
        float killtime;\r
        entity e;\r
        killtime = cvar("g_balance_kill_delay");\r
 \r
-       if(g_race_qualifying)\r
+       if(g_race_qualifying || g_cts)\r
                killtime = 0;\r
 \r
+    if(g_cts && self.killindicator && self.killindicator.health == 1) // self.killindicator.health == 1 means that the kill indicator was spawned by CTS_ClientKill\r
+    {\r
+               remove(self.killindicator);\r
+               self.killindicator = world;\r
+\r
+        ClientKill_Now(); // allow instant kill in this case\r
+        return;\r
+    }\r
+\r
        self.killindicator_teamchange = targetteam;\r
 \r
-       if(!self.killindicator)\r
+    if(!self.killindicator)\r
        {\r
+               if(self.modelindex && self.deadflag == DEAD_NO)\r
+               {\r
+                       killtime = max(killtime, self.clientkill_nexttime - time);\r
+                       self.clientkill_nexttime = time + killtime + cvar("g_balance_kill_antispam");\r
+               }\r
+\r
                if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO)\r
                {\r
                        ClientKill_Now();\r
@@ -1211,7 +1242,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto
                        self.killindicator.nextthink = time + (self.lip) * 0.05;\r
                        self.killindicator.cnt = ceil(killtime);\r
                        self.killindicator.count = bound(0, ceil(killtime), 10);\r
-                       sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n"));\r
+                       //sprint(self, strcat("^1You'll be dead in ", ftos(self.killindicator.cnt), " seconds\n"));\r
 \r
                        for(e = world; (e = find(e, classname, "body")) != world; )\r
                        {\r
@@ -1231,22 +1262,42 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto
        }\r
        if(self.killindicator)\r
        {\r
-               if(targetteam)\r
-                       self.killindicator.colormod = TeamColor(targetteam);\r
-               else\r
+               if(targetteam == 0) // just die\r
                        self.killindicator.colormod = '0 0 0';\r
+               else if(targetteam == -1) // auto\r
+                       self.killindicator.colormod = '0 1 0';\r
+               else if(targetteam == -2) // spectate\r
+                       self.killindicator.colormod = '0.5 0.5 0.5';\r
+               else\r
+                       self.killindicator.colormod = TeamColor(targetteam);\r
        }\r
 }\r
 \r
 void ClientKill (void)\r
 {\r
-       ClientKill_TeamChange(0);\r
+       if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either\r
+       {\r
+               // do nothing\r
+       }\r
+       else\r
+               ClientKill_TeamChange(0);\r
+}\r
+\r
+void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed\r
+{\r
+    e.killindicator = spawn();\r
+    e.killindicator.owner = e;\r
+    e.killindicator.think = KillIndicator_Think;\r
+    e.killindicator.nextthink = time + (e.lip) * 0.05;\r
+    e.killindicator.cnt = ceil(cvar("g_cts_finish_kill_delay"));\r
+    e.killindicator.health = 1; // this is used to indicate that it should be silent\r
+    e.lip = 0;\r
 }\r
 \r
 void DoTeamChange(float destteam)\r
 {\r
        float t, c0;\r
-       if(!teams_matter)\r
+       if(!teamplay)\r
        {\r
                if(destteam >= 0)\r
                        SetPlayerColors(self, destteam);\r
index 369005ad5b07cac7d29d1e60ba7cb62224bf2ef3..3d52a01922a2d38419a5703878b45cc47f20a260 100644 (file)
@@ -166,9 +166,8 @@ void SV_ParseClientCommand(string s) {
                }\r
                if(self.version != cvar("gameversion"))\r
                {\r
-                       self.classname = "observer";\r
                        self.version_mismatch = 1;\r
-                       PutClientInServer();\r
+                       ClientKill_TeamChange(-2); // observe\r
                } else if(cvar("g_campaign") || cvar("g_balance_teams") || cvar("g_balance_teams_force")) {\r
                        //JoinBestTeam(self, FALSE, TRUE);\r
                } else if(teams_matter && !cvar("sv_spectate")) {\r
@@ -221,16 +220,7 @@ void SV_ParseClientCommand(string s) {
                        }\r
                }\r
                if(self.classname == "player" && cvar("sv_spectate") == 1) {\r
-                       if(self.flagcarried)\r
-                               DropFlag(self.flagcarried, world, world);\r
-                       kh_Key_DropAll(self, TRUE);\r
-                       WaypointSprite_PlayerDead();\r
-                       self.classname = "observer";\r
-                       if(g_ca)\r
-                               self.caplayer = 0;\r
-                       if(blockSpectators)\r
-                               sprint(self, strcat("^7You have to become a player within the next ", ftos(cvar("g_maxplayers_spectator_blocktime")), " seconds, otherwise you will be kicked, because spectators aren't allowed at this time!\n"));\r
-                       PutClientInServer();\r
+                       ClientKill_TeamChange(-2); // observe\r
                }\r
        } else if(cmd == "join") {\r
                if not(self.flags & FL_CLIENT)\r
@@ -264,15 +254,15 @@ void SV_ParseClientCommand(string s) {
                } else if(lockteams) {\r
                        sprint( self, "^7The game has already begun, you must wait until the next map to be able to join a team.\n");\r
                } else if( argv(1) == "red" ) {\r
-                       DoTeamChange(COLOR_TEAM1);\r
+                       ClientKill_TeamChange(COLOR_TEAM1);\r
                } else if( argv(1) == "blue" ) {\r
-                       DoTeamChange(COLOR_TEAM2);\r
+                       ClientKill_TeamChange(COLOR_TEAM2);\r
                } else if( argv(1) == "yellow" ) {\r
-                       DoTeamChange(COLOR_TEAM3);\r
+                       ClientKill_TeamChange(COLOR_TEAM3);\r
                } else if( argv(1) == "pink" ) {\r
-                       DoTeamChange(COLOR_TEAM4);\r
+                       ClientKill_TeamChange(COLOR_TEAM4);\r
                } else if( argv(1) == "auto" ) {\r
-                       DoTeamChange(-1);\r
+                       ClientKill_TeamChange(-1);\r
                } else {\r
                        sprint( self, strcat( "selectteam none/red/blue/yellow/pink/auto - \"", argv(1), "\" not recognised\n" ) );\r
                }\r
index e48d865903896afad3212979203f9c36c005bd90..0f84c66530f5b14c02d7cd57e1010c3b062d4045 100644 (file)
@@ -485,7 +485,13 @@ void race_SendTime(entity e, float cp, float t, float tvalid)
 \r
                        if(t != 0) {\r
                                if(cp == race_timed_checkpoint)\r
+                               {\r
                                        race_SetTime(e, t, recordtime);\r
+                                       if(g_cts && cvar("g_cts_finish_kill_delay"))\r
+                                       {\r
+                                               CTS_ClientKill(e);\r
+                                       }\r
+                               }\r
 \r
                                if(t < recordtime || recordtime == 0)\r
                                {\r