// ===============
// kick teamkiller
// ===============
-set g_kick_teamkiller_limit 0 "Limit for teamkills before the client gets dropped."
+set g_kick_teamkiller_rate 0 "Limit for teamkills per minute before the client gets dropped."
+set g_kick_teamkiller_mintime 2 "Minimum playtime in minutes that is used for teamkill rate calculation"
-float autocvar_g_kick_teamkiller_limit;
+float autocvar_g_kick_teamkiller_rate;
+float autocvar_g_kick_teamkiller_mintime;
-REGISTER_MUTATOR(kick_teamkiller, (autocvar_g_kick_teamkiller_limit > 0));
+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))
{
}
int teamkills = PlayerScore_Get(attacker, SP_TEAMKILLS);
- if (teamkills >= autocvar_g_kick_teamkiller_limit)
+ // don't use the players actual playtime if they just started playing
+ // to avoid kicking players who only teamkilled by mistake just after joining
+ float playtime_minutes = max((time - attacker.alivetime)/60.0, autocvar_g_kick_teamkiller_mintime);
+ if (teamkills >= autocvar_g_kick_teamkiller_rate*playtime_minutes)
{
Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_QUIT_KICK_TEAMKILL, attacker.netname);
dropclient(attacker);