--- quake3/cgame/cg_consolecmds.c	Sun Jan 14 16:45:10 2001
+++ q3alias/cgame/cg_consolecmds.c	Thu Mar 29 21:01:37 2001
@@ -388,6 +388,44 @@
 #endif
 
 /*
+ ========
+  CG_Alias_f
+ ========
+*/
+static void CG_Alias_f (void)
+{
+  char name[MAX_CVAR_VALUE_STRING];
+  char content[MAX_CVAR_VALUE_STRING];
+  int i;
+
+  if (trap_Argc() == 1)  /* No parameters -- list all aliases. */
+    {
+      trap_SendConsoleCommand("cvarlist &*\n");
+      return;
+    }
+  if (trap_Argc() == 2)  /* Alias name only -- list its content. */
+    {
+      trap_SendConsoleCommand(va("cvarlist &%s\n", CG_Argv(1)));
+      return;
+    }
+
+  /* Construct cvar name of the alias. */
+  Q_strncpyz(name, va("&%s", CG_Argv(1)), sizeof(name));
+
+  /* Construct alias content. */
+  /* String up all the arguments separated by space. */
+  Q_strncpyz(content, CG_Argv(2), sizeof(content));
+  for (i = 3; i < trap_Argc(); i++)
+      Q_strncpyz(content, va("%s %s", content, CG_Argv(i)), sizeof(content));
+
+  /* Stash it. */
+  /* We don't have a cgame-space vmCvar_t to associate, so pass NULL instead. */
+  /* We want the alias to be persistant, so have it saved to q3config.cfg */
+  trap_Cvar_Register(NULL, name, content, CVAR_ARCHIVE);
+  trap_Cvar_Set(name, content);
+}
+
+/*
 ==================
 CG_StartOrbit_f
 ==================
@@ -461,6 +499,7 @@
 	{ "scoresDown", CG_scrollScoresDown_f },
 	{ "scoresUp", CG_scrollScoresUp_f },
 #endif
+	{ "alias", CG_Alias_f },
 	{ "startOrbit", CG_StartOrbit_f },
 	{ "loaddeferred", CG_LoadDeferredPlayers }	
 };
@@ -477,6 +516,7 @@
 qboolean CG_ConsoleCommand( void ) {
 	const char	*cmd;
 	int		i;
+  char cvartest[5];
 
 	cmd = CG_Argv(0);
 
@@ -486,6 +526,14 @@
 			return qtrue;
 		}
 	}
+
+  //Command unknown.  Try as alias.
+  trap_Cvar_VariableStringBuffer(va("&%s", cmd), cvartest, 5);
+  if (*cvartest) {  /* exists? */
+    trap_SendConsoleCommand(va("vstr &%s", cmd));
+    return qtrue;
+  }
+  //Well, tough. Alias unknown.
 
 	return qfalse;
 }
