Confused badminton players
Python 2: 320 chars - 45% = 176

def f(n,t,s):
 for l,r in zip(s,s[1:]):
  d=[r[0]-l[0],r[1]-l[1]]
  if[0,1]!=sorted(d):print'E';break
  if d[1]==t:v=2*t;n[v:v+2]=n[v:v+2][::-1]
  t=d[1];m=max(map(len,n))+2;z=('|'+'-'*m)*2;c='|{:^%d}'%m;print'|\n'.join([z,c*2,'|#'+'#'*2*m,c*2,z,'Player {} of team {} serves next.\n']).format(*n+[n[2*t+(t+r[t])%2],t+1])


I'm not happy with lots of things. For instance the line d=[r[0]-l[0],r[1]-l[1]] is so ugly. But spend quite some time in golfing this. 

Claims all 3 bonuses. 
Please tell me, if I my output is not entirely the way you wanted. The question was not very clear. 

Usage:

This defines a python method. The parameters are a list of strings (the names of the players), an integer 0 or 1 (serving team) and a list of tuples of the scores. 

f(["Jim","Bob","P3","P4"],0,[(0, 0), (0, 1), (0, 2), (1, 2), (1, 3)])
f(["Jim","Bob","A","Montgomery"],0,[(0, 0), (1, 0), (2, 0), (3, 0), (3, 1), (3, 2), (4, 2), (4, 3), (5, 3), (6, 3), (6, 4), (7, 4), (7, 5), (7, 6), (8, 6), (8, 7), (9, 7), (10, 7), (11, 7), (12, 7), (12, 8), (12, 9), (13, 9)])
f(["Jim","Bob","P3","P4"],0,[(0, 0), (0, 1), (0, 2), (1, 2), (2, 2), (3, 3), (4, 3), (4, 4)])


Output:

|-----|-----|
| Jim | Bob |
|###########|
| P4  | P3  |
|-----|-----|
Player P4 of team 2 serves next.

|------------|------------|
|    Bob     |    Jim     |
|#########################|
| Montgomery |     A      |
|------------|------------|
Player Jim of team 1 serves next.

E


This is of course shortened, for the full output visit http://pastebin.com/AzbnEbaH.