// MorgenGrauen MUDlib
//
// explorationmaster.c -- Verwaltung der ExplorationPoints (FP)
//
// $Id: explorationmaster.c 9569 2016-06-05 21:28:23Z Zesstra $
//
#pragma strict_types,rtt_checks
#pragma no_clone,no_shadow,no_inherit
//#pragma pedantic
//#pragma range_check
#pragma warn_deprecated

#define BY_EP "/secure/ARCH/EPSTAT_BY_EP"
#define BY_PL "/secure/ARCH/EPSTAT_BY_PL"
#define BY_PN "/secure/ARCH/EPSTAT_BY_PN"
#define AVGLOG "/secure/ARCH/EPSTAT_AVG"

inherit "/std/util/pl_iterator";

#include <config.h>
#include <wizlevels.h>
#include <userinfo.h>
#include <exploration.h>
#include <properties.h>
#include <new_skills.h>

#define DOMAIN_INFO 1

#include <living/comm.h>
#define ZDEBUG(x) if (find_player("zesstra")) \
  find_player("zesstra")->ReceiveMsg(x,MT_DEBUG,0,object_name()+":",this_object())
//#define ZDEBUG(x)

// Struktur: ([ string filename : string* action, int number, int type ]) 
private mapping obs;
private int epcount;  // Anzahl FP
private int epavg;    // Durchschnittliche FP/Spieler
// Bitstrings fuer normale (alloc) und Bonus-FP (bonus)
private string alloc,bonus;

private nosave string vc_ob;
private nosave string output;

private nosave int changed;
private nosave int dumping;
private nosave mapping dumpMap, lastfound, querytime;

private nosave int stat_done;

protected void create()
{
  seteuid(getuid(this_object()));
  if (!restore_object(EPSAVEFILE)) {
    obs = ([]);
    epcount = epavg = 0;
    alloc = " ";
    bonus = " ";
    save_object(EPSAVEFILE);
  }
  if (!bonus) bonus=" ";
  lastfound=([]);
  querytime=([]);
}

public varargs int remove(int silent)
{
  save_object(EPSAVEFILE);
  destruct(this_object());
  return 1;
}

// Statistik erstellen
private int SetAverage(int newavg)
{
  if (epavg != newavg)
  {
    epavg = newavg;
    write_file(AVGLOG, sprintf("%s : %d\n",dtime(time()),newavg));
    save_object(EPSAVEFILE);
  }
  return epavg;
}

private void check_player(string pl, mixed extra)
{
  int *fp_found = extra[0];
  mapping plstat = extra[1];
  mapping pnstat = extra[2];
  object pldata = extra[3];
  if (!pldata)
  {
    pldata=clone_object("/obj/playerdata");
    extra[3]=pldata;
  }
  // Letzte Loginzeit ermitteln, wenn laenger als 90 Tage her und nicht
  // eingeloggt, wird der Spieler uebersprungen.
  // Der playerdata hat als UID unsere eigene, weil wir ihn geclont haben.
  // Damit darf er alle Spielersavefiles lesen...
  pldata->ReleasePlayer();
  (int)pldata->LoadPlayer(pl);
  // Testspieler ausnehmen, Spieler, die 90 Tage nicht da waren.
  if ( ((int)pldata->QueryProp(P_LAST_LOGIN) < time() - 7776000
        && !find_player(pl))
      || (mixed)pldata->QueryProp(P_TESTPLAYER))
    return;
  // Wenn kein SPieler/Seher, sondern Magier: auch ueberspringen
  mixed* uinfo = (mixed*)master()->get_userinfo(pl);
  if (uinfo[USER_LEVEL+1] >= LEARNER_LVL)
    return;

  string eps=(string)master()->query_ep(pl) || "";
  int p=-1;
  int count, avgcount;
  while ((p=next_bit(eps,p)) != -1)
  {
    if (p<sizeof(fp_found))
    {
      ++count;
      ++fp_found[p];
      // es tragen nur normale EPs zum Durchschnitt bei
      if (!test_bit(bonus,p))
        ++avgcount;
    }
  }

  // Spieler mit weniger als MIN_EP ignorieren.
  if (avgcount >= MIN_EP)
  {
    extra[4] += avgcount;   // Summe der gefundenen FP
    ++extra[5];          // Anzahl beruecksichtigter Spieler
  }
  plstat += ([ pl : count ]);
  if (!member(pnstat, count))
    pnstat += ([ count : ({ pl }) ]);
  else
    pnstat[count] = ({ pl })+pnstat[count];
}

