diff -Nru trem901-original-wraths/src/game/bg_public.h trem901-original-wraths-tmp2/src/game/bg_public.h
--- trem901-original-wraths/src/game/bg_public.h	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/bg_public.h	2007-08-18 07:35:29.000000000 +0200
@@ -882,7 +882,9 @@
 
   MOD_ASPAWN,
   MOD_ATUBE,
-  MOD_OVERMIND
+  MOD_OVERMIND,
+  
+  MOD_SLAP
 } meansOfDeath_t;
 
 
diff -Nru trem901-original-wraths/src/game/g_active.c trem901-original-wraths-tmp2/src/game/g_active.c
--- trem901-original-wraths/src/game/g_active.c	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_active.c	2007-08-18 07:35:50.000000000 +0200
@@ -194,12 +194,28 @@
 static void G_ClientShove( gentity_t *ent, gentity_t *victim )
 {
   vec3_t  dir, push;
-  int entMass = 200, vicMass = 200;
+  int entMass = 200, vicMass = 200 , shove;
 
   // shoving enemies changes gameplay too much
   if( !OnSameTeam( ent, victim ) )
     return;
 
+  if ( g_shove.value < 0 )
+  {
+    if ( ( victim->client->ps.weapon >= WP_ABUILD ) &&
+         ( victim->client->ps.weapon <= WP_HBUILD ) &&
+         ( victim->client->ps.stats[ STAT_BUILDABLE ] != BA_NONE ) )
+      return;
+    else
+      shove = - g_shove.value;
+  }
+  else if ( g_shove.value > 0 )
+  {
+    shove = g_shove.value;
+  }
+  else
+    return;
+
   // alien mass is directly related to their health points
   // human mass is 200, double for bsuit  
   if( ent->client->pers.teamSelection == PTE_ALIENS )
@@ -235,7 +251,7 @@
     return;
 
   VectorScale( dir,
-    ( g_shove.value * ( ( float )entMass / ( float )vicMass ) ), push );
+    ( shove * ( ( float )entMass / ( float )vicMass ) ), push );
   VectorAdd( victim->client->ps.velocity, push,
                 victim->client->ps.velocity );
 
diff -Nru trem901-original-wraths/src/game/g_admin.c trem901-original-wraths-tmp2/src/game/g_admin.c
--- trem901-original-wraths/src/game/g_admin.c	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_admin.c	2007-08-18 08:01:51.000000000 +0200
@@ -82,7 +82,7 @@
     
     {"listadmins", G_admin_listadmins, "D",
       "display a list of all server admins and their levels",
-      "(^5name|start admin#^7)"
+      "(^5name|start admin#^7) (^5minimum level to display^7)"
     },
     
     {"listlayouts", G_admin_listlayouts, "L",
@@ -134,6 +134,11 @@
       "reloads the admin config file and refreshes permission flags",
       ""
     },
+    
+    {"register", G_admin_register, "R",
+      "Registers your name to protect it from being used by others or updates your admin name to your current name.",
+      ""
+    },
 
     {"rename", G_admin_rename, "N",
       "rename a player",
@@ -159,6 +164,11 @@
       "move 999 pingers to the spectator team",
       ""},
 
+    {"slap", G_admin_slap, "x",
+      "abuses your authoritay!",
+      "[^3name|slot^7] (damage)"
+    },
+
     {"time", G_admin_time, "C",
       "show the current local server time",
       ""},
@@ -176,6 +186,12 @@
     {"unmute", G_admin_mute, "m",
       "unmute a muted player",
       "[^3name|slot#^7]"
+    },
+
+    {
+     "warn", G_admin_warn, "w",
+      "Warn a player to cease or face admin intervention",
+      "[^3name|slot#^7] [reason]"
     }
   };
 
@@ -587,15 +603,15 @@
 
   Q_strncpyz( g_admin_levels[ 2 ]->name, "^6Team Manager",
     sizeof( l->name ) );
-  Q_strncpyz( g_admin_levels[ 2 ]->flags, "iahCpP", sizeof( l->flags ) );
+  Q_strncpyz( g_admin_levels[ 2 ]->flags, "iahCpPw", sizeof( l->flags ) );
 
   Q_strncpyz( g_admin_levels[ 3 ]->name, "^2Junior Admin",
     sizeof( l->name ) );
