]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into DefaultUser/kick_teamkiller
authorMario <mario@smbclan.net>
Sat, 25 Nov 2017 06:37:25 +0000 (16:37 +1000)
committerMario <mario@smbclan.net>
Sat, 25 Nov 2017 06:37:25 +0000 (16:37 +1000)
# Conflicts:
# mutators.cfg

17 files changed:
.gitlab-ci.yml
mutators.cfg
qcsrc/client/hud/panel/scoreboard.qc
qcsrc/common/mutators/mutator/_mod.inc
qcsrc/common/mutators/mutator/_mod.qh
qcsrc/common/mutators/mutator/kick_teamkiller/_mod.inc [new file with mode: 0644]
qcsrc/common/mutators/mutator/kick_teamkiller/_mod.qh [new file with mode: 0644]
qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc [new file with mode: 0644]
qcsrc/common/notifications/all.inc
qcsrc/common/scores.qh
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/defs.qh
qcsrc/server/g_damage.qc
qcsrc/server/scores.qc
qcsrc/server/scores.qh
qcsrc/server/scores_rules.qc

index 9305f527cd3abc9640d17bff880e021b854d7b17..9e6a7b6cda7cbe603a22e16bd0631195160c6168 100644 (file)
@@ -29,7 +29,7 @@ test_sv_game:
     - wget -O data/maps/stormkeep.waypoints https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints
     - wget -O data/maps/stormkeep.waypoints.cache https://gitlab.com/xonotic/xonotic-maps.pk3dir/raw/master/maps/stormkeep.waypoints.cache
     - make
