#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>
#include <living/comm.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 object *autoinf_subscribers = ({});
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;

  // Eigentlich braeuchte man die nur fuer die SP-Benachrichtigungen, aber
  // dann wird alle viel komplizierter, weil man dann bei Aenderungen und
  // Teamleiterwechseln pruefen muss etc.
  if (!(TP->QueryProp(P_CAN_FLAGS) & CAN_REPORT_SP)) {
    TP->ReceiveMsg("Du musst zunaechst die Quest \"Hilf den "
        "Gnarfen\" bestehen, um diese Funktion nutzen zu koennen.",
        MT_NOTIFICATION|MSG_DONT_IGNORE);
    return 1;
  }
  if (TP!=leader)
  {
    switch(arg)
    {
      case "an":
      case "ein":
        if (!(TP in autoinf_subscribers))
            autoinf_subscribers += ({TP});
        TP->ReceiveMsg("Du erhaelst eine Kopie des Autoinform-Berichtes "
            "an den Teamleiter, falls bzw. sobald dieser einen solchen "
            "konfiguriert hat.",MT_NOTIFICATION|MSG_DONT_IGNORE);
        break;

      case "aus":
        autoinf_subscribers -= ({TP});
        TP->ReceiveMsg("Du erhaelst keine Kopie des Autoinform-Berichtes "
            "an den Teamleiter.",MT_NOTIFICATION|MSG_DONT_IGNORE);
        break;

      default:
        notify_fail("Nur der Teamleiter kann den Inhalt des "
                    "Autoinform-Berichts konfigurieren.\n");
        return 0;
    }
    return 1;
  }
  //else TP == leader
  words=old_explode(arg?arg:""," ");fl=0;
  for (i=sizeof(words)-1;i>=0;i--)
  {
    switch(words[i]) {
    case "aus":
      TP->ReceiveMsg(
        "Du und das Team werden nicht mehr automatisch informiert.",
        MT_NOTIFICATION|MSG_DONT_IGNORE);
      autoinf_flags=0;
      autoinf_subscribers -= ({TP});
      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;
    }
  }
  if (!fl) {
    notify_fail("WIE moechtest Du automatisch informiert werden?\n");
    return 0;
  }
  if (fl==AUTOINF_INSTANT) fl|=AUTOINF_HP_MINUS;
  autoinf_flags=fl;
  if (!(TP in autoinf_subscribers))
      autoinf_subscribers += ({TP});
  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";
  }
  TP->ReceiveMsg(txt+".", MT_NOTIFICATION|MSG_DONT_IGNORE);
  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]);
  }
  autoinf_hp=([]);
  autoinf_sp=([]);
  str = capitalize(str);
  // Und an alle Subscriber zustellen.
  foreach(object pl: autoinf_subscribers)
  {
    if (pl)
      pl->ReceiveMsg(str, MT_NOTIFICATION|MSG_DONT_IGNORE);
    else
      autoinf_subscribers -= ({0}); // bereinigen
  }
}

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