-  Q_strncpyz( g_admin_levels[ 3 ]->flags, "iahCpPkm", sizeof( l->flags ) );
+  Q_strncpyz( g_admin_levels[ 3 ]->flags, "iahCpPkmw", sizeof( l->flags ) );
 
   Q_strncpyz( g_admin_levels[ 4 ]->name, "^3Senior Admin",
     sizeof( l->name ) );
-  Q_strncpyz( g_admin_levels[ 4 ]->flags, "iahCpPkmBbe", sizeof( l->flags ) );
+  Q_strncpyz( g_admin_levels[ 4 ]->flags, "iahCpPkmBbew", sizeof( l->flags ) );
 
   Q_strncpyz( g_admin_levels[ 5 ]->name, "^1Server Operator",
     sizeof( l->name ) );
@@ -754,7 +770,7 @@
   trap_FS_FCloseFile( f );
 }
 
-static int admin_listadmins( gentity_t *ent, int start, char *search )
+static int admin_listadmins( gentity_t *ent, int start, char *search, int minlevel )
 {
   int drawn = 0;
   char guid_stub[9];
@@ -813,59 +829,60 @@
 
   for( i = start; i < MAX_ADMIN_ADMINS && g_admin_admins[ i ]
     && drawn < MAX_ADMIN_LISTITEMS; i++ )
-  {
-    if( search[ 0 ] )
-    {
-      G_SanitiseName( g_admin_admins[ i ]->name, name );
-      if( !strstr( name, search ) )
-        continue;
+   if( g_admin_admins[ i ]->level >= minlevel ) 
+   {
+     if( search[ 0 ] )
+     {
+       G_SanitiseName( g_admin_admins[ i ]->name, name );
+       if( !strstr( name, search ) )
+         continue;
       
-      // verify we don't have the same guid/name pair in connected players
-      // since we don't want to draw the same player twice
-      dup = qfalse;
-      for( j = 0; j < level.maxclients; j++ )
-      {
-        vic = &g_entities[ j ];
-        if( !vic->client || vic->client->pers.connected != CON_CONNECTED )
-          continue;
-        G_SanitiseName( vic->client->pers.netname, name2 );
-        if( !Q_stricmp( vic->client->pers.guid, g_admin_admins[ i ]->guid )
-          && strstr( name2, search ) ) 
-        {
-          dup = qtrue;
-          break;
-        }
-      }
-      if( dup )
-        continue;
-    }
-    for( j = 0; j <= 8; j++ )
-      guid_stub[ j ] = g_admin_admins[ i ]->guid[ j + 24 ];
-    guid_stub[ j ] = '\0';
-   
-    lname[ 0 ] = '\0'; 
-    Q_strncpyz( lname_fmt, "%s", sizeof( lname_fmt ) );
-    for( j = 0; j < MAX_ADMIN_LEVELS && g_admin_levels[ j ]; j++ )
-    {
-      if( g_admin_levels[ j ]->level == g_admin_admins[ i ]->level )
-      {
-        G_DecolorString( g_admin_levels[ j ]->name, lname );
-        Com_sprintf( lname_fmt, sizeof( lname_fmt ), "%%%is",
-          ( admin_level_maxname + strlen( g_admin_levels[ j ]->name )
-            - strlen( lname ) ) );
-        Com_sprintf( lname, sizeof( lname ), lname_fmt,
-           g_admin_levels[ j ]->name );
-        break;
-      }
-    }
-    ADMBP( va( "%4i %4i %s^7 (*%s) %s^7\n",
-      ( i + MAX_CLIENTS ),
-      g_admin_admins[ i ]->level,
-      lname,
-      guid_stub,
-      g_admin_admins[ i ]->name ) );
-    drawn++;
-  }
+       // verify we don't have the same guid/name pair in connected players
+       // since we don't want to draw the same player twice
+       dup = qfalse;
+       for( j = 0; j < level.maxclients; j++ )
+       {
+         vic = &g_entities[ j ];
+         if( !vic->client || vic->client->pers.connected != CON_CONNECTED )
+           continue;
+         G_SanitiseName( vic->client->pers.netname, name2 );
+         if( !Q_stricmp( vic->client->pers.guid, g_admin_admins[ i ]->guid )
+           && strstr( name2, search ) ) 
+         {
+           dup = qtrue;
+           break;
+         }
+       }
+       if( dup )
+         continue;
+     }
+     for( j = 0; j <= 8; j++ )
+       guid_stub[ j ] = g_admin_admins[ i ]->guid[ j + 24 ];
+     guid_stub[ j ] = '\0';
+    
+     lname[ 0 ] = '\0'; 
+     Q_strncpyz( lname_fmt, "%s", sizeof( lname_fmt ) );
+     for( j = 0; j < MAX_ADMIN_LEVELS && g_admin_levels[ j ]; j++ )
+     {
+       if( g_admin_levels[ j ]->level == g_admin_admins[ i ]->level )
+       {
+         G_DecolorString( g_admin_levels[ j ]->name, lname );
+         Com_sprintf( lname_fmt, sizeof( lname_fmt ), "%%%is",
+           ( admin_level_maxname + strlen( g_admin_levels[ j ]->name )
+             - strlen( lname ) ) );
+         Com_sprintf( lname, sizeof( lname ), lname_fmt,
+            g_admin_levels[ j ]->name );
+         break;
+       }
+     }
+     ADMBP( va( "%4i %4i %s^7 (*%s) %s^7\n",
+       ( i + MAX_CLIENTS ),
+       g_admin_admins[ i ]->level,
+       lname,
+       guid_stub,
+       g_admin_admins[ i ]->name ) );
+     drawn++;
+   }
   ADMBP_end();
   return drawn;
 }
