#pragma strong_types,save_types
#pragma no_shadow
// Teamobjekt muss leider noch geerbt werden koennen.
// Arathorn, 2021-03-28
//#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,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;

  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) {
  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();
}