// Mit allen Spielern fertig, aufraeumen.
#define BAR "************************************************************"
private void plcheck_finished(mixed extra)
{
  ZDEBUG("plcheck_finished entry\n");
  if (get_eval_cost() < 1000000)
  {
    call_out(#'plcheck_finished, 4+random(6), extra);
    return;
  }

  int *fp_found = extra[0];
  mapping plstat = extra[1];
  mapping pnstat = extra[2];
  object pldata = extra[3];
  int avgcount = extra[4];
  int avgspieler = extra[5];

  if (objectp(pldata))
    pldata->remove(1);

  if (file_size(BY_EP) >= 0)
    rm(BY_EP);
  if (file_size(BY_PL) >= 0)
    rm(BY_PL);
  if (file_size(BY_PN) >= 0)
    rm(BY_PN);

  // Neuen Durchschnittswert fuer gefundene FP setzen.
  if (avgspieler)
  {
    SetAverage(to_int(avgcount/avgspieler));
  }

  // Histogramm ueber alle FP schreiben: wie oft wurde jeder gefunden?
  int maxval = max(fp_found);
  int fp_index;
  foreach(int found : fp_found)
  {
    write_file(BY_EP, sprintf("%5d:%5d %s\n", fp_index, found,
               BAR[0..(60*found)/maxval]));
    ++fp_index;
  }
  // sortierte Liste der Spieler (sortiert nach gefundenen FP) erzeugen
  foreach(int fp : sort_array(m_indices(pnstat),#'<) )
  {
    foreach(string pl : pnstat[fp])
      write_file(BY_PN, sprintf("%-14s: %5d\n", pl, fp));
  }
  // alphabetisch sortierte Liste der Spieler erzeugen
  foreach(string pl : sort_array(m_indices(plstat),#'>) )
  {
    write_file(BY_PL, sprintf("%-14s: %5d\n", pl, plstat[pl]));
  }
}
#undef BAR

private void make_stat()
{
  stat_done = time();
  // Leider laesst sich epcount nicht nutzen Beim Loeschen von FP wird
  // <epcount> dekrementiert, so dass hier nicht mehr alle FPs ausgewertet
  // werden. Daher muss stattdessen bis zur Gesamtgroesse von <obs> gezaehlt
  // werden.
  int* fp_found = allocate(sizeof(obs));
  mapping plstat = m_allocate(500);
  mapping pnstat = m_allocate(500);
  start_player_check(#'check_player, #'plcheck_finished, 1200000,
                     ({fp_found,plstat,pnstat,
                       0, 0, 0}) );
}

void reset()
{
  if (changed && !dumping)
  {
    catch(rm(DUMPFILE);publish);
    dumping = 1;
    call_out("dumpEPObjects", 0, sort_array(m_indices(obs),#'> /*'*/));
    changed = 0;
  }
  // nur einmal am tag statistiken erstellen
  if (time()%86400 < 4000
      && stat_done < time()-80000)
    make_stat();
}

private string strArr(string *s)
{
  string ret;
  int i;

  ret = ("\""+s[<1]+"\"");
  for (i=sizeof(s)-2; i>=0; i--)
    ret += (", \""+s[i]+"\"");

  return ret;
}

static void dumpEPObjects(string *doit)
{
  string *toGo, id;
  int i,j;

  if (!mappingp(dumpMap))
    dumpMap = ([]);

  toGo = 0;
  if (sizeof(doit) > 200) {
    toGo = doit[200..];
    doit = doit[0..199];
  }

  j = sizeof(doit);

  for (i=0; i<j; i++) {
    id = (string)master()->creator_file(doit[i]);
    if (member(dumpMap, id))
      dumpMap[id] += ({ doit[i] });
    else
      dumpMap += ([ id : ({ doit[i] }) ]);
  }
  if (toGo)
    call_out("dumpEPObjects", 1, toGo);
  else {
    int step;

    step = 0;
    id = "";
    toGo = sort_array(m_indices(dumpMap),#'> /*'*/ );
    for (i=0, j=sizeof(toGo); i<j; i++) {
      int k,l;
      doit = dumpMap[toGo[i]];
      id += sprintf("### %s %s\n", toGo[i], "#########################"[sizeof(toGo[i])..]);
      for (k=0, l=sizeof(doit); k<l; k++) {
        id += sprintf("%s %4d %s %s.c ({ %s })\n",
                      EP_TYPES[obs[doit[k], MPOS_TYPE]],
                      obs[doit[k], MPOS_NUM],
                      test_bit(bonus,obs[doit[k], MPOS_NUM])?"b":"n",
                      doit[k],
                      strArr(obs[doit[k]]));
        if (!(++step % 50)) {
          write_file(DUMPFILE, id);
          id = "";
        }
      }
      id += "\n";
    }
    write_file(DUMPFILE,id);
    if (dumping == 2)
      write("Fertig! Anfrage bitte wiederholen.\n");
    dumping = 0;
    changed = 0;
    dumpMap = 0;
  }
}

private string validOb(mixed ob)
{
  string fn, fpart;

  if (!objectp(ob))
    return 0;

  fn = old_explode(object_name(ob),"#")[0];
  fpart = old_explode(fn,"/")[<1];
 /*
  if (query_once_interactive(ob))
    return 0;

  if ((file_size(fn+".c") <= 0) &&
      this_player() &&
      (strstr(fpart, getuid(this_player())) >= 0))
    return 0;
 */
  return fn;
}

private int allowed()
{
  if (previous_object() && geteuid(previous_object())==ROOTID)
    return 1;
  if ( !process_call() && previous_object() && this_interactive()
        && ARCH_SECURITY )
    return 1;

  return 0;
}

nomask varargs int AddEPObject(object ob, mixed keys, int type, int bonusflag)
{
  string fn;

  if (!allowed())
    return EPERR_NOT_ARCH;

  if (!(fn = validOb(ob)))
    return EPERR_INVALID_OB;

  if (stringp(keys))
    keys = ({ keys });

  if (member(obs, fn)) {
    if (type == obs[fn, MPOS_TYPE])
      obs[fn] = keys;
    else
      obs += ([ fn : keys; obs[fn, MPOS_NUM]; type ]);
    if (bonusflag) bonus = set_bit(bonus, obs[fn, MPOS_NUM]);
       else bonus = clear_bit(bonus, obs[fn, MPOS_NUM]);
  }
  else {
    int nr, i;

    nr = 0;
    while (test_bit(alloc,nr))
      nr++;

    obs += ([ fn : keys; nr; type ]);
    ++epcount;
    alloc = set_bit(alloc,nr);
    if (bonusflag) bonus = set_bit(bonus,nr);
       else bonus = clear_bit(bonus,nr);
  }

  changed = 1;
  save_object(EPSAVEFILE);
  return epcount;
}

nomask int RemoveEPObject(string|object ob)
{
  string fn;

  if (!allowed())
    return EPERR_NOT_ARCH;
  
  if (objectp(ob))
    ob=object_name(ob);

  fn = explode(ob,"#")[0];
  if (!member(obs,fn))
    return EPERR_NO_ENTRY;

  alloc = clear_bit(alloc, obs[fn, MPOS_NUM]);
  bonus = clear_bit(bonus, obs[fn, MPOS_NUM]);

  m_delete(obs, fn);

  changed = 1;
  --epcount;
  save_object(EPSAVEFILE);
  return epcount;
}

nomask int ChangeEPObject(object ob, int what, mixed new)
{
  string fn, fn2;
  mapping entry;

  if (!allowed())
    return EPERR_NOT_ARCH;

  if (!(fn = validOb(ob)))
    return EPERR_INVALID_OB;

  if (!member(obs,fn))
    return EPERR_NO_ENTRY;

  switch(what) {
  case CHANGE_OB:
    if (!(fn2 = validOb(new)))
      return EPERR_INVALID_ARG;
    entry = ([ fn2: obs[fn]; obs[fn,MPOS_NUM]; obs[fn,MPOS_TYPE] ]);
    obs = m_copy_delete(obs, fn);
    obs += entry;
    break;
  case CHANGE_BONUS:
    if (!(intp(new)))
      return EPERR_INVALID_ARG;
    if (new) bonus=set_bit(bonus,obs[fn,MPOS_NUM]);
       else bonus=clear_bit(bonus,obs[fn,MPOS_NUM]);
    break;
  case CHANGE_KEY:
    if (!stringp(new) && !pointerp(new))
      return EPERR_INVALID_ARG;
       
    if (stringp(new))
      new = ({ new });

    obs[fn] = new;
    break;
  case CHANGE_TYPE:
    if (!intp(new) || new < 0 || new > EP_MAX)
      return EPERR_INVALID_ARG;

    obs[fn, MPOS_TYPE] = new;
    break;
  default:
    return EPERR_INVALID_ARG;
  }
  changed = 1;
  save_object(EPSAVEFILE);
  return 1;
}

nomask mixed QueryEPObject(object ob)
{
  string fn;

  if (!allowed())
    return EPERR_NOT_ARCH;

  if (!(fn = validOb(ob)))
    return EPERR_INVALID_OB;

  if (!member(obs, fn))
    return 0;

  return ({ obs[fn], obs[fn,MPOS_NUM], obs[fn, MPOS_TYPE], test_bit(bonus,obs[fn, MPOS_NUM]) });
}

private string getMatch(string m)
{
  string *res;
  int i;

  res = regexp(sort_array(m_indices(obs), #'> /*'*/), m);
  for (i=sizeof(res)-1; i>=0; i--)
    res[i] = sprintf("%s %s %s.c ({ %s })",
                     EP_TYPES[obs[res[i], MPOS_TYPE]],
                     test_bit(bonus,obs[res[i], MPOS_NUM])?"b":"n",
                     res[i],
                     strArr(obs[res[i]]));
  return implode(res, "\n");
}

private string getMatchArch(string m)
{
  string *res;
  int i;

  res = regexp(sort_array(m_indices(obs), #'> /*'*/), m);
  for (i=sizeof(res)-1; i>=0; i--)
    res[i] = sprintf("%s %4d %s %s.c ({ %s })",
                     EP_TYPES[obs[res[i], MPOS_TYPE]],
                     obs[res[i], MPOS_NUM],
                     test_bit(bonus,obs[res[i], MPOS_NUM])?"b":"n",
                     res[i],
                     strArr(obs[res[i]]));
  return implode(res, "\n");
}

/*
 *  Anleitung fuer >=EMs:
 *    ShowEPObjects() zeigt das gesamte Dumpfile an
 *    ShowEPObjects("dump") erzeugt ein neues Dumpfile
 *    ShowEPObjects("string") liefert alle EPs, die "/string/"
 *                            im Filenamen enthalten
 *    ShowEPObjects("string1","string2") liefert alle EPs, die
 *                            "/string1/string2/" im Filenamen enthalten
 *  Anleitung fuer RMs:
 *    ShowEPObjects() liefert all Deine EPs
 *    ShowEPObjects("domainname") liefert Deine EPs in Deiner Domanin
 *    ShowEPObjects("domainname","magiername") liefert die EPs des
 *                                Mitarbeiters in Deiner Region
 *
 *  Anleitung fuer <RMs:
 *    ShowEPObjects() liefert Deine EPs
 *
 *  Alle EPObjects einer ganzen Domain kann man nicht mehr auf einmal
 *  ziehen und sollte man auch nicht. Alle Zugriffe auf diese Funktion
 *  werden geloggt. Auch die der EMs!
 *
 *                                             Rikus
 */

nomask varargs void ShowEPObjects(string what, string magname)
{
  if (allowed()) {
    if (what == "dump") {
      if (!dumping) {
        dumping = 2;
        catch(rm(DUMPFILE);publish);
        call_out("dumpEPObjects", 0, sort_array(m_indices(obs),#'>/*'*/));
      }
      printf("Liste wird erstellt und in '%s' abgelegt!\n", DUMPFILE);
      return;
    }
    if (!what || what == "") {
      this_interactive()->More(DUMPFILE, 1);
      log_file("ARCH/EPZugriffe", ctime(time())+": "+
        capitalize(getuid(this_interactive()))+" schaute sich das DUMPFILE an.\n");
      return;
    }
    what="/"+what+"/";
    if (magname) what+=magname+"/";
  }
  else
#ifdef DOMAIN_INFO
    if (IS_LORD(this_interactive())) {
      if (!what || what == "")
       what = "/"+getuid(this_interactive())+"/";
      else {
       if (!master()->domain_master(getuid(this_interactive()), what)) {
         write("Sorry, Du kannst nur Objekte in Deiner eigenen Region abfragen!\n");
         return;
       }
       if (!magname || magname=="")
         magname = getuid(this_interactive());
//        if (!master()->domain_member(magname, what)) {
//         write(capitalize(magname)+" ist gar kein Mitarbeiter in Deiner Region!\n");
//          return;
//       }
       what = "/d/"+what+"/"+magname+"/";
      }
    }
    else
#endif
      {
       if (!what || what == "")
         what = getuid(this_interactive());
       else if (what != getuid(this_interactive())) {
         write("Sorry, Du kannst nur Deine eigenen Objekte abfragen!\n");
         return;
       }
       what="/"+what+"/";
      }
  if (allowed())
    this_interactive()->More(getMatchArch(what));
  else
    this_interactive()->More(getMatch(what));
  log_file("ARCH/EPZugriffe", ctime(time())+": "+
    capitalize(getuid(this_interactive()))+" schaute sich "+what+" an.\n");
  return;
}

nomask void PrepareVCQuery(string file)
{
  string path, *parts;

  vc_ob = 0;

  if (!previous_object() || !stringp(file))
    return;

  parts = explode(object_name(previous_object()),"/");

  if (parts[<1] == "virtual_compiler") {
    path = implode(parts[0..<2]+({ file }), "/");
    if (file_size(path+".c") < 0)
      vc_ob = path;
  }
}

nomask mixed *QueryExplore()
{
  string fn;

  if (!previous_object())
    return 0;

  if (!member(obs, fn = old_explode(object_name(previous_object()),"#")[0]))
    if (!vc_ob || !member(obs, fn = vc_ob)) {
      vc_ob = 0;
      return 0;
    }

  vc_ob = 0;
  return ({ obs[fn, MPOS_TYPE], obs[fn] });
}

nomask int QueryMaxEP()
{
  return (epcount||1);
}

nomask int QueryAverage()
{
  return (epavg||1);
}

static int check_arch(object u)
{
   return query_wiz_level(u)>=ARCH_LVL;
}

private int check_to_fast(string name, string fn, int gesetzt)
{
    if (gesetzt) return 1; // Rikus, sonst arger scroll :)

    log_file(FP_LOG,sprintf("%s : %s : %s\n",name,fn,dtime(time())),500000);

    if ( !member( lastfound, name ) )
        lastfound += ([ name: time(); 1; ({ fn + "#*#" + dtime(time()) + "#*#" +gesetzt }) ]);
    else if ( time() <= lastfound[name, 0] + LF_TIME ){
        lastfound[name, 1]++;
        lastfound[name, 2] = ({ fn + "#*#" + dtime(time()) + "#*#" +gesetzt })
            + lastfound[name,2];
    }
    else {
        lastfound[name, 1] = 1;
        lastfound[name, 2] = ({ fn + "#*#" + dtime(time()) + "#*#" +gesetzt });
    }

    lastfound[name, 0] = time();

    if ( lastfound[name, 1] >= LF_WARN ){
        object *u;
        int i;
        string *tmp;

//        u = filter( users(), "check_arch" );
//        map( u, #'tell_object/*'*/, "**** FP-Liste/Script " +
//                   capitalize(name) + " (" + dtime(time()) + ") ****\n" );

        for ( i = sizeof(lastfound[name, 2]); i--; ){
            tmp = explode( lastfound[name, 2][i], "#*#" );
            log_file( LF_LOG, sprintf( "%s : %s : %s : %s\n",
                                         tmp[1], name, tmp[2], tmp[0] ), 500000 );
        }

        lastfound[name, 2] = ({});
    }
    return 1;
}

nomask int GiveExplorationPoint(string key)
{
  string fn;
  string ep;
  int gesetzt;

  if (!previous_object() || !this_interactive() || !this_player() ||
       this_player() != this_interactive() ||
       this_player()->QueryProp(P_KILLS) ||
       this_player()->QueryGuest()       )
    return 0;

  fn = old_explode(object_name(previous_object()), "#")[0];

  if (!member(obs, fn))
    return 0;

  if (member(obs[fn],key) < 0)
    return 0;

  ep = (MASTER->query_ep(getuid(this_interactive())) || "");

  gesetzt=test_bit(ep,obs[fn,1]);
  check_to_fast(getuid(this_player()),fn,gesetzt);
  if (gesetzt) return 0;
  
  catch(ep = set_bit(ep, obs[fn,1]));

  return (int)MASTER->update_ep(getuid(this_interactive()),ep);
}

nomask int GiveExplorationPointObject(string key, object ob)
{
  string fn;
  string ep;
  int gesetzt;
  
  if (!objectp(ob) || ob->QueryProp(P_KILLS ))
    return 0;

  fn = old_explode(object_name(previous_object()), "#")[0];

  if (!member(obs, fn))
    return 0;

  if (member(obs[fn],key) < 0)
    return 0;

  ep = (MASTER->query_ep(getuid(ob)) || "");

  gesetzt=test_bit(ep,obs[fn,1]);
  check_to_fast(getuid(this_player()),fn,gesetzt);
  if (gesetzt) return 0;

  catch(ep = set_bit(ep, obs[fn,1]));

  return (int)MASTER->update_ep(getuid(ob),ep);
}


private int QueryRealExplorationPoints(string pl)
{
  return count_bits(MASTER->query_ep(pl) || " ");
}

nomask int QueryExplorationPoints(mixed pl)
{
  mixed val;
  int ep;

  if (!stringp(pl)) pl=getuid(pl);
  ep=QueryRealExplorationPoints(pl);

  if (allowed() || !ep) return ep;

  val=querytime[pl];

  if (!pointerp(val) || sizeof(val)<2)
    val=({0,time()});

  if (time()>=val[1]) {
    val = ({ ep + random(6)-3, time()+300+random(300) });
    if (val[0]<0) val[0]=0;
    querytime+=([pl:val]);
  }
  return val[0];
}

private int remove_fp(int num, string pl)
{
  int i,j,k,t,maxEP;
  string ep;
  ep = (MASTER->query_ep(pl) || "");

  maxEP = QueryMaxEP();
  for( i=0; i<num; i++)
  {
    t = random(maxEP);
    for( j=0; j<maxEP; j++ ) {
      if( test_bit(ep, k=(t+j)%maxEP ) ) break;
    }
    if( j==maxEP ) break;
    ep = clear_bit(ep, k);
  }
  MASTER->update_ep(pl,ep);
  return i;
}

/* */

// quoted from /sys/mail.h
#define MSG_FROM 0
#define MSG_SENDER 1
#define MSG_RECIPIENT 2
#define MSG_CC 3
#define MSG_BCC 4
#define MSG_SUBJECT 5
#define MSG_DATE 6
#define MSG_ID 7
#define MSG_BODY 8

nomask int RemoveFP(int num, string pl, string grund)
{
  int i;
  string text;
  mixed* mail;

  if (!allowed()) return -1;
  if( num<0 ) return -3;
  if (!grund || grund=="") grund="<unbekannt>";
  if (!pl) return -2;
  i=remove_fp(num, pl);
  log_file("ARCH/fp_strafen", ctime(time())+": "
    +this_interactive()->Name(WER)+" loescht "+pl+" "+i
    +" FPs\nGrund:"+grund+"\n");
  if( i>0 ) {
     text =
     "Hallo "+capitalize(pl)+",\n\n"+
     break_string(
      this_interactive()->Name(WER)+" hat soeben veranlasst, dass Dir "+i
      +" FPs abgezogen wurden.\nGrund:"+grund+"\n", 78 );

     mail = allocate(9);
     mail[MSG_FROM] = getuid(this_interactive());
     mail[MSG_SENDER] = MUDNAME;
     mail[MSG_RECIPIENT] = pl;
     mail[MSG_CC]=0;
     mail[MSG_BCC]=0;
     mail[MSG_SUBJECT]="FP-Reduktion";
     mail[MSG_DATE]=dtime(time());
     mail[MSG_ID]=MUDNAME":"+time();
     mail[MSG_BODY]=text;

     "/secure/mailer"->DeliverMail(mail,1);
  }
  return i;
}
/* */

private int add_fp(int num, string pl)
{
  int i,j,k,t,maxEP;
  string ep;
  ep = (MASTER->query_ep(pl) || "");

  maxEP = QueryMaxEP();
  for( i=0; i<num; i++)
  {
    t = random(maxEP);
    for( j=0; j<maxEP; j++ ) {
      if( !test_bit(ep, k=(t+j)%maxEP ) ) break;
    }
    if( j==maxEP ) break;
    ep = set_bit(ep, k);
  }
  MASTER->update_ep(pl,ep);
  return i;
}

nomask int AddFP(int num, string pl)
{
  int i;
  if (!allowed()) return -1;
  if ( num<0 ) return -3;
  if (!pl) return -2;
  i=add_fp(num, pl);
  log_file("ARCH/fp_strafen", ctime(time())+": "
    +this_interactive()->Name(WER)+" gibt "+pl+" "+i
    +" FPs\n");

  return i;
}

nomask int SetFP(int num, string pl)
{
  int maxEP;
  string ep;
  if (!allowed()) return -1;
  if ( num<0 ) return -3;
  if (!pl) return -2;
  ep = (MASTER->query_ep(pl) || "");

  maxEP = QueryMaxEP();
  if (num<0 || num>=maxEP) return -4;
  ep = set_bit(ep, num);
  MASTER->update_ep(pl,ep);
  return num;
}

nomask int ClearFP(int num, string pl)
{
  int maxEP;
  string ep;
  if (!allowed()) return -1;
  if ( num<0 ) return -3;
  if (!pl) return -2;
  ep = (MASTER->query_ep(pl) || "");

  maxEP = QueryMaxEP();
  if (num<0 || num>=maxEP) return -4;
  ep = clear_bit(ep, num);
  MASTER->update_ep(pl,ep);
  return num;
}

private void printep( int nr, string key, int kind, string* det )
{
  output+=sprintf("%4d %s %s.c %s ({ %s })\n",nr,test_bit(bonus,nr)?"b":"n",key,EP_TYPES[kind],
                strArr(det));
}

nomask varargs int ShowPlayerEPs(string pl,string pattern)
{
  string ep,teststring;
  if (!allowed()) return -1;
  ep = (MASTER->query_ep(pl) || "");

  output="";
  if (!pattern || pattern=="")
    teststring="%s";
  else teststring="%s"+pattern+"%s";
  walk_mapping( obs, function void (string fn, string* v1, int v2, int v3)
      {
        string unused;
        if ( test_bit(ep, v2) && sscanf(fn, teststring, unused, unused) )
          printep(v2, fn, v3, v1);
      });
  this_interactive()->More(output);
  return 1;
}

// Hier kommen Funktionen fuer die Levelpunkte
// Funktion fuer Levelpunkte steht im LEPMASTER!

nomask int QueryLEP(int lep) {
    raise_error("Bitte QueryLEP() im LEPMASTER abfragen, nicht im "
       "EPMASTER!");
    return(-1); //never reached
}

string QueryForschung()
{
  int my;
  string ret;

  if ((my=QueryRealExplorationPoints(getuid(previous_object()))) < MIN_EP)
    return "Du kennst Dich im "MUDNAME" so gut wie gar nicht aus.\n";

  my *= 100;
  int absolute = my/QueryMaxEP();
  int relative = my/QueryAverage();

  ret = "Verglichen mit Deinen Mitspielern kennst Du Dich im "MUDNAME" ";
  switch(relative) {
  case 0..10:
    ret += "kaum";
    break;
  case 11..40:
    ret += "aeusserst schlecht";
    break;
  case 41..56:
    ret += "sehr schlecht";
    break;
  case 57..72:
    ret += "schlecht";
    break;
  case 73..93:
    ret += "unterdurchschnittlich";
    break;
  case 94..109:
    ret += "durchschnittlich gut";
    break;
  case 110..125:
    ret += "besser als der Durchschnitt";
    break;
  case 126..145:
    ret += "recht gut";
    break;
  case 146..170:
    ret += "ziemlich gut";
    break;
  case 171..210:
    ret += "gut";
    break;
  case 211..300:
    ret += "sehr gut";
    break;
  case 301..400:
    ret += "ausserordentlich gut";
    break;
  case 401..500:
    ret += "unheimlich gut";
    break;
  default:
    ret += "einfach hervorragend";
    break;
  }
  ret += " aus.\nAbsolut gesehen ";

  switch(absolute) {
  case 0..5:
    ret += "kennst Du nur wenig vom "MUDNAME".";
    break;
  case 6..10:
    ret += "solltest Du Dich vielleicht noch genauer umsehen.";
    break;
  case 11..17:
    ret += "bist Du durchaus schon herumgekommen.";
    break;
  case 18..25:
    ret += "hast Du schon einiges gesehen.";
    break;
  case 26..35:
    ret += "bist Du schon weit herumgekommen.";
    break;
  case 36..50:
    ret += "koenntest Du eigentlich einen Reisefuehrer herausbringen.";
    break;
  case 51..75:
    ret += "hast Du schon sehr viel gesehen.";
    break;
  default:
    ret += "besitzt Du eine hervorragende Ortskenntnis.";
  }
  return break_string(ret, 78, 0, 1);
}

// Nicht jeder Magier muss den EPMASTER entsorgen koennen.
string NotifyDestruct(object caller) {
  if( (caller!=this_object() && !ARCH_SECURITY) || process_call() )
  {
    return "Du darfst den Exploration Master nicht zerstoeren!\n";
  }
  return 0;
}