@@ -1491,7 +1508,7 @@
   {
     ADMP( "^3!setlevel:^7 more than one match.  Use the admin number "
       "instead:\n" );
-    admin_listadmins( ent, 0, name );
+    admin_listadmins( ent, 0, name, 0 );
     return qfalse;
   }
 
@@ -2098,22 +2115,40 @@
   int start = 0;
   qboolean numeric = qtrue;
   int drawn = 0;
+  int minlevel = 1;
 
   t = trap_RealTime( &qt );
+  
+  if( G_SayArgc() == 3 + skiparg )
+  {
+    G_SayArgv( 2 + skiparg, s, sizeof( s ) );
+    if( s[ 0 ] >= '0' && s[ 0] <= '9' )
+    {
+      minlevel = atoi( s );
+      if( minlevel < 1 ) 
+       minlevel = 1;
+    }
+  }
 
   for( i = 0; i < MAX_ADMIN_ADMINS && g_admin_admins[ i ]; i++ )
   {
-    if( g_admin_admins[ i ]->level == 0 )
-      continue;
-    found++;
+    if( g_admin_admins[ i ]->level >= minlevel )
+      found++;
   }
   if( !found )
   {
-    ADMP( "^3!listadmins: ^7no admins defined\n" );
+    if( minlevel > 1 )
+    {
+      ADMP( va( "^3!listadmins: ^7no admins level %i or greater found\n", minlevel ) );
+    }
+    else
+    {
+       ADMP( "^3!listadmins: ^7no admins defined\n" );
+    }
     return qfalse;
   }
 