-    - EXPECT=ed9be8d1b1a544f89bcdd7d36876fede
+    - EXPECT=3fb0c7a99263dd44e026804c12da2fa2
     - HASH=$(${ENGINE} -noconfig -nohome +exec serverbench.cfg
       | tee /dev/stderr
       | grep '^:'
index e37c190902d4901aa02ee2e5abbd86188c6f4489..79ac41791ade308fde3b9371f47757b23b2656b0 100644 (file)
@@ -480,6 +480,12 @@ set g_dynamic_handicap_exponent 1 "The exponent used to calculate handicap. 1 me
 set g_dynamic_handicap_min 0 "The minimum value of the handicap."
 set g_dynamic_handicap_max 0 "The maximum value of the handicap."
 
+// ===============
+// kick teamkiller
+// ===============
+set g_kick_teamkiller_rate 0 "Limit for teamkills per minute before the client gets dropped. 0 means that the teamkillers don't get kicked automatically"
+set g_kick_teamkiller_lower_limit 5 "Minimum number of teamkills before the teamkill rate is considered"
+
 // =====================
 //  stale-move negation
 // =====================
index 8e0d0f057695d8e237fbcbe2816b11298c6fce89..063cb887f92d51a734ff4d3d740ce09fca7bece6 100644 (file)
@@ -96,6 +96,7 @@ string TranslateScoresLabel(string l)
                case "kd": return CTX(_("SCO^k/d"));
                case "kdr": return CTX(_("SCO^kdr"));
                case "kills": return CTX(_("SCO^kills"));
+               case "teamkills": return CTX(_("SCO^teamkills"));
                case "laps": return CTX(_("SCO^laps"));
                case "lives": return CTX(_("SCO^lives"));
                case "losses": return CTX(_("SCO^losses"));
@@ -312,6 +313,7 @@ void Cmd_Scoreboard_Help()
        LOG_INFO(_("^3deaths^7                   Number of deaths"));
        LOG_INFO(_("^3suicides^7                 Number of suicides"));
        LOG_INFO(_("^3frags^7                    kills - suicides"));
+       LOG_INFO(_("^3teamkills^7                Number of teamkills"));
        LOG_INFO(_("^3kd^7                       The kill-death ratio"));
        LOG_INFO(_("^3dmg^7                      The total damage done"));
        LOG_INFO(_("^3dmgtaken^7                 The total damage taken"));
@@ -361,6 +363,7 @@ void Cmd_Scoreboard_Help()
 " -teams,rc,cts,inv,lms/kills +ft,tdm/kills ?+rc,inv/kills" \
 " -teams,lms/deaths +ft,tdm/deaths" \
 " -teams,lms,rc,cts,inv,ka/suicides +ft,tdm/suicides ?+rc,inv/suicides" \
+" +teams/teamkills"\
 " -cts,dm,tdm,ka,ft/frags" /* tdm already has this in "score" */ \
 " -rc,cts,nb/dmg -rc,cts,nb/dmgtaken" \
 " +ctf/caps +ctf/pickups +ctf/fckills +ctf/returns +ons/caps +ons/takes" \
index d1a6acfc91c0988929456b8eecbf7abc1354f70f..9d52fa20c44af25537d2b11bf68b04b2020cac0c 100644 (file)
@@ -15,6 +15,7 @@
 #include <common/mutators/mutator/instagib/_mod.inc>
 #include <common/mutators/mutator/invincibleproj/_mod.inc>
 #include <common/mutators/mutator/itemstime/_mod.inc>
+#include <common/mutators/mutator/kick_teamkiller/_mod.inc>
 #include <common/mutators/mutator/melee_only/_mod.inc>
 #include <common/mutators/mutator/midair/_mod.inc>
 #include <common/mutators/mutator/multijump/_mod.inc>
index a865d1922d9b0844ec65a711006f1cc3bf6ae679..f9edf4c56c47868e01161b34793a5c05e33f64d9 100644 (file)
@@ -15,6 +15,7 @@
 #include <common/mutators/mutator/instagib/_mod.qh>
 #include <common/mutators/mutator/invincibleproj/_mod.qh>
 #include <common/mutators/mutator/itemstime/_mod.qh>
+#include <common/mutators/mutator/kick_teamkiller/_mod.qh>
 #include <common/mutators/mutator/melee_only/_mod.qh>
 #include <common/mutators/mutator/midair/_mod.qh>
 #include <common/mutators/mutator/multijump/_mod.qh>
diff --git a/qcsrc/common/mutators/mutator/kick_teamkiller/_mod.inc b/qcsrc/common/mutators/mutator/kick_teamkiller/_mod.inc
new file mode 100644 (file)
index 0000000..a374a0e
--- /dev/null
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc>
+#endif
diff --git a/qcsrc/common/mutators/mutator/kick_teamkiller/_mod.qh b/qcsrc/common/mutators/mutator/kick_teamkiller/_mod.qh
new file mode 100644 (file)
index 0000000..98fb481
--- /dev/null
@@ -0,0 +1 @@
+// generated file; do not modify
diff --git a/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc b/qcsrc/common/mutators/mutator/kick_teamkiller/sv_kick_teamkiller.qc
new file mode 100644 (file)
index 0000000..a3b028f
--- /dev/null
@@ -0,0 +1,33 @@
+
+float autocvar_g_kick_teamkiller_rate;
+float autocvar_g_kick_teamkiller_lower_limit;
+
+REGISTER_MUTATOR(kick_teamkiller, (autocvar_g_kick_teamkiller_rate > 0));
+
+MUTATOR_HOOKFUNCTION(kick_teamkiller, PlayerDies)
+{
+       if (!teamplay)
+       {
+               return;
+       }
+       if (warmup_stage)
+       {
+               return;
+       }
+       entity attacker = M_ARGV(1, entity);
+       if (!IS_REAL_CLIENT(attacker))
+       {
+               return;
+       }
+
+       int teamkills = PlayerScore_Get(attacker, SP_TEAMKILLS);
+       // use the players actual playtime
+       float playtime = time - CS(attacker).startplaytime;
+       // rate is in teamkills/minutes, playtime in seconds
+       if (teamkills >= autocvar_g_kick_teamkiller_lower_limit && 
+           teamkills >= autocvar_g_kick_teamkiller_rate*playtime/60.0)
+       {
+               Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_TEAMKILL, attacker.netname);
+               dropclient(attacker);
+       }
+}
index 3b5492ac2d0adab12235d3512c13177e179b412b..b4c6146bb6662535e983df75a4e73962e6289636 100644 (file)
     MSG_INFO_NOTIF(QUIT_DISCONNECT,                         N_CHATCON,  1, 0, "s1", "",         "",             _("^BG%s^F3 disconnected"), "")
     MSG_INFO_NOTIF(QUIT_KICK_IDLING,                        N_CHATCON,  1, 0, "s1", "",         "",             _("^BG%s^F3 was kicked for idling"), "")
     MSG_INFO_NOTIF(QUIT_KICK_SPECTATING,                    N_CONSOLE,  0, 0, "", "",           "",             _("^F2You were kicked from the server because you are a spectator and spectators aren't allowed at the moment."), "")
+    MSG_INFO_NOTIF(QUIT_KICK_TEAMKILL,                      N_CHATCON,  1, 0, "s1", "",         "",             _("^BG%s^F3 was kicked for excessive teamkilling"), "")
     MSG_INFO_NOTIF(QUIT_SPECTATE,                           N_CONSOLE,  1, 0, "s1", "",         "",             _("^BG%s^F3 is now spectating"), "")
 
     MSG_INFO_NOTIF(RACE_ABANDONED,                          N_CONSOLE,  1, 0, "s1", "",                                                                     "",                         _("^BG%s^BG has abandoned the race"), "")
index 646638a80ca704778f8628513a6225021c154566..476d0dbbaa612445241bd1450c48642a7f78f347 100644 (file)
@@ -34,6 +34,7 @@ REGISTER_SP(DMGTAKEN);
 REGISTER_SP(KILLS);
 REGISTER_SP(DEATHS);
 REGISTER_SP(SUICIDES);
