diff --git a/engine/common/console.h b/engine/common/console.h
index 5dca25f28..648b5c3ae 100644
--- a/engine/common/console.h
+++ b/engine/common/console.h
@@ -57,8 +57,9 @@ extern consolecolours_t consolecolours[MAXCONCOLOURS];
 #define S_COLOR_WHITE	"^7"
 
 #define		CON_TEXTSIZE	16384
-typedef struct
+typedef struct console_s
 {
+	char name[64];
 	unsigned short	text[CON_TEXTSIZE];
 	int		current;		// line where next message will be printed
 	int		x;				// offset in current line for next print
@@ -66,11 +67,13 @@ typedef struct
 	int		linewidth;
 	int		totallines;
 	int		vislines;
-	void	(*redirect) (int key);
+	void	(*redirect) (struct console_s *con, int key);
+	void	*userdata;
+	struct console_s *next;
 } console_t;
 
 extern	console_t	con_main;
-extern	console_t	*con;			// point to either con_main or con_chat
+extern	console_t	*con_current;			// point to either con_main or con_chat
 
 extern	int			con_ormask;
 
@@ -87,7 +90,6 @@ void Con_CheckResize (void);
 void Con_Init (void);
 void Con_DrawConsole (int lines, qboolean noback);
 void Con_Print (char *txt);
-void Con_CycleConsole (void);
 void VARGS Con_Printf (const char *fmt, ...);
 void VARGS Con_TPrintf (translation_t text, ...);
 void VARGS Con_DPrintf (char *fmt, ...);
@@ -97,6 +99,15 @@ void Con_DrawNotify (void);
 void Con_ClearNotify (void);
 void Con_ToggleConsole_f (void);
 
+
+void Con_CycleConsole (void);
+qboolean Con_IsActive (console_t *con);
+void Con_Destroy (console_t *con);
+console_t *Con_FindConsole(char *name);
+console_t *Con_Create(char *name);
+void Con_SetVisible (console_t *con);
+void Con_PrintCon (console_t *con, char *txt);
+
 void Con_NotifyBox (char *text);	// during startup for sound / cd warnings
 
 #ifdef CRAZYDEBUGGING