-  if( G_SayArgc() == 2 + skiparg )
+  if( G_SayArgc() >= 2 + skiparg )
   {
     G_SayArgv( 1 + skiparg, s, sizeof( s ) );
     for( i = 0; i < sizeof( s ) && s[ i ]; i++ )
@@ -2137,31 +2172,42 @@
   if( start >= found || start < 0 )
     start = 0;
 
-  if( start >= found )
-  {
-    ADMP( va( "^3!listadmins: ^7listing %d admins\n", found ) );
-    return qfalse;
-  }
-
-  drawn = admin_listadmins( ent, start, search );
+  drawn = admin_listadmins( ent, start, search, minlevel );
 
   if( search[ 0 ] )
   {
-    ADMP( va( "^3!listadmins:^7 found %d admins matching '%s^7'\n",
-      drawn, search ) );
+    if( drawn <= 20 )
+    {
+      ADMP( va( "^3!listadmins:^7 found %d admins level %i or greater matching '%s^7'\n",
+        drawn, minlevel, search ) );
+    }
+    else
+    {
+      ADMP( va( "^3!listadmins:^7 found >20 admins level %i or greater matching '%s^7. Try a more narrow search.'\n",
+        minlevel, search ) );
+    }
   }
   else
   {
     ADMBP_begin();
-    ADMBP( va( "^3!listadmins:^7 showing admin %d - %d of %d.  ",
+    ADMBP( va( "^3!listadmins:^7 showing admins level %i or greater %d - %d of %d.  ",
+      minlevel,
       ( found ) ? ( start + 1 ) : 0,
       ( ( start + MAX_ADMIN_LISTITEMS ) > found ) ?
        found : ( start + MAX_ADMIN_LISTITEMS ),
       found ) );
     if( ( start + MAX_ADMIN_LISTITEMS ) < found )
     {
-      ADMBP( va( "run '!listadmins %d' to see more",
-        ( start + MAX_ADMIN_LISTITEMS + 1 ) ) );
+      if( minlevel > 1)
+      {
+        ADMBP( va( "run '!listadmins %d %d' to see more",
+          ( start + MAX_ADMIN_LISTITEMS + 1 ), minlevel ) );
+      }
+      else
+      {
+        ADMBP( va( "run '!listadmins %d' to see more",
+          ( start + MAX_ADMIN_LISTITEMS + 1 ) ) );
+      }
     }
     ADMBP( "\n" );
     ADMBP_end();
@@ -2310,21 +2356,34 @@
 
     }
 
-    ADMBP( va( "%2i %s%s^7 %-2i %s^7 (*%s) ^1%1s%1s^7 %s^7 %s%s^7%s\n",
-             i,
-             c,
-             t,
-             l,
-             ( *lname ) ? lname2 : "", 
-             guid_stub,
-             muted,
-             denybuild,
-             p->pers.netname,
-             ( *n ) ? "(a.k.a. " : "",
-             n,
-             ( *n ) ? ")" : ""
-           ) );
-  }
+    if( G_admin_permission(ent, ADMF_SEESFULLLISTPLAYERS ) ) {	
+        ADMBP( va( "%2i %s%s^7 %-2i %s^7 (*%s) ^1%1s%1s^7 %s^7 %s%s^7%s\n",
+              i,
+              c,
+              t,
+              l,
+              ( *lname ) ? lname2 : "", 
+              guid_stub,
+              muted,
+              denybuild,
+              p->pers.netname,
+              ( *n ) ? "(a.k.a. " : "",
+              n,
+              ( *n ) ? ")" : ""
+            ) );
+    }
+    else
+    {
+        ADMBP( va( "%2i %s%s^7 ^1%1s%1s^7 %s^7\n",
+              i,
+              c,
+              t,
+              muted,
+              denybuild,
+              p->pers.netname
+            ) );
+    }
+   }
   ADMBP_end();
   return qtrue;
 }
@@ -2690,6 +2749,140 @@
   return qtrue;
 }
 
