#pragma strong_types,save_types
#pragma no_shadow
#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();
}