+REGISTER_SP(TEAMKILLS);
 REGISTER_SP(FRAGS);
 
 REGISTER_SP(ELO);
index d7b9a7ae0e7d6305ef86a5994b2b3e09f2edef80..d2fae8b50b1f60350d5d37f88b2de72bdada324e 100644 (file)
@@ -654,9 +654,11 @@ void PutPlayerInServer(entity this)
 
        PHYS_INPUT_BUTTON_ATCK(this) = PHYS_INPUT_BUTTON_JUMP(this) = PHYS_INPUT_BUTTON_ATCK2(this) = false;
 
+       // player was spectator
        if (CS(this).killcount == FRAGS_SPECTATOR) {
                PlayerScore_Clear(this);
                CS(this).killcount = 0;
+               CS(this).startplaytime = time;
        }
 
        for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
index af81535a7a231bbd66f34bc0612d40caaf567999..42d7d9560b4e92359242e19428f242d146cbff0a 100644 (file)
@@ -85,6 +85,7 @@ CLASS(Client, Object)
     ATTRIB(Client, motd_actived_time, float, this.motd_actived_time);
     ATTRIB(Client, jointime, float, this.jointime);
     ATTRIB(Client, spectatortime, float, this.spectatortime);
+    ATTRIB(Client, startplaytime, float, this.startplaytime);
     ATTRIB(Client, version_nagtime, float, this.version_nagtime);
     ATTRIB(Client, netname_previous, string, this.netname_previous);
     ATTRIB(Client, allowed_timeouts, int, this.allowed_timeouts);
index 0566d576767bdaf8e3d6f1012e7090c0e69d2aa2..7ddea9f5ea8f4bd52b60dbf3997003d0e3fc2b44 100644 (file)
@@ -138,7 +138,8 @@ void checkSpectatorBlock(entity this);
 
 float game_completion_ratio; // 0 at start, 1 near end
 .float winning;
-.float jointime; // time of joining
+.float jointime; // time of connecting
+.float startplaytime; // time of switching from spectator to player
 .float alivetime; // time of being alive
 .float motd_actived_time; // used for both motd and campaign_message
 
index afe018c08bc0198c2240c99e44f7dea7e75295fd..c0ff6b3f4ebd6c1a833f45c3b2f880ff06f1f442 100644 (file)
@@ -47,7 +47,7 @@ void GiveFrags (entity attacker, entity targ, float f, int deathtype)
                else
                {
                        // teamkill
-                       GameRules_scoring_add(attacker, KILLS, -1); // or maybe add a teamkills field?
+                       GameRules_scoring_add(attacker, TEAMKILLS, 1);
                }
        }
        else
index 32fe3c6aaa2dd178f3af6cff5d89606688e3209f..c9948660efe1165c7ed8654dac1ba770e6763277 100644 (file)
@@ -96,7 +96,7 @@ void TeamScore_Spawn(float t, string name)
        PlayerStats_GameReport_AddTeam(t);
 }
 
-float TeamScore_AddToTeam(float t, float scorefield, float score)
+float TeamScore_AddToTeam(int t, float scorefield, float score)
 {
        entity s;
 
index 79b65299f41e1bfa2c01d5a09e528011d5a560cd..e2a57f43fb4a3ffaf36b6a5d33f1d475d793e9db 100644 (file)
@@ -52,7 +52,7 @@ float TeamScore_Add(entity player, float scorefield, float score);
  * NEVER call this if team has not been set yet!
  * Returns the new score.
  */
-float TeamScore_AddToTeam(float t, float scorefield, float score);
+float TeamScore_AddToTeam(int t, float scorefield, float score);
 
 /**
  * Returns a value indicating the team score (and higher is better).
index d46d95bd1c6114ee5138527c74cb726afc8a7dab..8d87407e64ebd3bc165efe3e27b53c6ceef25f0b 100644 (file)
@@ -44,7 +44,10 @@ void ScoreRules_basics(int teams, float sprio, float stprio, float score_enabled
        ScoreInfo_SetLabel_PlayerScore(SP_DEATHS,       "deaths",    SFL_LOWER_IS_BETTER);
 
        if (!INDEPENDENT_PLAYERS)
+       {
                ScoreInfo_SetLabel_PlayerScore(SP_SUICIDES,     "suicides",  SFL_LOWER_IS_BETTER);
+               ScoreInfo_SetLabel_PlayerScore(SP_TEAMKILLS,     "teamkills", SFL_LOWER_IS_BETTER);
+       }
 
        if(score_enabled)
                ScoreInfo_SetLabel_PlayerScore(SP_SCORE,        "score",     sprio);