+qboolean G_admin_register(gentity_t *ent, int skiparg ){
+  int level = 0;
+
+  level = G_admin_level(ent);
+	
+  if( level == 0 )
+   level = 1;
+  
+  if( !Q_stricmp( ent->client->pers.guid, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" ) )
+  {
+    ADMP( va( "^3!register: ^7 You cannot register for name protection until you update your client. Please replace your client executable with the one at http://trem.tjw.org/backport/ and reconnect. Updating your client will also allow you to have faster map downloads.\n" ) );
+    return qfalse;
+  }
+
+  trap_SendConsoleCommand( EXEC_APPEND,va( "!setlevel %d %d;",ent - g_entities, level) );
+  ClientUserinfoChanged( ent - g_entities );
+  
+  AP( va( "print \"^3!register: ^7%s^7 is now a protected nickname.\n\"", ent->client->pers.netname) );
+  
+  return qtrue;
+}
+
+qboolean G_admin_slap( gentity_t *ent, int skiparg )
+{
+  int pids[ MAX_CLIENTS ], damage = 0;
+  char name[MAX_NAME_LENGTH], err[MAX_STRING_CHARS], command[MAX_ADMIN_CMD_LEN], *cmd;
+  gentity_t *vic;
+  vec3_t dir;
+ 
+  if( level.intermissiontime ) return qfalse;
+
+  if( G_SayArgc() < 2 + skiparg )
+  {
+    ADMP( "^3!slap: ^7usage: slap [name|slot#]\n" );
+    return qfalse;
+  }
+  G_SayArgv( skiparg, command, sizeof( command ) );
+  cmd = command;
+  if( cmd && *cmd == '!' )
+    cmd++;
+  G_SayArgv( 1 + skiparg, name, sizeof( name ) );
+  
+  if ( !Q_stricmp( name, "target_in_aim" ) )
+  {
+	vec3_t      forward, end;
+    trace_t     tr;
+
+    // trace a teammate
+    AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
+    VectorMA( ent->client->ps.origin, 8192 * 16, forward, end );
+
+    trap_Trace( &tr, ent->client->ps.origin, NULL, NULL, end, ent->s.number, MASK_PLAYERSOLID );
+    vic = &g_entities[ tr.entityNum ];
+
+    if( tr.fraction >= 1.0f || !vic->client )
+    {
+      trap_SendServerCommand( ent-g_entities,
+        va( "print \"!slap: aim at a victem to slap.\n\"") );
+      return qfalse;
+    }
+  }
+  else if( G_ClientNumbersFromString( name, pids ) != 1 )
+  {
+    G_MatchOnePlayer( pids, err, sizeof( err ) );
+    ADMP( va( "^3!slap: ^7%s\n", err ) );
+    return qfalse;
+  }
+  else
+  {
+	vic = &g_entities[ pids[ 0 ] ];
+  }
+  if( !admin_higher( ent, vic ) )
+  {
+    ADMP( "^3!slap: ^7sorry, but your intended victim has a higher admin"
+        " level than you\n" );
+    return qfalse;
+  }
+
+  // cant slap spectators
+  if( vic->client->pers.teamSelection == PTE_NONE ||
+      vic->client->pers.classSelection == PCL_NONE ) {
+    ADMP( "^3!slap: ^7can't slap thin air\n" );
+    return qfalse;
+  }
+
+  // cant slap console?
+  if( !vic ) {
+    ADMP( "^3!slap: ^7bad target\n" );
+    return qfalse;
+  }
+
+  // knockback in a random direction
+  dir[0] = crandom();
+  dir[1] = crandom();
+  dir[2] = random();
+  G_Knockback( vic, dir, g_slapKnockback.integer );
+
+  // play a sound
+  //G_AddEvent( vic, EV_SLAP, 0 );
+
+  if( vic != ent )
+    trap_SendServerCommand( vic-g_entities,
+      va( "cp \"%s^7 is ^1not amused!\n\"",
+      ent ? ent->client->pers.netname : "Console" ) );
+
+  if( g_slapDamage.integer > 0 ) {
+
+    // !slap (name) [damage] syntax
+    if( G_SayArgc() > 2 + skiparg ) {
+      char dmg_str[ MAX_STRING_CHARS ];
+      G_SayArgv( 2 + skiparg, dmg_str, sizeof( dmg_str ) );
+      damage = atoi(dmg_str);
+      if( damage < 0 ) damage = 0;
+    } else {
+      if( g_slapDamage.integer > 100 ) g_slapDamage.integer = 100;
+      damage = BG_FindHealthForClass( vic->client->ps.stats[ STAT_PCLASS ] ) *
+        g_slapDamage.integer / 100;
+      if( damage < 1 ) damage = 1;
+    }
+
+    vic->health -= damage;
+    vic->client->ps.stats[ STAT_HEALTH ] = vic->health;
+    vic->lastDamageTime = level.time;
+    if( vic->health <= 0 )
+    {
+      vic->flags |= FL_NO_KNOCKBACK;
+      vic->enemy = &g_entities[ pids[ 0 ] ];
+      vic->die( vic, ent, ent, damage, MOD_SLAP );
+    } else if( vic->pain ) vic->pain( vic, &g_entities[ pids[ 0 ] ], damage );
+  }
+
+  return qtrue;
+}
+
 qboolean G_admin_rename( gentity_t *ent, int skiparg )
 {
   int pids[ MAX_CLIENTS ];
@@ -2936,6 +3129,49 @@
     ( ent ) ? ent->client->pers.netname : "console" ) );
   return qtrue;
 } 