diff --git a/engine/common/cvar.c b/engine/common/cvar.c
index 8b31c100b..1499e7dff 100644
--- a/engine/common/cvar.c
+++ b/engine/common/cvar.c
@@ -432,7 +432,6 @@ void Cvar_Register (cvar_t *variable, char *groupname)
 	{
 		if (old->flags & CVAR_POINTER)
 		{
-			cvar_t *prev;
 			group = Cvar_GetGroup(groupname);
 
 			variable->modified = old->modified;
diff --git a/engine/common/plugin.c b/engine/common/plugin.c
index 61785b1f1..8937a2d72 100644
--- a/engine/common/plugin.c
+++ b/engine/common/plugin.c
@@ -13,6 +13,7 @@ typedef struct plugin_s {
 	vm_t *vm;
 	int tick;
 	int executestring;
+	int conexecutecommand;
 	int menufunction;
 	int sbarlevel[3];	//0 - main sbar, 1 - supplementry sbar sections (make sure these can be switched off), 2 - overlays (scoreboard). menus kill all.
 	int reschange;
@@ -214,6 +215,8 @@ int Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg)
 		currentplug->tick = arg[1];
 	else if (!strcmp(name, "ExecuteCommand"))
 		currentplug->executestring = arg[1];
+	else if (!strcmp(name, "ConExecuteCommand"))
+		currentplug->conexecutecommand = arg[1];
 	else if (!strcmp(name, "MenuEvent"))
 		currentplug->menufunction = arg[1];
 	else if (!strcmp(name, "UpdateVideo"))
@@ -474,14 +477,14 @@ int Plug_Draw_Fill(void *offset, unsigned int mask, const long *arg)
 	{
 #ifdef RGLQUAKE
 	case QR_OPENGL:
-		glDisable(GL_TEXTURE_2D);
-		glBegin(GL_QUADS);
-		glVertex2f(x, y);
-		glVertex2f(x+width, y);
-		glVertex2f(x+width, y+height);
-		glVertex2f(x, y+height);
-		glEnd();
-		glEnable(GL_TEXTURE_2D);
+		qglDisable(GL_TEXTURE_2D);
+		qglBegin(GL_QUADS);
+		qglVertex2f(x, y);
+		qglVertex2f(x+width, y);
+		qglVertex2f(x+width, y+height);
+		qglVertex2f(x, y+height);
+		qglEnd();
+		qglEnable(GL_TEXTURE_2D);
 		return 1;
 #endif
 	}
@@ -634,6 +637,35 @@ int Plug_CL_GetStats(void *offset, unsigned int mask, const long *arg)
 	return max;
 }
 
+int Plug_Con_SubPrint(void *offset, unsigned int mask, const long *arg)
+{
+	char *name = VM_POINTER(arg[0]);
+	char *text = VM_POINTER(arg[1]);
+	console_t *con;
+	con = Con_FindConsole(name);
+	if (!con)
+	{
+		con = Con_Create(name);
+		Con_SetVisible(con);
+	}
+
+	Con_PrintCon(con, text);
+
+	return 1;
+}
+int Plug_Con_RenameSub(void *offset, unsigned int mask, const long *arg)
+{
+	char *name = VM_POINTER(arg[0]);
+	console_t *con;
+	con = Con_FindConsole(name);
+	if (!con)
+		return 0;
+
+	Q_strncpyz(con->name, name, sizeof(con->name));
+
+	return 1;
+}
+
 void Plug_Init(void)
 {
 	Plug_RegisterBuiltin("Plug_GetEngineFunction",	Plug_FindBuiltin, 0);//plugin wishes to find a builtin number.
@@ -666,6 +698,9 @@ void Plug_Init(void)
 	Plug_RegisterBuiltin("Draw_Colour3f",			Plug_Draw_Colour3f, 0);
 	Plug_RegisterBuiltin("Draw_Colour4f",			Plug_Draw_Colour4f, 0);
 
+	Plug_RegisterBuiltin("Con_SubPrint",			Plug_Con_SubPrint, 0);
+	Plug_RegisterBuiltin("Con_RenameSub",			Plug_Con_RenameSub, 0);
+
 #ifdef _WIN32
 	COM_EnumerateFiles("plugins/*x86.dll",	Plug_Emumerated, "x86.dll");
 #elif defined(__linux__)
diff --git a/engine/common/pmove.c b/engine/common/pmove.c
index 2c8e0254d..581862f8e 100644
--- a/engine/common/pmove.c
+++ b/engine/common/pmove.c
@@ -168,13 +168,22 @@ int PM_SlideMove (void)
 //
 		for (i=0 ; i<numplanes ; i++)
 		{
+			if (movevars.walljump == 2)	//just bounce off!
+			{	//pinball
+				PM_ClipVelocity (original_velocity, planes[i], pmove.velocity, 2);
+				return 0;
+			}
+			//regular run at a wall and jump off
 			if (movevars.walljump && planes[i][2] != 1	//not on floors
-				&& Length(pmove.velocity)>200 && pmove.cmd.buttons & 2 && !pmove.jump_held)
+				&& Length(pmove.velocity)>200 && pmove.cmd.buttons & 2 && !pmove.jump_held && !pmove.waterjumptime)
 			{
 				PM_ClipVelocity (original_velocity, planes[i], pmove.velocity, 2);
-				pmove.velocity[2] = 270;
+				pmove.velocity[2] += 270;
+				if (pmove.velocity[2] < 125)
+					pmove.velocity[2] = 125;
 				pmove.jump_msec = pmove.cmd.msec;
 				pmove.jump_held = true;
+				pmove.waterjumptime = 0;
 				return 0;
 			}
 			PM_ClipVelocity (original_velocity, planes[i], pmove.velocity, 1);