diff --git a/obj/team.c b/obj/team.c
new file mode 100644
index 0000000..0319f5e
--- /dev/null
+++ b/obj/team.c
@@ -0,0 +1,1432 @@
+#pragma strong_types,save_types
+#pragma no_shadow
+// TODO: Morgoth erbt das Teamobjekt: klaeren warum und wieso eigentlich.
+//#pragma no_inherit
+#pragma pedantic
+
+#include <living/team.h>
+#include <properties.h>
+#include <language.h>
+#include <new_skills.h>
+#include <ansi.h>
+#include <wizlevels.h>
+#define ME this_object()
+#define PO previous_object()
+#define TP this_player()
+#define TI this_interactive()
+
+#define AUTOINF_HP_MINUS 0x01
+#define AUTOINF_HP_PLUS  0x02
+#define AUTOINF_SP_MINUS 0x04
+#define AUTOINF_SP_PLUS  0x08
+#define AUTOINF_INSTANT  0x10
+
+private nosave mapping is_member;   // Teammitglieder
+private nosave object leader;       // Teamleiter
+private nosave string tname;        // Teamname
+private nosave mapping wanted_row;  // Gewuenschte Reihe
+private nosave mapping wimpy_row;   // Fluchtreihe
+private nosave mapping act_row;     // Aktuelle Reihe
+private nosave mapping autofollow;  // Spieler folgt Teamleiter
+private nosave mapping attack_cmd;  // Spieler hat Angriffsbefehl
+private nosave mapping assoc_mem;   // Zugeordnete Mitglieder (Kampf NPCs)
+private nosave int *formin,*formax; // Formation
+private nosave mixed *rows;         // Die Reihen
+private nosave int last_reorder;    // Letzte Formationspruefung
+private nosave mapping h;           // Sortier-Score: 125*G.Reihe-HP
+private nosave object *att_exec;    // Mitglieder, die Attacke ausfuehren.
+private nosave object *mis_attacked;// (Ex-)Mitglieder ohne Begruessungsschlag
+private nosave mapping mis_init_att;// Fehlende Begruessungsschlaege
+private nosave mapping hp_info;     // HP, MAX_HP, SP, MAX_SP
+private nosave int autoinf_flags;
+private nosave mapping autoinf_hp;
+private nosave mapping autoinf_sp;
+private nosave int autoinf_time;
+private nosave string *hist;
+
+private nosave object debugger;
+
+void _set_debug() {
+  if (!debugger && IS_LEARNER(TI))
+    debugger=TI;
+  else if (debugger==TI)
+    debugger=0;
+}
+ 
+private void debug(string str) {
+  if (objectp(debugger) && stringp(str))
+    tell_object(debugger,"#TEAM: "+str);
+}
+
+void create() {
+  autoinf_flags=0;
+  autoinf_sp=([]);
+  autoinf_hp=([]);
+  is_member=([]);
+  leader=0;
+  wanted_row=([]);
+  act_row=([]);
+  wimpy_row=([]);
+  autofollow=([]);
+  attack_cmd=([]);
+  assoc_mem=([]);
+  formin=({1,0,0,0,0});
+  formax=({5,4,3,2,1});
+  rows=EMPTY_TEAMARRAY;
+  h=([]);
+  att_exec=({});
+  mis_init_att=([]);
+  mis_attacked=({});
+  hp_info=([]);
+  hist=({});
+  if (object_name(ME)==TEAM_OBJECT)
+    return;
+  if (!stringp(tname=TEAM_MASTER->RegisterTeam()))
+    tname="?";
+}
+
+object *Members() {
+  return (m_indices(is_member)-({0}));
+}
+
+object Leader() {
+  return leader;
+}
+
+varargs string name(int casus, int demon) {
+  if (!stringp(tname))
+    return "Team ?";
+  return "Team "+capitalize(tname);
+}
+
+varargs string Name(int casus, int demon) {
+  return name(casus,demon);
+}
+
+varargs int remove(int silent) {
+  if (mappingp(is_member) && sizeof(Members())) // Nur leere Teams removen
+    return 0;
+  TEAM_MASTER->UnregisterTeam(); // Teamnamen freigeben.
+  destruct(ME);
+  return 1;
+}
+
+private void TryRemove() {
+  if (clonep(ME)
+      && (!mappingp(is_member) || !sizeof(Members()))
+      && !first_inventory(ME)
+      && find_call_out("remove")<0)
+    call_out("remove",0);
+}
+
+int CmpFirstArrayElement(mixed *a, mixed *b) {
+  return(a[0]<b[0]);
+}
+
+varargs private void gtell(string str, string who, int tohist) {
+  int i;
+  object *tmembers,rochus;
+  string prefix,msg;
+
+  tmembers=Members();
+  prefix=sprintf("[%s:%s] ",name(),stringp(who)?who:"");
+  msg=break_string(str,78,prefix);
+  for (i=sizeof(tmembers)-1;i>=0;i--)
+    tell_object(tmembers[i],msg);
+  if (objectp(rochus=find_player("rochus"))
+      && rochus->QueryProp("debug_team"))
+    tell_object(rochus,msg);
+  if (tohist)
+    hist=(hist+({break_string(str+" <"+ctime()[11..15]+">",78,prefix)}))[-100..];
+}
+
+int IsMember(object ob) {
+  return (objectp(ob) && is_member[ob]);
+}
+
+int IsInteractiveMember(object ob) {
+  return (objectp(ob) && is_member[ob] && query_once_interactive(ob));
+}
+
+varargs private int *GetHpInfo(object ob, closure cl) {
+  int *res;
+
+  if (!closurep(cl)) cl=symbol_function("QueryProp",ob);
+  if (!pointerp(res=hp_info[ob]) || sizeof(res)<4)
+    res=({0,funcall(cl,P_MAX_HP),0,funcall(cl,P_MAX_SP)});
+  res[0]=funcall(cl,P_HP);
+  res[2]=funcall(cl,P_SP);
+  return hp_info[ob]=res;
+}
+
+int CompareHp(object a, object b) {
+  return h[a]>h[b];
+}
+
+// Aktualisiert act_row (->wer steht in welcher Reihe).
+private void UpdateActRow() {
+  int i,j,update_hp;
+  object *new;
+  mixed aso;
+
+  act_row=([]);
+  rows[0]+=Members();
+  update_hp=0;
+  if (!mappingp(h)) {
+    h=([]);
+    update_hp=1;
+  }
+  for (i=MAX_TEAMROWS-1;i>=0;i--) {
+    new=({});
+    foreach(object ob: rows[i]) {
+      if (objectp(ob) && is_member[ob] && !act_row[ob]) {
+        act_row[ob]=i+1;
+        new+=({ob});
+        if (update_hp) {
+          if (!objectp(aso=assoc_mem[ob]) || environment(aso)!=environment(ob))
+            aso=ob;
+          h[ob]=
+            1000*wanted_row[aso]
+            +40*act_row[aso]
+            -(query_once_interactive(aso)?8:2)*aso->QueryProp(P_HP)
+            -query_once_interactive(ob);
+          // NPCs bekommen fast gleichen Wert wie Caster,
+          // im Zweifelsfalle steht der Caster weiter vorne...
+        }
+      }
+    }
+    rows[i]=sort_array(new,"CompareHp",ME);
+  }
+}
+
+private void CheckFormation() {
+  int i,mincap,maxcap,d,num;
+
+  mincap=maxcap=0;
+  if (formin[0]<1)
+    formin[0]=1;
+  
+  // erstmal die Wuensche normalisieren/korrigieren auf sinnvolle Werte.
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    if (formin[i]<0) formin[i]=0;
+    if (formax[i]<formin[i]) formax[i]=formin[i];
+    if (formax[i]>MAX_TEAM_ROWLEN) formax[i]=MAX_TEAM_ROWLEN;
+    if (formin[i]>formax[i]) formin[i]=formax[i];
+    mincap+=formin[i]; // Summe der min. je Reihe gewuenschten.
+    maxcap+=formax[i]; // Summe der max. je Reihe gewuenschten.
+  }
+
+  num=sizeof(Members());
+
+  // max. gewuenschte Reihenlaenge verlaengern, wenn die Summe der maximal je
+  // Reihe gewuenschten kleiner als die Anzahl der Spieler ist. Von vorne
+  // natuerlich.
+  d=num-maxcap;
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    if (d<=0)
+      break;
+    d-=(MAX_TEAM_ROWLEN-formax[i]);
+    formax[i]=MAX_TEAM_ROWLEN;
+    if (d<0)
+      formax[i]+=d;  // doch noch was uebrig, wieder anhaengen. 
+  }
+  // min. gewuenschte Reihenlaenge auf 0 verkuerzen, wenn die Summe der
+  // minimal je Reihe gewuenschten groesser als die Anzahl der Spieler ist.
+  // Von hinten natuerlich.
+  d=mincap-num; // 
+  for (i=MAX_TEAMROWS-1;i>=0;i--) {
+    if (d<=0)
+      break;
+    d-=formin[i];
+    formin[i]=0;
+    if (d<0)
+      formin[i]-=d; // doch noch was uebrig, wieder anhaengen.
+  }
+}
+
+private void MakeFormation() {
+  // Verlegungsstrategie:
+  //    Richtung Test Verschieben
+  // 1. -----> a) MAX          <- X
+  //           b) MAX             X ->
+  //           c) MIN             X <- <- <- <-
+  // 2. <----- a) MIN -> -> -> -> X
+  //           b) MAX          <- X
+  int i,j,d;
+
+  last_reorder=time();
+  UpdateActRow();
+  CheckFormation();
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    d=sizeof(rows[i]);
+    if (d<formin[i] || d>formax[i])
+      break;
+  }
+  if (i>=MAX_TEAMROWS)
+    return; // Formation ist noch in Ordnung
+
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    if (sizeof(rows[i])>formax[i]) {     // Reihe ist zu voll
+      if (i>0) {
+        d=formax[i-1]-sizeof(rows[i-1]);
+        if (d>0) {                       // Reihe vorher hat d freie Plaetze
+          rows[i-1]+=rows[i][0..(d-1)];  // Also d Mitglieder abgeben
+          rows[i]=rows[i][d..];
+        }
+      }
+      if (i<MAX_TEAMROWS-1 && sizeof(rows[i])>formax[i]) {// Immer noch zu voll
+        rows[i+1]=rows[i][formax[i]..]+rows[i+1];         // Rest nach hinten.
+        rows[i]=rows[i][0..(formax[i]-1)];
+      }
+      continue; // War zu voll, kann nicht zu leer sein
+    }
+    for (j=i+1;j<MAX_TEAMROWS;j++) {
+      d=formin[i]-sizeof(rows[i]);
+      if (d<=0)                   // Ausreichende Anzahl
+        break;                    // kein weiteres j noetig
+      rows[i]+=rows[j][0..(d-1)]; // Sonst Nachschub von hinten holen
+      rows[j]=rows[j][d..];
+    }
+  }
+  for (i=MAX_TEAMROWS-1;i>0;i--) {
+    for (j=i-1;j>=0;j--) {
+      d=formin[i]-sizeof(rows[i]);
+      if (d<=0)                   // Ausreichende Anzahl
+        break;                    // kein weiteres j noetig
+      rows[i]+=rows[j][0..(d-1)]; // Sonst Nachschub von vorne holen
+      rows[j]=rows[j][d..];
+    }
+    d=sizeof(rows[i])-formax[i];
+    if (d>0) {
+      rows[i-1]+=rows[i][0..(d-1)]; // Ueberschuss nach vorne schieben
+      rows[i]=rows[i][d..];
+    }
+  }
+  UpdateActRow();
+}
+
+private void RemoveFromRow(object ob, int src) {
+  if (src<0 || src>=MAX_TEAMROWS)
+    return;
+  rows[src]-=({ob});
+  if (sizeof(rows[src])>=formin[src])
+    return;
+  // Falls hinten noch Ueberschuss da ist, her damit.
+  if (src<MAX_TEAMROWS-1 && sizeof(rows[src+1])-1>=formin[src+1]) {
+    rows[src]+=rows[src+1][0..0];
+    rows[src+1]=rows[src+1][1..];
+    return;
+  }
+  // Falls vorne noch Ueberschuss da ist, her damit.
+  if (src>0 && sizeof(rows[src-1])-1>=formin[src-1]) {
+    rows[src]=rows[src-1][<1..]+rows[src];
+    rows[src-1]=rows[src-1][0..<2];
+  }
+}
+
+private void AddToRow(object ob, int dest) {
+  if (dest<0 || dest>=MAX_TEAMROWS)
+    return;
+  rows[dest]+=({ob});
+  if (sizeof(rows[dest])<=formax[dest])
+    return;
+  // Falls vorne noch jemand hin kann, dorthin
+  if (dest>0 && sizeof(rows[dest-1])+1<=formax[dest-1]) {
+    rows[dest-1]+=rows[dest][0..];
+    rows[dest]=rows[dest][1..];
+    return;
+  }
+  // Falls hinten noch jemand hin kann, dorthin
+  if (dest<MAX_TEAMROWS-1 && sizeof(rows[dest+1])+1<=formax[dest+1]) {
+    // Dest: ({... <3, <2, ob});
+    rows[dest+1]=rows[dest][<2..<2]+rows[dest+1];
+    rows[dest]=rows[dest][0..<3]+({ob});
+  }
+}
+
+private void CycleRows(object ob, int src, int dest) {
+  int i;
+
+  if (src<0 || src>=MAX_TEAMROWS || dest<0 || dest>=MAX_TEAMROWS)
+    return;
+  rows[src]-=({ob});
+  if (sizeof(rows[src])<formin[src] || sizeof(rows[dest])>=formax[dest]) {
+    if (src<dest) {             // (<- -X) <- <- <- <- (+X <-)
+      for (i=src+1;i<=dest;i++) {
+        rows[i-1]+=rows[i][0..0];
+        rows[i]=rows[i][1..];
+      }
+    } else if (src>dest) {           // (-> +X) -> -> -> -> (-X ->)
+      for (i=src-1;i>=dest;i--) {
+        rows[i+1]=rows[i][<1..]+rows[i+1];
+        rows[i]=rows[i][0..<2];
+      }
+    }
+  }
+  if (src<=dest)
+    rows[dest]+=({ob});
+  else
+    rows[dest]=({ob})+rows[dest];
+}
+
+// tauscht zufaellig aus den ersten 4 Reihen aus einer Reihe den letzten mit
+// dem ersten aus der Folgereihe, wenn die der Score des vorderen Spieler mehr
+// als 10 groesser als der des hinteren Spielers ist.
+private void RandomChangeRow() {
+  int *nums,i;
+  object p1,p2;
+
+  if (!mappingp(h))
+    UpdateActRow();
+  for (nums=({0,1,2,3});sizeof(nums);nums-=({i})) {
+    i=nums[random(sizeof(nums))];
+    if (!sizeof(rows[i]) || !sizeof(rows[i+1])) continue;
+    if (!objectp(p1=rows[i][<1]) || !objectp(p2=rows[i+1][0])) continue;
+    if (wanted_row[p1]<wanted_row[p2]) continue;
+    if (h[p2]-h[p1]>=-10) continue;
+    rows[i][<1]=p2;
+    rows[i+1][0]=p1;
+    return;
+  }
+}
+
+varargs private string
+CountUpNames(object *obs, string zsing, string zplur) {
+  string res;
+  object ob;
+  int i,sz;
+
+  res="";
+  if (!pointerp(obs)) return res;
+  if (!stringp(zsing)) zsing="";
+  if (!stringp(zplur)) zplur="";
+  if (sz=sizeof(obs)) {
+    for (i=0;i<sz;i++) {
+      if (i)
+	      res+=((i<sz-1)?", ":" und ");
+      if (objectp(ob=obs[i]))
+        res+=ob->name(WER);
+    }
+    if (sz>1)
+      res+=zplur;
+    else
+      res+=zsing;
+  }
+  return res;
+}
+
+static void DoChangeRow(object pl, int dest) {
+  mapping old_row,ec1,ec2,ecb;
+  int i;
+  object *obs,*envs,env;
+  string *msg,str;
+
+  dest--;
+  CheckFormation();
+  h=0;  // damit HP-Liste geupdated wird.
+  UpdateActRow();
+  old_row=deep_copy(act_row);
+
+  // welche Objekte bewegen?
+  obs=({});
+  if (objectp(pl)) {
+    obs=({pl});
+    if (pointerp(assoc_mem[pl]))
+      obs+=assoc_mem[pl];
+  } else {
+    RandomChangeRow();
+  }
+
+  foreach (object ob:obs) {
+    if (!objectp(ob))
+      continue;
+    // Alle assoziierten NPC kriegen die gleiche gewuenschte Reihe wie der
+    // Spieler.
+    wanted_row[ob]=wanted_row[pl];
+    UpdateActRow();
+    // und dann in die gew. Reihe stopfen.
+    int src=act_row[ob]-1;
+    if (dest<0 || dest>=MAX_TEAMROWS)
+      RemoveFromRow(ob,src);
+    else if (src<0 || src>=MAX_TEAMROWS)
+      AddToRow(ob,dest);
+    else if (src!=dest)
+      CycleRows(ob,src,dest);
+  }
+
+  MakeFormation();
+
+  obs = Members(); // alle Members beruecksichtigen beim Abgleich!
+  object *changed = allocate(0);
+  foreach (object ob:obs)
+    if (objectp(ob) && old_row[ob]!=act_row[ob]) {
+      ob->InformRowChange(old_row[ob],act_row[ob]);
+      changed += ({ob});
+    }
+
+  // Ab jetzt nur noch Ausgabe.
+  if (get_eval_cost()<800000) return; // War schon teuer genug, Lagvermeidung
+  msg=({});ec1=([]);ec2=([]);ecb=([]);
+  foreach (object ob:changed) {
+    tell_object(ob,sprintf("Du bist jetzt in Reihe %d.\n",act_row[ob]));
+    msg+=({sprintf("%s->%d",ob->Name(WER),act_row[ob])});
+    if (query_once_interactive(ob) && !interactive(ob)) continue;
+    if (!objectp(env=environment(ob))) continue;
+    if (old_row[ob]<=1) {
+      if (!pointerp(envs=ec1[env])) envs=({});
+      ec1[env]=envs+({ob});ecb[env]|=1;
+    }
+    if (act_row[ob]<=1) {
+      if (!pointerp(envs=ec2[env])) envs=({});
+      ec2[env]=envs+({ob});ecb[env]|=2;
+    }
+  }
+  if (sizeof(msg))
+    gtell(implode(msg,", ")); // Ausgabe an alle Gruppenmitglieder.
+  m_delete(ecb,find_object("/room/netztot")); // Das gaebe Mega-Lag :-)
+  envs=m_indices(ecb);obs=Members();
+  for (i=sizeof(envs)-1;i>=0;i--) {
+    if (!objectp(env=envs[i])) continue;
+    str="";
+    str+=CountUpNames(ec1[env]," tritt zurueck"," treten zurueck");
+    if (ecb[env]==3) str+=", ";
+    str+=CountUpNames(ec2[env]," tritt vor"," treten vor");
+    str+=".\n";
+    tell_room(env,capitalize(break_string(str,78)),obs);
+  }
+}
+
+void UpdateFormation() {
+  DoChangeRow(0,0);
+}
+
+int SwapRows(object ob1, object ob2) {
+  int i,r1,r2,p1,p2;
+
+  if (!objectp(ob1) || !objectp(ob2) || ob1==ob2)
+    return 0;
+  r1=r2=-1;
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    if (r1==-1 && (p1=member(rows[i],ob1))>=0)
+      r1=i;
+    if (r2==-1 && (p2=member(rows[i],ob2))>=0)
+      r2=i;
+  }
+  if (r1==-1 || r2==-1)
+    return 0;
+  if (r1==r2)
+    return 1;
+  if (r1<r2) { // Nicht Monster vor Spieler stellen
+    if (query_once_interactive(ob1) && !interactive(ob2))
+      return 0;
+  } else {
+    if (query_once_interactive(ob2) && !interactive(ob1))
+      return 0;
+  }
+  rows[r1][p1]=ob2;ob2->InformRowChange(r2,r1);
+  rows[r2][p2]=ob1;ob1->InformRowChange(r1,r2);
+  gtell(ob1->Name(WER)+" und "+ob2->name(WER)+" tauschen die Plaetze.\n");
+  return 1;
+}
+
+private int ChangeRow(string arg) {
+  int num;
+
+  if (!arg || sscanf(arg,"%d",num)!=1)
+    return notify_fail("In welche Reihe willst Du denn wechseln?\n"),0;
+  if (num<1 || num>MAX_TEAMROWS)
+    return notify_fail("Die Reihenangabe ist ungueltig.\n"),0;
+  TP->SetProp(P_TEAM_WANTED_ROW,wanted_row[TP]=num);
+  printf("Du versuchst in Reihe %d zu wechseln.\n",num);
+  DoChangeRow(TP,num);
+  return 1;
+}
+
+private int ChangeWimpyRow(string arg) {
+  int num;
+
+  if (!arg || sscanf(arg,"%d",num)!=1)
+    return notify_fail("In welche Reihe willst Du fliehen?\n"),0;
+  if (num<0 || num>MAX_TEAMROWS)
+    return notify_fail("Die Reihenangabe ist ungueltig.\n"),0;
+  TP->SetProp(P_TEAM_WIMPY_ROW,wimpy_row[TP]=num);
+  if (num>1)
+    printf("Bei der Flucht wirst Du in Reihe %d wechseln.\n",num);
+  else
+    write("Bei der Flucht wirst Du den Raum verlassen.\n");
+  return 1;
+}
+
+mixed *PresentRows(object env) {
+  int i,j,d,arbeit;
+  mixed *res;
+  object *nd,ob;
+
+  if (!objectp(env))
+    env=environment(TP);
+  if (last_reorder!=time() || !mappingp(h))
+    UpdateFormation();
+  res=EMPTY_TEAMARRAY;arbeit=0;nd=({});
+  for (i=0;i<MAX_TEAMROWS;i++) {
+    object *new=({});
+    foreach(ob: rows[i]) {
+      if (objectp(ob) && is_member[ob] && environment(ob)==env) {
+        if (query_once_interactive(ob) && !interactive(ob)) {
+          nd+=({ob});
+          arbeit=1;
+        } else {
+          new+=({ob});
+        }
+      } else {
+        arbeit=1;
+      }
+    }
+    res[i]=new;
+  }
+  if (!arbeit)
+    return res;
+  for (i=j=0;i<MAX_TEAMROWS;i++) {
+    if (j<=i) j=i+1;
+    for (;j<MAX_TEAMROWS;j++) {
+      d=formin[i]-sizeof(res[i]);
+      if (d<=0)                   // Ausreichende Anzahl
+        break;                    // kein weiteres j noetig
+      res[i]+=res[j][0..(d-1)];   // Sonst Nachschub von hinten holen
+      res[j]=res[j][d..];
+    }
+  }
+  res[MAX_TEAMROWS-1]+=nd; // Netztote bieten keine Deckung, nach hinten.
+  return res;
+}
+
+mapping PresentPositions(mixed pres_rows) {
+  mapping res=([]);
+  if (objectp(pres_rows))
+    pres_rows=PresentRows(pres_rows);
+  if (!pointerp(pres_rows))
+    return res;
+  for (int i=0;i<MAX_TEAMROWS;i++) {
+    foreach(object ob: pres_rows[i])
+      if (ob)
+        res[ob]=i+1;
+  }
+  return res;
+}
+
+
+varargs int FleeToRow(object ob) {
+  int num;
+
+  if (!objectp(ob))
+    ob=TP;
+  if (!IsMember(ob))
+    return 0;
+  h=0; // Reihen bei naechster Abfrage neu sortieren
+  num=wimpy_row[ob];
+  if (num<2 || num>MAX_TEAMROWS) // Flucht in 1. Reihe nicht sinnvoll.
+    return 0;
+  if (num==wanted_row[ob]) // Ist schonmal nach hinten geflohen.
+    return 0;
+  tell_object(ob,sprintf("Du versuchst in Reihe %d zu fliehen.\n",num));
+  ob->SetProp(P_TEAM_WANTED_ROW,wanted_row[ob]=num);
+  DoChangeRow(ob,num);
+  if (PresentPositions(environment(ob))[ob]<=1) // Flucht gescheitert?
+    return 0;
+  return 1;
+}
+
+static int ChangeFormation(string arg) {
+  string *words;
+  int i,min,max;
+  mapping old_row;
+
+  if (arg=="aus")
+    arg="1-6 0-6 0-6 0-6 0-6";
+  i=sizeof(words=old_explode(arg," "));
+  if (i>MAX_TEAMROWS)
+    i=MAX_TEAMROWS;
+  for (--i;i>=0;i--) {
+    if (sscanf(words[i],"%d-%d",min,max)==2) {
+      formin[i]=min;
+      formax[i]=max;
+    } else if (sscanf(words[i],"%d",min)==1) {
+      formin[i]=formax[i]=min;
+    }
+  }
+
+  UpdateFormation();
+
+  words=({});
+  for (i=0;i<MAX_TEAMROWS;i++)
+    words+=({sprintf("%d-%d",formin[i],formax[i])});
+  gtell("Die Formation ist jetzt "+implode(words," / ")+".\n");
+  return 1;
+}
+
+int Shout(string str) {
+  if (!str || str=="")
+    return notify_fail("Was willst Du den anderen Teammitgliedern sagen?\n"),0;
+  gtell(str,TP->Name(WER),1);
+  return 1;
+}
+
+int Hist(string str) {
+  int i,anz,maximal;
+
+  // non-interactive oder Nicht-Mitglieder sollten die Hist nicht abfragen.
+  if (!IsInteractiveMember(TP)) return -1;
+
+  maximal=sizeof(hist);
+  if (str && sscanf(str,"%d",anz)==1)
+    i=maximal-anz;
+  if (i<0)
+    i=0;
+
+  TP->More(sprintf("%@s",hist[i..maximal])||"");
+  return 1;
+}
+
+private void DoChangeLeader(object ob) {
+  if (objectp(leader) && leader->QueryProp(P_TEAM_LEADER)==ME)
+    leader->SetProp(P_TEAM_LEADER,0);
+  leader=ob;
+  leader->SetProp(P_TEAM_LEADER,ME);
+}
+
+private int ChangeLeader(string arg) {
+  object ob;
+
+  if (stringp(arg) && arg!="") {
+    if (!objectp(ob=find_player(arg))
+        && !objectp(ob=present(arg,environment(TP))))
+      return notify_fail(capitalize(arg)+" nicht gefunden.\n"),0;
+  } else {
+    ob=TP;
+  }
+  if (objectp(leader)
+      && TP!=leader
+      && (!interactive(TP) || (interactive(leader) && query_idle(leader)<180)))
+    return notify_fail("Der Teamleiter ist noch aktiv.\n"),0;
+  if (objectp(leader)
+      && query_once_interactive(leader)
+      && !query_once_interactive(leader))
+    return notify_fail("Nur ein Spieler kann das Team leiten.\n"),0;
+  if (!IsMember(ob))
+    return notify_fail(ob->Name(WER)+" ist kein Teammitglied.\n"),0;
+  DoChangeLeader(ob);
+  gtell(ob->Name(WER)+" leitet jetzt das Team.\n");
+  return 1;
+}
+
+varargs private int CheckSecond(object pl, object *obs) {
+  mixed x,ip;
+  mapping second;
+  object ob;
+  int i;
+
+  if (!objectp(pl))
+    pl=TP;
+  if (!query_once_interactive(pl))
+    return 0;
+  if (!pointerp(obs))
+    obs=Members();
+  obs-=({pl});
+  second=([]);
+  for (i=sizeof(obs)-1;i>=0;i--) {
+    if (!objectp(ob=obs[i]) || !query_once_interactive(ob)) continue;
+    second[getuid(ob)]=1;
+    if (stringp(x=ob->QueryProp(P_SECOND)))
+      second[lower_case(x)]=1;
+  }
+  if (second[getuid(pl)] ||
+      (stringp(x=pl->QueryProp(P_SECOND)) && second[lower_case(x)]))
+    return 1;
+
+  if (!stringp(ip=pl->QueryProp(P_CALLED_FROM_IP)) || ip=="")
+    return 0;
+  for (i=sizeof(obs)-1;i>=0;i--) {
+    if (!objectp(ob=obs[i]) || !query_once_interactive(ob)) continue;
+    if (ob->QueryProp(P_CALLED_FROM_IP)!=ip) continue;
+    log_file("rochus/zweitieverdacht",
+             sprintf("%s %s,%s\n",ctime()[4..15],getuid(pl),getuid(ob)));
+    break;
+  }
+  return 0;
+}
+
+static int Allowed(object pl) {
+  mixed x;
+  string nm;
+
+  if (!objectp(pl))
+    return notify_fail("WER soll ins Team aufgenommen werden?\n"),0;
+  if (pl==TP)
+    nm="Du b";
+  else
+    nm=pl->Name(WER)+" ";
+  if (objectp(x=pl->QueryProp(P_TEAM)) && x!=ME)
+    return notify_fail(nm+"ist schon in einem anderen Team.\n"),0;
+  if (pl->QueryGuest())
+    return notify_fail(nm+"ist ein Gast.\n"),0;
+  if (pl->QueryProp(P_GHOST))
+    return notify_fail(nm+"ist ein Geist.\n"),0;
+  if (CheckSecond(pl))
+    return notify_fail(nm+"ist Zweitspieler eines Teammitglieds.\n"),0;
+  if (sizeof(filter(Members(),"IsInteractiveMember",ME))
+      >=MAX_TEAM_MEMBERS)
+    return notify_fail("Es sind schon zuviele Spieler im Team.\n"),0;
+  return 1;
+}
+
+private void DoAddMember(object ob) {
+  closure cl;
+
+  if (!IsMember(leader))
+    DoChangeLeader(ob);
+  ob->SetProp(P_TEAM,ME);
+  if (IsMember(ob))
+    return;
+  is_member[ob]=1;
+  cl=symbol_function("QueryProp",ob);
+  attack_cmd[ob]=funcall(cl,P_TEAM_ATTACK_CMD);
+  autofollow[ob]=funcall(cl,P_TEAM_AUTOFOLLOW);
+  wimpy_row[ob]=funcall(cl,P_TEAM_WIMPY_ROW);
+  wanted_row[ob]=funcall(cl,P_TEAM_WANTED_ROW);
+  if (!wanted_row[ob]) wanted_row[ob]=1;;
+  ob->SetProp(P_TEAM_NEWMEMBER,0);
+  GetHpInfo(ob,cl);
+  if (query_once_interactive(ob)) ob->AddHpHook(ME);
+  if (!objectp(assoc_mem[ob]))
+    gtell(ob->Name(WER)+" wurde ins Team aufgenommen.\n");
+  DoChangeRow(ob,wanted_row[ob]);
+}
+
+int AddAssocMember(object caster, object npc) {
+  object *obs;
+
+  if (extern_call() && PO!=caster)
+    return 0;
+  if (!IsMember(caster)
+      || !objectp(npc)
+      || query_once_interactive(npc)
+      || IsMember(npc)
+      || objectp(assoc_mem[caster])
+      || assoc_mem[npc]
+      || caster==npc)
+    return 0;
+  assoc_mem[npc]=caster;
+  DoAddMember(npc);
+  if (!pointerp(obs=assoc_mem[caster]))
+    obs=({});
+  obs=(obs-({npc,0}))+({npc});
+  assoc_mem[caster]=obs;
+  return 1;
+}
+
+static void AddMemberAndAssocs(object caster) {
+  object *obs,ob;
+  int i;
+
+  DoAddMember(caster);
+  if (!pointerp(obs=caster->QueryProp(P_TEAM_ASSOC_MEMBERS)))
+    return;
+  for (i=sizeof(obs)-1;i>=0;i--)
+    if (objectp(ob=obs[i]) && !caster->IsEnemy(ob))
+      AddAssocMember(caster,ob);
+}
+
+int AddMember(object ob) {
+ 
+  if (!Allowed(ob))
+    return 0;
+  
+  // Wenn es einen TP gibt, unterliegt er einigen Einschraenkungen.
+  // Dafuer wird er aber via Aufnahme ins Team auch ggf. Teamleiter, wenn
+  // noetig.
+  // TODO: Dieser Code geht davon aus, dass er nur aus einem Kommando
+  // ausgefuehrt wird und TP der Veranlasser der Aufnahme ist. Dies scheint
+  // mir unrealistisch. (Zesstra)
+  if (TP && TP==previous_object()) {
+    if (!Allowed(TP))
+      return 0;
+    if (TP!=ob && CheckSecond(ob,({TP}))) {// Zweitiereglung bei Gruendung.
+      notify_fail(ob->Name(WER)+" ist Zweitspieler von Dir.\n");
+      return 0;
+    }
+    if (!IsMember(leader))
+      AddMemberAndAssocs(TP);
+    if (TP!=leader) {
+      notify_fail("Nur der Teamleiter kann Mitglieder aufnehmen.\n");
+      return 0;
+    }
+  }
+
+  AddMemberAndAssocs(ob);
+  return 1;
+}
+
+private void DoRemoveMember(object ob) {
+  object *tmembers,caster;
+  mixed asmem;
+  int i;
+
+  ob->SetProp(P_TEAM,0);
+  m_delete(is_member,ob);
+  m_delete(wanted_row,ob);
+  m_delete(act_row,ob);
+  m_delete(wimpy_row,ob);
+  m_delete(autofollow,ob);
+  m_delete(attack_cmd,ob);
+  if (objectp(caster=assoc_mem[ob]) && pointerp(asmem=assoc_mem[caster]))
+    assoc_mem[caster]=asmem-({ob,0});
+  if (query_once_interactive(ob)) ob->RemoveHpHook(ME);
+  m_delete(hp_info,ob);
+  m_delete(autoinf_hp,ob);
+  m_delete(autoinf_sp,ob);
+  DoChangeRow(ob,-1);
+
+  if (!objectp(assoc_mem[ob])) {
+    if (ob->QueryProp(P_GHOST)) {
+      gtell(upper_case(ob->name(WER))+" HAT DAS TEAM VERLASSEN.","Tod");
+    } else {
+      tell_object(ob,"Du verlaesst das Team.\n");
+      gtell(ob->Name(WER)+" hat das Team verlassen.\n");
+    }
+  }
+  m_delete(assoc_mem,ob);
+
+  if (IsMember(leader)) // Hat das Team noch einen Leiter?
+    return;
+  tmembers=Members();ob=0;
+  if (i=sizeof(tmembers)) {
+    ob=tmembers[0];
+    for (--i;i>=0;i--) {
+      if (interactive(tmembers[i])) {
+        ob=tmembers[i];
+        break;
+      }
+      if (query_once_interactive(tmembers[i]))
+        ob==tmembers[i];
+    }
+    DoChangeLeader(ob);
+    gtell(leader->Name(WER)+" hat die Teamleitung uebernommen.\n");
+    return;
+  }
+  TryRemove();
+}
+
+int RemoveAssocMember(object caster, object npc) {
+  object *obs;
+
+  if (extern_call() && PO!=caster)
+    return 0;
+  if (!IsMember(caster) || assoc_mem[npc]!=caster)
+    return 0;
+  DoRemoveMember(npc);
+  return 1;
+}
+
+static void RemoveMemberAndAssocs(object caster) {
+  object *obs,ob;
+  int i;
+
+  if (pointerp(obs=caster->QueryProp(P_TEAM_ASSOC_MEMBERS))) {
+    for (i=sizeof(obs)-1;i>=0;i--)
+      if (objectp(ob=obs[i]))
+        RemoveAssocMember(caster,ob);
+  }
+  DoRemoveMember(caster);
+}
+
+private void RemoveSingles() {
+  object *obs;
+  mixed aso;
+
+  if (!IsMember(leader)) return;
+  if (!query_once_interactive(leader)) return; // NPC Team
+  obs=Members()-({leader});
+  if (pointerp(aso=assoc_mem[leader]))
+    obs-=aso;
+  if (sizeof(obs)) return;
+  gtell("Das Team loest sich auf.\n");
+  RemoveMemberAndAssocs(leader);
+  TryRemove();
+}
+
+int RemoveMember(mixed arg) {
+  object *mems,mem,ob;
+  int i;
+  
+  if (objectp(arg)) {
+    ob=arg;
+  } else if (stringp(arg) && arg!="") {
+    mems=Members()-({leader});
+    for (i=sizeof(mems)-1;i>=0;i--) {
+      if (objectp(mem=mems[i]) && mem->id(arg))  {
+        ob=mem;
+        if (query_once_interactive(ob))
+          break;
+      }
+    }
+    if (!objectp(ob))
+      return notify_fail(capitalize(arg)+" nicht gefunden.\n"),0;
+  } else {
+    return 0;
+  }
+  if (TP!=leader && TP!=ob && ob!=PO)
+    return notify_fail("Nur der Teamleiter kann Mitglieder entlassen.\n"),0;
+  if (!IsMember(ob) && ob->QueryProp(P_TEAM)!=ME)
+    return notify_fail(ob->Name(WER)+" ist kein Teammitglied.\n"),0;
+  if (PO!=ob && objectp(assoc_mem[ob]))
+    return notify_fail(ob->Name(WER)+" gehoert zu "+
+                       assoc_mem[ob]->Name(WEM)+".\n"),0;
+
+  RemoveMemberAndAssocs(ob);
+  RemoveSingles();
+  return 1;
+}
+
+static int ChangeName(string str) {
+  if (leader && TP!=leader)
+    return notify_fail("Nur der Teamleiter kann den Namen aendern.\n"),0;
+  if (!str || str=="")
+    return 0;
+  str=str[0..19];
+  if (!stringp(str=(TEAM_MASTER->RegisterTeam(str))))
+    return notify_fail("Der Name ist schon vergeben.\n"),0;
+  tname=str;
+  if (objectp(TP))
+    gtell(TP->Name(WER)+" aendert den Teamnamen auf \""+tname+"\".\n");
+  return 1;
+}
+
+void TeamInitAttack() {
+  object *obs,*ens,*removed,ob,en;
+  int i,j;
+
+  debug(sprintf("mis_init_att: %O\n",mis_init_att));
+  ens=m_indices(mis_init_att);removed=({});
+  for (i=sizeof(ens)-1;i>=0;i--) {
+    if (!objectp(en=ens[i]))
+      continue;
+    if (!pointerp(obs=mis_init_att[en]))
+      continue;
+    for (j=sizeof(obs)-1;j>=0;j--)
+      if (!IsMember(ob=obs[j]) || environment(ob)!=environment(en))
+        obs[j]=0;
+    obs-=({0});
+    ob=en->SelectNearEnemy(obs,1);
+    debug(sprintf("Begruessungsschlag von %O fuer %O\n",en,ob));
+    if (!objectp(ob))
+      continue;
+    en->Attack2(ob); // Begruessungsschlag
+    removed+=({en}); // Kein Begruessungsschlag mehr von diesem Monster
+  }
+
+  for (i=sizeof(mis_attacked)-1;i>=0;i--)
+    if (objectp(ob=mis_attacked[i]))
+      ob->ExecuteMissingAttacks(removed);
+  // Begruessungsschlaege die ausgefuehrt wurden entfernen
+  // und nicht ausgefuehrte nachholen
+
+  mis_attacked=({});
+  mis_init_att=([]);
+  att_exec=({});
+}
+
+int InitAttack_Callback(object enemy) {
+  object *arr;
+
+  if (!IsMember(PO) || member(att_exec,PO)<0)
+    return 0;
+  if (!pointerp(arr=mis_init_att[enemy]))
+    arr=({});
+  mis_init_att[enemy]=arr+({PO});
+  if (member(mis_attacked,PO)<0)
+    mis_attacked+=({PO});
+  return 1;
+}
+
+void TeamAttackExecuted_Callback(int success) {
+  if (!IsMember(PO))
+    return;
+  att_exec-=({PO,0});
+  if (!sizeof(att_exec))
+    TeamInitAttack();
+}
+
+private int StartAttack() {
+  object *tmembers,ob,env;
+  int i;
+
+  if (TP!=leader || !objectp(env=environment(TP)))
+    return notify_fail("Nur der Teamleiter kann den Angriff starten.\n"),0;
+  tmembers=Members();
+  TeamInitAttack(); // Falls noch Schlaege fehlen....
+  for (i=sizeof(tmembers)-1;i>=0;i--)
+    if (objectp(ob=tmembers[i]) && stringp(attack_cmd[ob]))
+      if (ob->CallTeamAttack(env)) // Angriff wird ausgefuehrt?
+        att_exec+=({ob});          // Liste der Angreifer
+  gtell(TP->Name(WER)+" startet den Angriff.\n");
+  return 1;
+}
+
+void StartFollow(object env) {
+  object *tmembers,ob;
+  int i;
+  string cmd,args;
+
+  // printf("ld:%O PO:%O TP:%O qv:%O env:%O\n",leader,PO,TP,query_verb(),env);
+  if (TP!=leader
+      || !stringp(cmd=query_verb())
+      || !objectp(env)
+      || TP!=PO
+      || TP->QueryProp(P_GHOST) // Der Befehl war wohl ungesund...
+      || TP->IsTeamMove()) // Angriffsbefehl nicht durch verfolge 2 mal...
+    return;
+  cmd="\\"+cmd;
+  if (stringp(args=TP->_unparsed_args()) && args!="")
+    cmd+=(" "+args);
+  tmembers=Members()-({leader});
+  for (i=sizeof(tmembers)-1;i>=0;i--)
+    if (objectp(ob=tmembers[i]) && autofollow[ob])    
+    	if(!query_once_interactive(ob)  || env==environment(ob)) // autofolge nur bei anfuehrer im gleichen raum
+    	      ob->CallTeamFollow(env,cmd);
+}
+
+void ShowTeamInfo() {
+  int i;
+  object *tmembers,ob;
+  string form;
+
+  if (!TI || TP!=TI || !IS_LEARNER(TI))
+    return;
+
+  UpdateActRow();
+  form="";
+  for (i=0;i<MAX_TEAMROWS;i++)
+    form+=sprintf(" %d-%d",formin[i],formax[i]);
+  printf("%s [%O] L: %s F:%s\n",name(),ME,
+         (objectp(leader)?leader->Name(WER):"?"),form);
+  tmembers=Members();
+  for (i=sizeof(tmembers)-1;i>=0;i--) {
+    ob=tmembers[i];
+    printf("  %d(%d) %s [%O]\n",
+           act_row[ob],wanted_row[ob],ob->Name(WER),ob);
+  }
+}
+
+varargs int ShowTeamHP(string arg) {
+  object *tmembers,ob;
+  closure qp;
+  int i,longinf;
+  mixed *vals,*res,cols,fr,rr,termstr;
+  mapping real_row;
+  string nm,inf;
+
+  if (arg && arg[0..3]=="lang") {
+    if (TP!=leader)
+      return notify_fail("Nur der Teamleiter kann die lange "+
+                         "Uebersicht aufrufen.\n"),0;
+    longinf=1;
+    arg=arg[5..];
+  } else
+    longinf=0;
+  real_row=PresentPositions(environment(TP));
+  tmembers=({});
+  for (i=0;i<MAX_TEAMROWS;i++)
+    tmembers+=rows[i];
+  res=({});
+  switch(TP->QueryProp(P_TTY)) {
+  case "ansi":
+    termstr=({ANSI_RED+ANSI_BOLD,ANSI_YELLOW,ANSI_GREEN,ANSI_NORMAL,
+              ANSI_UNDERL});
+    break;
+  case "vt100":
+    termstr=({ANSI_BOLD,"","",ANSI_NORMAL,ANSI_UNDERL});
+    break;
+  default:
+    termstr=({"","","","",""});
+  }
+  vals=({"",0,0,termstr[3],"",0,0,termstr[3]});
+
+  printf("  Name        Gilde           LV GLV  LP (MLP)  KP (MKP) Vors. GR AR TR FR A V\n");
+  if (longinf)
+    printf("  (Zeile 2)   Angriffsbefehl                             Fluchtrichtung\n");
+
+  for (i=sizeof(tmembers)-1;i>=0;i--) {
+    if (!objectp(ob=tmembers[i])) continue;
+    qp=symbol_function("QueryProp",ob);
+    fr=GetHpInfo(ob,qp);
+    vals[1]=fr[0];vals[2]=fr[1];vals[5]=fr[2];vals[6]=fr[3];
+    /*
+    vals[1]=funcall(qp,P_HP);vals[2]=funcall(qp,P_MAX_HP);
+    vals[5]=funcall(qp,P_SP);vals[6]=funcall(qp,P_MAX_SP);
+    */
+    if (!pointerp(cols=funcall(qp,P_TEAM_COLORS)) || sizeof(cols)<4)
+      cols=({vals[2]/4,vals[2]/2,vals[6]/4,vals[6]/2});
+    if (vals[1]<cols[0])
+      vals[0]=termstr[0];
+    else if (vals[1]<cols[1])
+      vals[0]=termstr[1];
+    else
+      vals[0]=termstr[2];
+    if (vals[5]<cols[2])
+      vals[4]=termstr[0];
+    else if (vals[5]<cols[3])
+      vals[4]=termstr[1];
+    else
+      vals[4]=termstr[2];
+    if (intp(fr=wimpy_row[ob]) && fr>1) fr=sprintf("%2d",fr); else fr="--";
+    if (intp(rr=real_row[ob]) && rr>0)  rr=sprintf("%2d",rr); else rr="--";
+    nm=ob->Name(RAW);
+    inf=sprintf("%s %-11s%s %-14s %3d %3d %s%3d (%3d)%s %s%3d (%3d)%s %5d %2d %2d %2s %2s %1s %1s\n",
+               ((ob==leader)?(termstr[4]+"*"):" "),
+               nm[0..10],termstr[3],
+               capitalize(funcall(qp,P_GUILD)||"")[0..13],
+               funcall(qp,P_LEVEL),
+               funcall(qp,P_GUILD_LEVEL),
+               vals[0],vals[1],vals[2],vals[3],
+               vals[4],vals[5],vals[6],vals[7],
+               funcall(qp,P_WIMPY),
+               wanted_row[ob],act_row[ob],rr,fr,
+               (attack_cmd[ob]?"X":"-"),
+               (autofollow[ob]?"X":"-"));
+    if (longinf) {
+      if (!stringp(fr=funcall(qp,P_WIMPY_DIRECTION))) fr="";
+      if (!stringp(rr=attack_cmd[ob])) rr="";
+      if (fr!="" || rr!="")
+        inf+=sprintf("              %-42s %-21s\n",rr[0..41],fr[0..20]);
+    }
+
+    switch (arg) {
+    case "alphabetisch":
+      res+=({({(query_once_interactive(ob)?"0":"1")+nm,inf})});
+      break;
+    case "sortiert":
+      res+=({({sprintf("%2s %2d %2d %s",rr,act_row[ob],wanted_row[ob],nm),
+                 inf})});
+      break;
+    default:
+      res+=({({i,inf})});
+    }
+  }
+  if (arg && arg!="")
+    res=sort_array(res,"CmpFirstArrayElement",ME);
+  for (i=sizeof(res)-1;i>=0;i--)
+    write(res[i][1]);
+  return 1;
+}
+
+varargs int ShowTeamRooms(string arg) {
+  object *tmembers,ob;
+  string s1,s2;
+  mixed *res;
+  int i;
+
+  tmembers=Members();res=({});
+  for (i=sizeof(tmembers)-1;i>=0;i--) {
+    if (!objectp(ob=tmembers[i])) continue;
+    if (!query_once_interactive(ob) && arg!="alle") continue;
+    s1=ob->Name(RAW);
+    if (!objectp(ob=environment(ob))) continue;
+    if (!stringp(s2=ob->QueryProp(P_INT_SHORT))) s2="";
+    res+=({({s1,s2})});
+  }
+  res=sort_array(res,"CmpFirstArrayElement",ME);
+  for (i=sizeof(res)-1;i>=0;i--)
+    printf("%-11s %-66s\n",res[i][0][0..10],res[i][1][0..65]);
+  return 1;
+}
+
+int ChangeColors(string arg) {
+  int *col;
+
+  notify_fail("team farben lp_rot lp_gelb [kp_rot kp_gelb]\n");
+  if (!arg)
+    return 0;
+  col=({0,0,0,0});
+  if (sscanf(arg,"%d %d %d %d",col[0],col[1],col[2],col[3])!=4) {
+    if (sscanf(arg,"%d %d",col[0],col[1])!=2)
+      return 0;
+    col[2]=col[0];col[3]=col[1];
+  }
+  printf("Die Anzeige ist jetzt gelb unter %d LP, rot unter %d LP\n"+
+         "                 bzw. gelb unter %d KP, rot unter %d KP.\n",
+         col[1],col[0],col[3],col[2]);
+  TP->SetProp(P_TEAM_COLORS,col);
+  TP->Set(P_TEAM_COLORS,SAVE,F_MODE_AS);
+  return 1;
+}
+
+int ChangeAutoInfo(string arg) {
+  string *words,txt;
+  int i,fl;
+
+  if (TP!=leader)
+    return notify_fail("Nur der Teamleiter kann automatisch "+
+                       "informiert werden.\n"),0;
+  words=old_explode(arg?arg:""," ");fl=0;
+  for (i=sizeof(words)-1;i>=0;i--) {
+    switch(words[i]) {
+    case "aus":
+      write("Du wirst nicht mehr automatisch informiert.\n");
+      autoinf_flags=0;
+      return 1;
+    case "+kp":
+      fl|=AUTOINF_SP_PLUS;
+    case "kp":
+      fl|=AUTOINF_SP_MINUS;
+      break;
+    case "+lp":
+      fl|=AUTOINF_HP_PLUS;
+    case "lp":
+    case "ein":
+    case "an":
+      fl|=AUTOINF_HP_MINUS;
+      break;
+    case "sofort":
+      fl|=AUTOINF_INSTANT;
+      break;
+    default:
+      ;
+    }
+  }
+  if (!fl)
+    return notify_fail("WIE moechtest Du automatisch informiert werden?\n"),0;
+  if (fl==AUTOINF_INSTANT) fl|=AUTOINF_HP_MINUS;
+  autoinf_flags=fl;
+  txt="Du wirst"+((fl&AUTOINF_INSTANT)?" sofort ":" ")+"informiert, wenn";
+  if (fl&(AUTOINF_HP_PLUS|AUTOINF_HP_MINUS)) {
+    txt+=" die Lebenspunkte eines Teammitglieds";
+    if (fl&(AUTOINF_HP_PLUS)) txt+=" sich aendern"; else txt+=" fallen";
+    if (fl&(AUTOINF_SP_PLUS|AUTOINF_SP_MINUS)) txt+=" oder";
+  }
+  if (fl&(AUTOINF_SP_PLUS|AUTOINF_SP_MINUS)) {
+    txt+=" die Konzentrationspunkte";
+    if (fl&(AUTOINF_SP_PLUS)) txt+=" sich aendern"; else txt+=" fallen";
+  }
+  write(break_string(txt+".\n",78));
+  return 1;
+}
+
+private void DoNotifyHpChange() {
+  object *obs,ob;
+  string str;
+  int i;
+
+  autoinf_time=time();
+  str="";
+  obs=m_indices(autoinf_hp);
+  for (i=sizeof(obs)-1;i>=0;i--) {
+    if (!objectp(ob=obs[i])) continue;
+    if (str!="") str+=", ";
+    str+=sprintf("%s: %d LP",ob->name(WER),autoinf_hp[ob]);
+    if (member(autoinf_sp,ob))
+      str+=sprintf(" / %d KP",autoinf_sp[ob]);
+    m_delete(autoinf_sp,ob);
+  }
+  obs=m_indices(autoinf_sp);
+  for (i=sizeof(obs)-1;i>=0;i--) {
+    if (!objectp(ob=obs[i])) continue;
+    if (str!="") str+=", ";
+    str+=sprintf("%s: %d KP",ob->name(WER),autoinf_sp[ob]);
+  }
+
+  if (str!="" && IsMember(leader))
+    tell_object(leader,break_string(capitalize(str)+"\n",78));
+  autoinf_hp=([]);
+  autoinf_sp=([]);
+}
+
+void NotifyHpChange() {
+  mixed act,old;
+  int change;
+
+  if (!IsMember(PO) || !pointerp(act=hp_info[PO]))
+    return;
+  old=act[0..];
+  act=GetHpInfo(PO);change=0;
+  if (!autoinf_flags) return;
+  if (((autoinf_flags&AUTOINF_HP_MINUS) && act[0]<old[0]) ||
+      ((autoinf_flags&AUTOINF_HP_PLUS)  && act[0]>old[0]))
+    autoinf_hp[PO]=act[0],change=1;
+  if (((autoinf_flags&AUTOINF_SP_MINUS) && act[2]<old[2]) ||
+      ((autoinf_flags&AUTOINF_SP_PLUS)  && act[2]>old[2]))
+    autoinf_sp[PO]=act[2],change=1;
+
+  if (autoinf_time<time() || (change && (autoinf_flags&AUTOINF_INSTANT)))
+    DoNotifyHpChange();
+}
+
+int TeamCmd(string cmd, string arg) {
+  if (!IsMember(TP)) {
+    notify_fail("Du bist kein Teammitglied.\n");
+    if (TP->QueryProp(P_TEAM)==ME)
+      TP->SetProp(P_TEAM,0);
+    return 0;
+  }
+  switch(cmd) {
+  case "angriff":
+    return StartAttack();
+  case "angriffsbefehl":
+    if (stringp(arg))
+      attack_cmd[TP]=arg;
+    else
+      m_delete(attack_cmd,arg);
+    return 1;
+  case "autofolge":
+  case "autof":
+    if (arg=="ein" || arg=="an")
+      autofollow[TP]=1;
+    else
+      m_delete(autofollow,TP);
+    return 1;
+  case "autoi":
+  case "autoinf":
+  case "autoinfo":
+  case "autoinform":
+    return ChangeAutoInfo(arg);
+  case "entlasse":
+    return RemoveMember(arg);
+  case "farben":
+    return ChangeColors(arg);
+  case "fluchtreihe":
+  case "flucht":
+    return ChangeWimpyRow(arg);
+  case "formation":
+    if (TP!=leader)
+      return notify_fail("Nur der Teamleiter kann die Formation aendern.\n"),0;
+    return ChangeFormation(arg);
+  case "hist":
+  case "history":
+    return Hist(arg);
+  case "":
+  case "info":
+    return ShowTeamHP(arg);
+  case "leiter":
+  case "leiterin":
+  case "leitung":
+    return ChangeLeader(arg);
+  case "name":
+    return ChangeName(arg);
+  case "orte":
+    return ShowTeamRooms(arg);
+  case "kampfreihe":
+  case "reihe":
+    return ChangeRow(arg);
+  case "ruf":
+  case "rufe":
+    return Shout(arg);
+  case "verlasse":
+    TP->SetProp(P_TEAM,0);
+    return RemoveMember(TP);
+  default:;
+  }
+  return 0;
+}
+
+void reset() {
+  RemoveSingles();
+  TryRemove();
+}