+//!Warn by Gate (Daniel Evans) 
+qboolean G_admin_warn( gentity_t *ent, int skiparg )
+{//mostly copy and paste with the proper lines altered from !mute and !kick
+
+
+  int pids[ MAX_CLIENTS ];
+  char name[ MAX_NAME_LENGTH ], *reason, err[ MAX_STRING_CHARS ];
+  int minargc;
+  gentity_t *vic;
+
+  minargc = 3 + skiparg;
+  if( G_admin_permission( ent, ADMF_UNACCOUNTABLE ) )
+    minargc = 2 + skiparg;
+
+  if( G_SayArgc() < minargc )
+  {
+    ADMP( "^3!warn: ^7usage: warn [name] [reason]\n" );
+    return qfalse;
+  }
+  G_SayArgv( 1 + skiparg, name, sizeof( name ) );
+  reason = G_SayConcatArgs( 2 + skiparg );
+  if( G_ClientNumbersFromString( name, pids ) != 1 )
+  {
+    G_MatchOnePlayer( pids, err, sizeof( err ) );
+    ADMP( va( "^3!warn: ^7%s\n", err ) );
+    return qfalse;
+  }
+  if( !admin_higher( ent, &g_entities[ pids[ 0 ] ] ) )
+  {
+    ADMP( "^3!warn: ^7sorry, but your intended victim has a higher admin"
+        " level than you.\n" );
+    return qfalse;
+  }
+ 
+  vic = &g_entities[ pids[ 0 ] ];
+  //next line is the onscreen warning
+  CPx( pids[ 0 ],va("cp \"^1You have been warned by an administrator.\n ^3Cease imeediately or face admin action!\n^1 %s%s\"",(*reason)? "REASON: " : "" ,(*reason)? reason : "") );
+  AP( va( "print \"^3!warn: ^7%s^7 has been warned to cease and desist %s by %s \n\"",
+            vic->client->pers.netname, (*reason) ? reason : "his current activity",
+            ( ent ) ? ent->client->pers.netname : "console" ) );//console announcement
+  ClientUserinfoChanged( pids[ 0 ] );
+  return qtrue;
+}
 
 /*
 ================
diff -Nru trem901-original-wraths/src/game/g_admin.h trem901-original-wraths-tmp2/src/game/g_admin.h
--- trem901-original-wraths/src/game/g_admin.h	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_admin.h	2007-08-18 08:01:51.000000000 +0200
@@ -69,6 +69,7 @@
 
 #define ADMF_IMMUTABLE '!'
 #define ADMF_INCOGNITO '@'
+#define ADMF_SEESFULLLISTPLAYERS '$'
 
 #define ADMF_VIP '#'
 
@@ -162,13 +163,17 @@
 qboolean G_admin_allready( gentity_t *ent, int skiparg );
 qboolean G_admin_cancelvote( gentity_t *ent, int skiparg );
 qboolean G_admin_passvote( gentity_t *ent, int skiparg );
+qboolean G_admin_slap( gentity_t *ent, int skiparg );
 qboolean G_admin_spec999( gentity_t *ent, int skiparg );
+qboolean G_admin_register( gentity_t *ent, int skiparg );
 qboolean G_admin_rename( gentity_t *ent, int skiparg );
 qboolean G_admin_restart( gentity_t *ent, int skiparg );
 qboolean G_admin_nextmap( gentity_t *ent, int skiparg );
 qboolean G_admin_namelog( gentity_t *ent, int skiparg );
 qboolean G_admin_lock( gentity_t *ent, int skiparg );
 qboolean G_admin_unlock( gentity_t *ent, int skiparg );
+ 
+qboolean G_admin_warn( gentity_t *ent, int skiparg );
 
 void G_admin_print( gentity_t *ent, char *m );
 void G_admin_buffer_print( gentity_t *ent, char *m );
diff -Nru trem901-original-wraths/src/game/g_combat.c trem901-original-wraths-tmp2/src/game/g_combat.c
--- trem901-original-wraths/src/game/g_combat.c	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_combat.c	2007-08-18 07:35:29.000000000 +0200
@@ -117,7 +117,9 @@
 
   "MOD_ASPAWN",
   "MOD_ATUBE",
-  "MOD_OVERMIND"
+  "MOD_OVERMIND",
+  
+  "MOD_SLAP"
 };
 
 /*
@@ -191,7 +193,21 @@
     BG_DeactivateUpgrade( i, self->client->ps.stats );
 
   // broadcast the death event to everyone
-  if( !tk )
+  if( meansOfDeath == MOD_SLAP )
+  {
+    if( self == attacker || !attacker )
+      trap_SendServerCommand( -1, va( "print \"%s^7 slapped himself silly\n\"",
+        self->client->pers.netname ) );
+    else
+      trap_SendServerCommand( -1,
+        va( "print \"%s^7 felt %s^7's authoritay\n\"",
+        self->client->pers.netname, killerName ) );
+ 
+    // do not send obituary or credit any kills by slapping, skip straight to
+    // setting the animations etc
+    goto finish_dying;
+  }
+  else if( !tk )
   {
     ent = G_TempEntity( self->r.currentOrigin, EV_OBITUARY );
     ent->s.eventParm = meansOfDeath;
@@ -376,6 +392,8 @@
       Cmd_Score_f( g_entities + i );
   }
 
+finish_dying:
+
   self->client->pers.classSelection = PCL_NONE; //TA: reset the classtype
   VectorCopy( self->s.origin, self->client->pers.lastDeathLocation );
 
@@ -893,6 +911,54 @@
 
 /*
 ============
++G_Knockback
++
++Apply knockback or kickback to an entity.
++============
++*/
+void G_Knockback( gentity_t *targ, vec3_t dir, int knockback )
+{
+  if( knockback && targ->client )
+  {
+    vec3_t  kvel;
+    float   mass;
+
+    mass = 200;
+
+    // Halve knockback for bsuits
+    if( targ->client &&
+        targ->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS &&
+        BG_InventoryContainsUpgrade( UP_BATTLESUIT, targ->client->ps.stats ) )
+      mass += 400;
+
+    // Halve knockback for crouching players
+    if(targ->client->ps.pm_flags&PMF_DUCKED) knockback /= 2;
+
+    VectorScale( dir, g_knockback.value * (float)knockback / mass, kvel );
+    VectorAdd( targ->client->ps.velocity, kvel, targ->client->ps.velocity );
+
+    // set the timer so that the other client can't cancel
+    // out the movement immediately
+    if( !targ->client->ps.pm_time )
+    {
+      int   t;
+
+      t = knockback * 2;
+      if( t < 50 )
+        t = 50;
+
+      if( t > 200 )
+        t = 200;
+
+      targ->client->ps.pm_time = t;
+      targ->client->ps.pm_flags |= PMF_TIME_KNOCKBACK;
+    }
+  }
+}
+
+
+/*
++============
 T_Damage
 
 targ    entity that is being damaged
diff -Nru trem901-original-wraths/src/game/g_local.h trem901-original-wraths-tmp2/src/game/g_local.h
--- trem901-original-wraths/src/game/g_local.h	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_local.h	2007-08-18 07:35:29.000000000 +0200
@@ -799,6 +799,7 @@
 // g_combat.c
 //
 qboolean  CanDamage( gentity_t *targ, vec3_t origin );
+void      G_Knockback( gentity_t *targ, vec3_t dir, int knockback );
 void      G_Damage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker,
                     vec3_t dir, vec3_t point, int damage, int dflags, int mod );
 void      G_SelectiveDamage( gentity_t *targ, gentity_t *inflictor, gentity_t *attacker, vec3_t dir,
@@ -1184,6 +1185,9 @@
 
 extern  vmCvar_t  g_dretchPunt;
 
+extern  vmCvar_t  g_slapKnockback;
+extern  vmCvar_t  g_slapDamage;
+
 void      trap_Printf( const char *fmt );
 void      trap_Error( const char *fmt );
 int       trap_Milliseconds( void );
diff -Nru trem901-original-wraths/src/game/g_main.c trem901-original-wraths-tmp2/src/game/g_main.c
--- trem901-original-wraths/src/game/g_main.c	2007-07-15 09:04:09.000000000 +0200
+++ trem901-original-wraths-tmp2/src/game/g_main.c	2007-08-18 07:35:29.000000000 +0200
@@ -146,6 +146,9 @@
 
 vmCvar_t  g_allowShare;
 
+vmCvar_t  g_slapKnockback;
+vmCvar_t  g_slapDamage;
+
 static cvarTable_t   gameCvarTable[ ] =
 {
   // don't override the cheat state set by the system
@@ -277,7 +280,10 @@
   
   { &g_rankings, "g_rankings", "0", 0, 0, qfalse},
   
-  { &g_allowShare, "g_allowShare", "1", CVAR_ARCHIVE, 0, qfalse}
+  { &g_allowShare, "g_allowShare", "1", CVAR_ARCHIVE, 0, qfalse},
+  
+  { &g_slapKnockback, "g_slapKnockback", "200", CVAR_ARCHIVE, 0, qfalse},
+  { &g_slapDamage, "g_slapDamage", "5", CVAR_ARCHIVE, 0, qfalse}
 };
 
 static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );
