// MorgenGrauen MUDlib
//
// scoremaster.c - Verwaltung der eindeutigen Nummernvergabe fuer NPCs und
//       MiniQuests sowie der Stufenpunkte, die sie geben  
//
// $Id: scoremaster.c 9170 2015-03-05 20:18:54Z Zesstra $
#pragma strict_types
#pragma no_clone
#pragma no_shadow
#pragma no_inherit
#pragma verbose_errors
#pragma combine_strings
#pragma pedantic
//#pragma range_check
#pragma warn_deprecated

#include "/secure/scoremaster.h"
#include "/secure/wizlevels.h"
#include <properties.h>
#include <files.h>

#define ZDEBUG(x) if (find_player("zesstra")) \
  tell_object(find_player("zesstra"),sprintf("SCM: %s\n",x))

// hoechste vergebene Nr.
private int lastNum;

// Liste alle EKs: ([obname: num; score; killcount])
private mapping npcs = m_allocate(0,3);

// Liste von Spielernamen-Wert-Paaren, die im Reset abgearbeitet wird:
// ([plname: ({wert1, wert2, wert3, ...}) ]) 
// wert > 0 bedeutet setzen des entsprechenden EKs, < 0 bedeutet loeschen.
private mapping to_change = ([]);

// Liste der EK-Tips: ([obname: Spruch])
private mapping tipList = ([]);

// Bit-Nr., die (wieder) vergeben werden duerfen.
private int *free_num = ({});

// zu entfernende EKs, Liste Bitnummern, also ints
private int *to_be_removed = ({});

// Liste von temporaeren EKs, die noch nicht bestaetigt wurden:
// ([obname: ({plname1, plname2}) ])
private mapping unconfirmed_scores = ([]);

// alle Spieler kriegen diesen 
// Nach Nr. sortierte NPC-Liste: ([num: key; score])
private nosave mapping by_num = m_allocate(0,2);

// Cache fuer EKs von Spielern: ([plname: scoresumme])
private nosave mapping users_ek = ([]);

// bitstring, der alle aktiven EKs als gesetztes Bit enthaelt.
private nosave string active_eks="";

// Prototypen
public mapping getFreeEKsForPlayer(object player);
public int addTip(mixed key,string tip);
public int changeTip(mixed key,string tip);
public int removeTip(mixed key);
private string getTipFromList(mixed key);
public string getTip(mixed key);

public void CheckNPCs(int num);
public void check_all_player(mapping allplayer);
public varargs int DumpNPCs(int sortkey);

private void make_num(string key, int num, int score) {
  by_num += ([ num : key; score ]);
  // fuer aktive EKs, die also einen Scorewert > 0 haben, wird das jeweilige
  // Bit gesetzt. Wird spaeter zum Ausfiltern inaktiver EKs aus den Bitstrings
  // in den Spieler gebraucht.
  if (score>0 && !member(unconfirmed_scores,num))
    active_eks = set_bit(active_eks, num);
}

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

protected void create()
{
  seteuid(getuid());
  if (!restore_object(SCORESAVEFILE))
  {
    lastNum=0;
    npcs=m_allocate(0,3);
    to_change=m_allocate(0,1);
    tipList=([]);
  }
  npcs-=([0]);
  walk_mapping(npcs, #'make_num);
}

public int ClearUsersEKCache()
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  users_ek = ([]);
  return 1;
}

public mixed QueryUsersEKCache()
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  return users_ek;
}

public mixed Query_free_num()
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  return free_num;
}

public mixed Add_free_num(int what)
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!what || !intp(what) || by_num[what])
    return SCORE_INVALID_ARG;
  if (member(free_num,what)==-1)
    free_num+=({what});
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("ADDFREENUM: %s %5d (%s, %O)\n",     
  strftime("%d%m%Y-%T",time()),what,
  geteuid(previous_object()), this_interactive()));

  return free_num;
}

public mixed Remove_free_num(int what)
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!what || !intp(what))
    return SCORE_INVALID_ARG;
  free_num-=({what});
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("REMOVEFREENUM: %s %5d (%s, %O)\n",     
  strftime("%d%m%Y-%T",time()),what,
  geteuid(previous_object()),this_interactive()));
  return free_num;
}

public mixed Query_to_change(string who)
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!who)
    return to_change;
  if (who=="")
    return m_indices(to_change);
  return to_change[who];
}

public mixed Add_to_change(string who, int what)
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!who || !stringp(who) || !what || !intp(what))
    return SCORE_INVALID_ARG;
  if (member(to_change,who))
  {
    to_change[who]-=({-what});
    if (member(to_change[who],what)==-1)
      to_change[who]+=({what});
  }
  else
     to_change[who]=({what});
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("ADDTOCHANGE: %s %s %5d (%s, %O)\n",
         strftime("%d%m%Y-%T",time()),who,what,
         geteuid(previous_object()), this_interactive()));
  return to_change[who];
}

public mixed Remove_to_change(string who, int what)
{
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!who || !stringp(who) || !what || !intp(what))
    return SCORE_INVALID_ARG;
  if (member(to_change,who))
  {
     to_change[who]-=({what});
     if (!sizeof(to_change[who]))
        m_delete(to_change,who);
  }
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("REMOVETOCHANGE: %s %s %5d (%s, %O)\n",
         strftime("%d%m%Y-%T",time()),who,what,
         geteuid(previous_object()), this_interactive()));
  return to_change[who];
}

void reset()
{
  string *whop,who,ek;
  mixed what;
  int i,j,value,changed;

  // falls EKs global entfernt werden sollen, schonmal den noetigen Callout
  // starten.
  if (sizeof(to_be_removed) && find_call_out(#'check_all_player) == -1)
      call_out(#'check_all_player, 10, 0);
  // EK-Mainteiner ueber unbestaetigte EKs informieren
  if (sizeof(unconfirmed_scores)) {
    foreach(string n: SCOREMAINTAINERS) {
      if (objectp(find_player(n)))
          tell_object(find_player(n),break_string(
      "Es gibt unbestaetigte EKs im Scoremaster. Schau Dir die doch "
      "mal an. ;-)",78, "Der Scoremaster teilt Dir mit: "));
    }
  }

  i=sizeof(whop=m_indices(to_change))-1;
  while (i>=0 && get_eval_cost()>100000)
  {
    ek = ({string})(MASTER->query_ek(who=whop[i]) || "");
    for (j=sizeof(what=to_change[who])-1;j>=0;j--) {
      if ((value=what[j])>0) {
    // Vergabestatistik hochzaehlen.
    npcs[by_num[value,BYNUM_KEY],NPC_COUNT]++;
    ek=set_bit(ek,value);
      }
      else {
    // Vergabestatistik hochzaehlen.
    npcs[by_num[-value,BYNUM_KEY],NPC_COUNT]++;
    ek=clear_bit(ek,-value);
      }
      // if (find_player("rikus")) 
      //tell_object(find_player("rikus"),"SCOREMASTER "+who+" "+erg+"\n");

      write_file(SCOREAUTOLOG,
  sprintf("SET_CLEAR_BIT (reset): %s %4d %s\n",
    who, j, strftime("%d%m%Y-%T",time()) ));
    }
    MASTER->update_ek(who, ek);

    if (member(users_ek, who))
      m_delete(users_ek, who);
    
    m_delete(to_change,who);
    changed=1;
    i--;
  }
  if (changed) save_object(SCORESAVEFILE);
}

public varargs mixed QueryNPC(int score)
{
  string key;
  int val;

  if (!previous_object())
    return SCORE_INVALID_ARG;
  
  key = load_name(previous_object());

  // schon bekannter EK?
  if (member(npcs,key))
    return ({npcs[key,NPC_NUMBER],npcs[key,NPC_SCORE]});

  if (score<=0 || 
      member(inherit_list(previous_object()),"/std/living/life.c") < 0)
    return SCORE_INVALID_ARG;

  if (key[0..8]=="/players/") return SCORE_INVALID_ARG;

  if (score>2) score=2;

  if (sizeof(free_num)) {
      val = free_num[0];
      free_num -= ({val});
  }
  else val=++lastNum;

  npcs[key,NPC_SCORE] = score;
  npcs[key,NPC_NUMBER] = val;
  npcs[key,NPC_COUNT] = 0;
  by_num += ([val: key; score]);
  // werden noch nicht als aktive EKs gewertet, damit sie nicht als Ek-Tips
  // vergben werden.
  //active_eks = set_bit(active_eks, val);

  unconfirmed_scores += ([ val: ({}) ]);

  ClearUsersEKCache();
  save_object(SCORESAVEFILE);
  write_file(SCOREAUTOLOG,sprintf(
  "ADDNPC: %s %5d %4d %s (UID: %s, TI: %O, TP: %O)\n",
  strftime("%d%m%Y-%T",time()),val,score,key,
  getuid(previous_object()), this_interactive(), this_player()));

  while(remove_call_out("DumpNPCs") != -1) ;
  call_out("DumpNPCs",60);
  return ({val,score});
}

public varargs mixed NewNPC(string key,int score)
{
  int val;

  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!key || !stringp(key))
    return SCORE_INVALID_ARG;
  
  key = load_name(key);
  if (val=npcs[key,NPC_NUMBER])
    return ({val,npcs[key,NPC_SCORE]});
  if (score<=0)
    return SCORE_INVALID_ARG;

  if (sizeof(free_num)) {
      val=free_num[0];
      free_num=free_num[1..];
  }
  else val=++lastNum;

  npcs[key,NPC_SCORE] = score;
  npcs[key,NPC_NUMBER] = val;
  npcs[key,NPC_COUNT] = 0;
  by_num += ([val: key; score]);
  active_eks = set_bit(active_eks, val);

  ClearUsersEKCache();
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("NEWNPC: %s %5d %4d %s (%s, %O)\n",
         strftime("%d%m%Y-%T",time()),val,score,key,
         geteuid(previous_object()), this_interactive()));
 while(remove_call_out("DumpNPCs") != -1) ; 
  call_out("DumpNPCs",60);
  return ({val,score});
}

public varargs mixed AddNPC(string key,int score) { return NewNPC(key,score); }

// restauriert die Daten eines frueher geloeschten, in den Spielern noch
// enthaltenen EKs. Moeglich, wenn man Pfad, Nr. und Punkte noch kennt.
public int RestoreEK(string key, int bit, int score) {
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!stringp(key) || !sizeof(key) 
      || !intp(bit) || bit < 0
      || !intp(score) || score < 0)
      return SCORE_INVALID_ARG;

  if (member(npcs,key) || member(by_num,bit))
      return SCORE_INVALID_ARG;

  npcs += ([key: bit;score;0 ]);
  by_num += ([bit: key;score ]);

  ClearUsersEKCache();
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("RESTOREEK: %s %5d %4d %s (%s, %O)\n",
         strftime("%d%m%Y-%T",time()), bit, score, key,
         geteuid(previous_object()), this_interactive()));
  while(remove_call_out("DumpNPCs") != -1) ;
  call_out("DumpNPCs",60);
  return 1;

}

public int ConfirmScore(mixed key) {
  // Bits in den Spielern in unconfirmed_scores setzen und Statistik
  // hochzaehlen
  // Bit in active_eks setzen
  // Eintrag aus unconfirmed_scores loeschen
  int bit;

  if (!allowed()) return SCORE_NO_PERMISSION;
  if (stringp(key) && member(npcs,key)) {
      bit = npcs[key, NPC_NUMBER];
  }
  else if (intp(key) && member(by_num,key)) {
      bit = key;
  }
  else
      return SCORE_INVALID_ARG;

  if (!member(unconfirmed_scores, bit)) 
      return SCORE_INVALID_ARG;

  string obname = by_num[bit, BYNUM_KEY];
  int score = by_num[bit,BYNUM_SCORE];
  
  foreach(string pl: unconfirmed_scores[bit]) {
      string eks = (string)master()->query_ek(pl);
      eks = set_bit(eks, bit);
      master()->update_ek(pl, eks);
      write_file(SCOREAUTOLOG, sprintf(
    "SETBIT: %s %5d %s\n",
    strftime("%d%m%Y-%T",time()), bit, pl));
  }
  //Vergabestatistik hochzaehlen...
  npcs[obname,NPC_COUNT]+=sizeof(unconfirmed_scores[bit]);

  m_delete(unconfirmed_scores, bit);
  active_eks = set_bit(active_eks, bit);
  save_object(SCORESAVEFILE);

  write_file(SCORELOGFILE,sprintf(
      "CONFIRMNPC: %s %5d Score %3d %s [%s, %O]\n",
       strftime("%d%m%Y-%T",time()), bit, score, obname,
       getuid(previous_object()),this_interactive()));

  return 1;
}

public int RejectScore(mixed key) {
  // Eintrag aus unconfirmed_scores, npcs, by_num loeschen
  // Bit-Nr. in free_num eintragen
  // evtl. EK-Spruch entfernen?
  int bit;

  if (!allowed()) return SCORE_NO_PERMISSION;
  if (stringp(key) && member(npcs,key)) {
      bit = npcs[key, NPC_NUMBER];
  }
  else if (intp(key) && member(by_num,key)) {
      bit = key;
  }
  else
      return SCORE_INVALID_ARG;

  if (!member(unconfirmed_scores, bit)) 
      return SCORE_INVALID_ARG;

  string obname = by_num[bit, BYNUM_KEY];
  int score = by_num[bit,BYNUM_SCORE];

  m_delete(by_num, bit);
  m_delete(npcs, obname);
  m_delete(unconfirmed_scores,bit);
  removeTip(obname);
  free_num += ({bit});

  save_object(SCORESAVEFILE);

  write_file(SCORELOGFILE,sprintf(
      "REJECTNPC: %s %5d Score %3d %s [%s, %O]\n",
       strftime("%d%m%Y-%T",time()), bit, score, obname,
       getuid(previous_object()),this_interactive()));
  return 1;
}

// unbestaetigte NPCs in ein File ausgeben
public void DumpUnconfirmedScores() {
  if (!objectp(this_player())) return;
 
  write(sprintf("%5s  %5s  %4s   %s\n",
  "Nr.", "Cnt", "Sc", "Objekt"));
  foreach(int bit, string *pls: unconfirmed_scores) {
    write(sprintf("%5d  %5d  %4d   %s\n",
  bit, sizeof(pls), by_num[bit,BYNUM_SCORE], by_num[bit,BYNUM_KEY]));
  }
}

public mapping _query_unconfirmed() {
  if (allowed()) return unconfirmed_scores;
  return 0;
}

public varargs int SetScore(mixed key,int score)
{
  int num;
  string ob;
  int oldscore;

  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!key) return SCORE_INVALID_ARG;

  if (stringp(key) && sizeof(key)) {
    ob = load_name(key);
    if (!member(npcs, ob)) return SCORE_INVALID_ARG;
    num = npcs[ob, NPC_NUMBER];
    if (ob != by_num[num, BYNUM_KEY])
  return SCORE_INVALID_ARG;
  }
  else if (intp(key) && member(by_num,key) ) {
    num = key;
    ob = by_num[num, BYNUM_KEY];
    if (!member(npcs, ob) || (npcs[ob, NPC_NUMBER] != num))
  return SCORE_INVALID_ARG;
  }
  else
    return SCORE_INVALID_ARG;

  oldscore = by_num[num,BYNUM_SCORE];
  by_num[num,BYNUM_SCORE] = score;
  npcs[ob, NPC_SCORE] = score;

  if (score > 0)
      active_eks = set_bit(active_eks, num);
  else
      active_eks = clear_bit(active_eks, num);

  ClearUsersEKCache();
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf(
  "SETSCORE: %s %5d %.3d OSc: %.3d %s (%s, %O)\n",
         strftime("%d%m%Y-%T",time()),num,score,oldscore, ob,
         geteuid(previous_object()), this_interactive()));
 while(remove_call_out("DumpNPCs") != -1) ; 
  call_out("DumpNPCs",60);
  return 1;
}

// entfernt einen EK endgueltig und unwiderruflich und gibt die Nr. wieder
// frei.
// Technisch wird der EK erstmal in eine Liste eingetragen. Im Reset iteriert
// der Master ueber alle SPieler-Savefiles und loescht den Ek aus alle
// Spielern. Nach Abschluss wird der Eintrag in npcs geloescht und seine Nr.
// in die Liste freier Nummern eingetragen.
public int* MarkEKForLiquidation(mixed key) {
  int bit;
  if (!allowed())
      return 0;
  // nicht in to_be_removed aendern, wenn check_all_player() laeuft.
  if (find_call_out(#'check_all_player) != -1)
      return 0;

  if (stringp(key) && sizeof(key)) {
    if (!member(npcs,key)) return 0;
    bit = npcs[key,NPC_NUMBER];
  }
  else if (intp(key) && key>=0) {
    bit = key;
  }
  else
    return 0;

  if (member(to_be_removed,bit) == -1)
    to_be_removed += ({bit});
  write_file(SCORELOGFILE,sprintf("DELETEFLAG: %s %5d %s (%s, %O)\n",
  strftime("%d%m%Y-%T",time()), bit, by_num[bit,BYNUM_KEY] || "NoName",
  geteuid(previous_object()), this_interactive()));
  
  save_object(SCORESAVEFILE);
  
  return to_be_removed;
}

// geht nur, solange nach einem RemoveEK() noch kein reset() gelaufen ist!
public int* UnmarkEKForLiquidation(mixed key) {
  int bit;
  if (!allowed())
      return 0;
  // nicht in to_be_removed aendern, wenn check_all_player() laeuft.
  if (find_call_out(#'check_all_player) != -1)
      return 0;

  if (stringp(key) && sizeof(key)) {
    if (!member(npcs,key)) return 0;
    bit = npcs[key,NPC_NUMBER];
  }
  else if (intp(key) && key>=0) {
    bit = key;
  }
  else
    return 0;
 
  to_be_removed -= ({bit});
  write_file(SCORELOGFILE,sprintf("UNDELETEFLAG: %s %5d %s (%s, %O\n",
  strftime("%d%m%Y-%T",time()),bit, by_num[bit, BYNUM_KEY] || "NoName",
  geteuid(previous_object()), this_interactive()));
  
  save_object(SCORESAVEFILE);

  return to_be_removed;
}

public int* QueryLiquidationMarks() {
  if (allowed())
      return to_be_removed;
  else
      return 0;;
}

// setzt nur den Scorewert auf 0, sonst nix. Solche EKs koennen dann spaeter
// durch Angabe eines neues Scorewertes reaktiviert werden.
public int RemoveScore(mixed key) {
  int changed;
  int oldscore;

  if (!allowed())
    return SCORE_NO_PERMISSION;

  if (stringp(key) && member(npcs,key)) {
    int num = npcs[key, NPC_NUMBER];
    if ( key == by_num[num, BYNUM_KEY]) {
      oldscore = by_num[num, BYNUM_SCORE];
      npcs[key, NPC_SCORE] = 0;
      by_num[num, BYNUM_SCORE] = 0;
      active_eks = clear_bit(active_eks,num); 
      write_file(SCORELOGFILE,sprintf(
      "REMOVESCORE: %s %5d OSc: %.3d %s (%s, %O)\n",
        strftime("%d%m%Y-%T",time()), num, oldscore, key, 
        geteuid(previous_object()), this_interactive()));
      changed = 1;
    }
  }
  else if (intp(key) && member(by_num, key)) {
    string obname = by_num[key, BYNUM_KEY];
    if (key == npcs[obname, NPC_NUMBER]) {
      oldscore = by_num[key, BYNUM_SCORE];
      npcs[obname, NPC_SCORE] = 0;
      by_num[key, BYNUM_SCORE] = 0;
      active_eks = clear_bit(active_eks,key); 
      write_file(SCORELOGFILE,sprintf(
      "REMOVESCORE: %s %5d OSc: %.3d %s (%s, %O)\n",
        strftime("%d%m%Y-%T",time()),key, oldscore, obname,
        geteuid(previous_object()), this_interactive()));
      changed = 1;
    }
  }

  if (changed) {
    ClearUsersEKCache();
    save_object(SCORESAVEFILE);
    while(remove_call_out("DumpNPCs") != -1) ;
    call_out("DumpNPCs",60);
    return 1;
  }
  return SCORE_INVALID_ARG;
}

public varargs int MoveScore(mixed oldkey, string newpath)
{
  int num,score;
  string oldpath;
  string tip;
  
  if (!allowed())
    return SCORE_NO_PERMISSION;
  if (!stringp(newpath))
    return SCORE_INVALID_ARG;

  if (stringp(oldkey)) {
    oldkey = load_name(oldkey); 
    num=npcs[oldkey,NPC_NUMBER];
  }
  else if (intp(oldkey)) num=oldkey;
  else return SCORE_INVALID_ARG;

  if (!member(by_num,num)) return SCORE_INVALID_ARG;
  
  tip=getTipFromList(oldkey);
  oldpath = by_num[num, BYNUM_KEY];
  score = by_num[num, BYNUM_SCORE];

  if (member(npcs, oldpath)) {
    m_delete(npcs, oldpath);
    removeTip(oldkey);
    if(tip!="") addTip(newpath,tip);
    npcs[newpath, NPC_SCORE] = score;
    npcs[newpath, NPC_NUMBER] = num;
  }
  else return SCORE_INVALID_ARG;

  by_num += ([num: newpath; score]);

  ClearUsersEKCache();
  save_object(SCORESAVEFILE);
  write_file(SCORELOGFILE,sprintf("MOVESCORE: %s %s %s (%s, %O)\n",
  strftime("%d%m%Y-%T",time()),oldpath,newpath,
  geteuid(previous_object()),this_interactive()));

  while(remove_call_out("DumpNPCs") != -1) ;
  call_out("DumpNPCs",60);
  return 1;
}

// liefert alle Kills des Spielers zurueck, auch solche, die momentan
// ausgetragen/deaktiviet sind.
public string QueryAllKills(string pl)
{
  return (MASTER->query_ek(pl) || "");
}

// filtert alle Eintraege aus dem Bitstring heraus, die fuer
// ausgetragene/inaktive EKs stehen.
public string QueryKills(string pl) {
  string res = ({string})MASTER->query_ek(pl) || "";
  // vergleichen mit den aktiven EKs aus active_eks und nur jene Bits
  // zurueckliefern, die in beiden Strings gesetzt sind.
  return and_bits(res,active_eks);
}

public int QueryKillPoints(mixed pl) {
  
  if (!allowed() &&
      (!previous_object() 
       || strstr(object_name(previous_object()), "/gilden/") != 0) )
     return 0;

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

  if (member(users_ek,pl)) return users_ek[pl];

  string s = (MASTER->query_ek(pl) || "");
  
  int p=-1;
  int summe;
  while ((p=next_bit(s,p)) != -1) {
      summe+=by_num[p,BYNUM_SCORE];
  }

  users_ek += ([pl:summe]);
  return summe;
}

public mixed *QueryNPCbyNumber(int num)
{
  if (!allowed())
    return 0;

  if (member(by_num, num))
    return ({num, by_num[num, BYNUM_SCORE], by_num[num, BYNUM_KEY]});

  return 0;
}

protected mixed *StaticQueryNPCbyNumber(int num)
{
  if (member(by_num, num))
    return ({num, by_num[num, BYNUM_SCORE], by_num[num, BYNUM_KEY]});

  return 0;
}

public mixed *QueryNPCbyObject(object o)
{
  string key;
  int val;

  key=load_name(o);
  if (member(npcs,key)) {
    val = npcs[key,NPC_NUMBER];
    return ({val, by_num[val, BYNUM_SCORE], by_num[val, BYNUM_KEY]});
  }
  return 0;
}

public int GiveKill(object pl, int bit)
{
  mixed info;
  object po;
  int drin;
  string pls, ek;


  if (!pointerp(info = StaticQueryNPCbyNumber(bit)))
    return -1;

  if ((!po=previous_object()) 
      || load_name(po) != info[SCORE_KEY])
    return -2;

  pls=getuid(pl);

  // wenn unbestaetigt, Spieler fuer spaeter merken
  if (member(unconfirmed_scores, bit)) {
    if (member(unconfirmed_scores[bit], pls) == -1)
  unconfirmed_scores[bit] += ({pls});
  }
  else {
    // sonst wird das Bit direkt im Spieler gesetzt.
    ek = (MASTER->query_ek(pls) || "");
    if (test_bit(ek, bit))
      return -3;
    ek = set_bit(ek, bit);
    MASTER->update_ek(pls, ek);
    // Vergabestatistik hochzaehlen.
    npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]++;
  }

  if (member(users_ek, pls))
    m_delete(users_ek, pls);

  EK_GIVENLOG(sprintf("%s: %s", info[SCORE_KEY], pls)); 

  return info[SCORE_SCORE];
}

public int HasKill(mixed pl, mixed npc)
{
  string fn, *pls;

  if (!objectp(pl) && !stringp(pl) && 
      !objectp(npc) && !stringp(npc) && !intp(npc))
    return 0;
  if (!stringp(pl)) 
    pl=getuid(pl);

  if (intp(npc))
    npc=by_num[npc,BYNUM_KEY];
  fn=load_name(npc);

  if (!member(npcs, fn)) return 0;
  
  int bit = npcs[fn, NPC_NUMBER];
  
  if (pointerp(pls=unconfirmed_scores[bit]) &&
      member(pls,pl) != -1)
    return 1;

  string eks = (MASTER->query_ek(pl) || "");

  return test_bit(eks, bit);
}

private void WriteDumpFile(string *keys) {
  int maxn;

  if (!pointerp(keys)) return;

  rm(SCOREDUMPFILE);

  write_file(SCOREDUMPFILE,sprintf("%5s  %5s  %4s   %s\n",
  "Nr.", "Cnt", "Sc", "Objekt"));
  foreach(string key: keys) {
    write_file(SCOREDUMPFILE,sprintf("%5d  %5d  %4d   %O\n",
    npcs[key,NPC_NUMBER], npcs[key,NPC_COUNT],
    npcs[key,NPC_SCORE], key));
    maxn += npcs[key,NPC_SCORE];
  }
  write_file(SCOREDUMPFILE,sprintf(
  "========================================================\n"
  "NPCs gesamt: %d Punkte\n\n",maxn));
}

public varargs int DumpNPCs(int sortkey) {

  if (extern_call() && !allowed()) return SCORE_NO_PERMISSION;
  if (!intp(sortkey)) return SCORE_INVALID_ARG;

  rm(SCOREDUMPFILE);

  // sortieren
  string *keys=sort_array(m_indices(npcs), function int (string a, string b) {
        return(npcs[a,sortkey] < npcs[b,sortkey]); } );
  call_out(#'WriteDumpFile, 2, keys);

  return 1;
}

public int SetScoreBit(string pl, int bit)
{
  string ek;

  if (!allowed())
    return SCORE_NO_PERMISSION;

  ek = (MASTER->query_ek(pl) || "");
  ek = set_bit(ek, bit);
  MASTER->update_ek(pl, ek);

  // Vergabestatistik hochzaehlen.
  npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]++;

  if (member(users_ek, pl))
    m_delete(users_ek, pl);

  write_file(SCORELOGFILE,sprintf("SETBIT: %s %s %5d Sc: %.3d %s (%s, %O)\n",
         strftime("%d%m%Y-%T",time()),pl, bit,
         by_num[bit,BYNUM_SCORE], by_num[bit,BYNUM_KEY],
         geteuid(previous_object()), this_interactive()));
  return 1;
}

public int ClearScoreBit(string pl, int bit)
{
  string ek;

  if (!allowed())
    return SCORE_NO_PERMISSION;

  ek = (MASTER->query_ek(pl) || "");
  ek = clear_bit(ek, bit);
  MASTER->update_ek(pl, ek);

  // Vergabestatistik runterzaehlen.
  npcs[by_num[bit,BYNUM_KEY],NPC_COUNT]--;

  if (member(users_ek, pl))
    m_delete(users_ek, pl);

  write_file(SCORELOGFILE,sprintf(
  "CLEARBIT: %s %s %5d Sc: %.3d %s (%s, %O)\n",       
  strftime("%d%m%Y-%T",time()),pl,bit,
  by_num[bit,BYNUM_SCORE],by_num[bit,BYNUM_KEY],
  geteuid(previous_object()), this_interactive()));
  return 1;
}

private status ektipAllowed()
{ 
  status poOK;
  string poName;
  status ret;
                
  poName=load_name(previous_object());        
  poOK=previous_object() &&     
    ((previous_object()==find_object(EKTIPGIVER)) || (poName==EKTIPLIST) );

  ret=allowed() || 
    (this_player() && this_interactive() && previous_object() && 
     this_interactive()==this_player() && poOK);
  return ret;
}

// liefert alle EKs, die aktiv sind und die der Spieler noch nicht hat in
// einem Mapping entsprechend npcs zurueck.
public mapping getFreeEKsForPlayer(object player)
{
  if(!ektipAllowed() || !objectp(player) || !query_once_interactive(player)){
      return ([]);
  }
  // alle EKs, die der Spieler hat
  string eks = ({string})master()->query_ek(getuid(player));
  // als Tips kommen alle in Frage, die er nicht hat, vor dem Invertieren muss
  // aber sichergestellt werden, dass eks min. so lang ist wie active_eks, da
  // die Invertierung ja z.B. nur EKs 0-1700 beruecksichtigt, wenn 1700 der
  // hoechste EK im Spieler ist und dann als Tips alle EKs ueber
  // 1700 verlorengingen.
  // hier wird das letzte Bit von active_eks ermittelt und das darauf folgende
  // Bit im Spieler-EK-String gesetzt und wieder geloescht, woraufhin der
  // EK-String min. so lang wie active_eks ist. (es ist egal, wenn er
  // laenger ist, auch egal, wenn man ein Bit ueberschreibt, das faellt alles
  // gleich beim and_bits() raus.
  int lb = last_bit(active_eks) + 1;
  eks = clear_bit(set_bit(eks, lb), lb);
  // jetzt invertieren
  string non_eks = invert_bits(eks);
  // jetzt vorhande EK-Tips ausfiltern. Im Prinzip gleiches Spiel wie oben.
  string ektips = ({string})master()->query_ektips(getuid(player));
  // jetzt alle nicht als Tip vergebenen NPC ermitteln, vor dem Invertieren
  // wieder Laenge angleichen...
  ektips = invert_bits(clear_bit(set_bit(ektips, lb), lb));
  // verunden liefert EKs, die der Spieler nicht hat und nicht als Tip hat
  ektips = and_bits(ektips, non_eks);

  // und nun die inaktive EKs ausfiltern, nochmal verunden
  ektips = and_bits(ektips, active_eks);

  // mal Platz reservieren, entsprechend der Menge an Bits
  mapping freeKills = m_allocate( count_bits(ektips), 2);
  // durch alle jetzt gesetzten Bits laufen, d.h. alle EKs, die der Spieler
  // nicht hat und ein Mapping a la npcs erstellen.
  int p=-1;
  while ( (p=next_bit(ektips, p)) != -1) {
    freeKills += ([ by_num[p,0]: p; by_num[p,1] ]);
  }

  return freeKills;
}

public int addTip(mixed key,string tip)
{
  string fn;
  
  if (!allowed())
    return SCORE_NO_PERMISSION;

  if (!tip || (!objectp(key) && !stringp(key)))
    return SCORE_INVALID_ARG;

  fn=load_name(key);

  if (!member(npcs, fn)) return SCORE_INVALID_ARG;
  tipList+=([fn:tip]);
  save_object(SCORESAVEFILE);
    
  return 1;
}

public int changeTip(mixed key,string tip)
{
    return addTip(key,tip);
}

public int removeTip(mixed key)
{
  string fn;
  
  if (!allowed())
    return SCORE_NO_PERMISSION;
  
  if ((!objectp(key) && !stringp(key)))
    return SCORE_INVALID_ARG;

  fn=load_name(key);
  
  if (!member(tipList, fn)) return SCORE_INVALID_ARG;
    
  m_delete(tipList,fn);
  save_object(SCORESAVEFILE);
    
  return 1;  
}

private string getTipFromList(mixed key)
{
  string fn;
  
  if (!ektipAllowed())
    return "";
  
  if ((!objectp(key) && !stringp(key)))
    return "";

  fn=load_name(key);
  
  if (!member(tipList, fn)) return "";
        
  return tipList[fn];  
}

private string _getTip(mixed key)
{
  string fn;
  string tip;
  string* path;
    
  if ((!objectp(key) && !stringp(key)))
    return "";

  fn=load_name(key);
  
  if(!member(npcs,fn)) return "";
  
  tip=getTipFromList(fn);
  if(!tip || tip==""){
    path=explode(fn,"/")-({""});
    if(sizeof(path)<3) return "";
    if(path[0]=="players") {
      string tiptext;
      if ( path[1] == "ketos" )
        tiptext = "Ketos im Gebirge";
      else if ( path[1] == "boing" && path[2] == "friedhof" )
        tiptext = "Boing im eisigen Polar";
      else
        tiptext = capitalize(path[1]);
      return "Schau Dich doch mal bei "+tiptext+" um.";
    }
    
    if(path[0]=="d")
    {
      tip+="Schau Dich doch mal ";
    
      if(file_size("/players/"+path[2])==-2)
      {
        tip+="bei "+capitalize(path[2]+" ");
      }
      if ( path[1]=="polar" && file_size("/players/"+path[3])==-2 )
      {
        tip+="bei "+capitalize(path[3])+" ";
      }

      if(path[1]=="anfaenger")
        tip+="in den Anfaengergebieten ";
      if(path[1]=="fernwest")
        tip+="in Fernwest ";
      if(path[1]=="dschungel")
        tip+="im Dschungel ";
      if(path[1]=="schattenwelt")
        tip+="in der Welt der Schatten ";
      if(path[1]=="unterwelt")
        tip+="in der Unterwelt ";
      if(path[1]=="gebirge")
        tip+="im Gebirge ";
      if(path[1]=="seher")
        tip+="bei den Sehergebieten ";
      if(path[1]=="vland")
        tip+="auf dem Verlorenen Land ";
      if(path[1]=="ebene")
        tip+="in der Ebene ";
      if(path[1]=="inseln")
        tip+="auf den Inseln ";
      if(path[1]=="wald")
        tip+="im Wald ";
      if(path[1]=="erzmagier")
        tip+="bei den Erzmagiern ";
      if(path[1]=="polar")
      {
        if (path[2]=="files.chaos")
          tip+="in den Raeumen der Chaosgilde ";
        tip+="im eisigen Polar ";
      }
      if(path[1]=="wueste")
        tip+="in der Wueste ";
      tip+="um.";
    }
    else if ( path[0]=="gilden" )
    {
      tip+="Schau Dich doch mal";
      switch( path[1] )
      {
        case "mon.elementar": 
          tip+=" unter den Anfuehrern der Elementargilde"; 
          break;
        case "files.dunkelelfen":
          tip+=" unter den Anfuehrern der Dunkelelfengilde";
          break;
        case "files.klerus":
          tip+=" beim Klerus"; 
          break;
        case "files.werwoelfe": 
          tip+=" unter den Anfuehrern der Werwoelfe";
          break;
        case "files.chaos": 
          tip+=" unter den Anfuehrern der Chaosgilde";
          break;
        default: 
          tip+=" in einer der Gilden"; 
          break;
      }
      tip+=" um.";
    }
    else if ( path[0] == "p" ) 
    {
      tip+="Schau Dich doch mal ";
      switch( path[1] ) 
      {
        case "zauberer":
          tip+="in der Zauberergilde zu Taramis";
          break;
        case "kaempfer":
          tip+="bei den Angehoerigen des Koru-Tschakar-Struvs";
          break;
        case "katzenkrieger":
          tip+="bei der Gilde der Katzenkrieger";
          break;
        case "tanjian":
          tip+="unter den Meistern der Tanjiangilde";
          break;
      }
      tip+=" um.";
    }
  }
  return tip;
}

// return valid tips from database or existing 
public string getTip(mixed key)
{
  string fn;
  string tip;
  string* path;
  
  if (!ektipAllowed())
    return "";
  
  return _getTip(key);
}

// liefert ein Array mit allen Objekten zurueck, auf die bitstr verweist, also
// eine Liste aller Objekte, die als Tip vergeben wurden.
private string* makeTiplistFromBitString(string bitstr)
{ 
  string * ret= allocate(count_bits(bitstr));
  // ueber alle gesetzten bits laufen und Array zusammensammeln
  int i;
  int p=-1;
  while ((p=next_bit(bitstr,p)) != -1) {
    ret[i] = by_num[p, 0];
    i++;
  }
  // zur Sicherheit
  ret -= ({0});

  return ret;
}

// gibt die Objektnamen der EK-Tips vom jeweiligen Spieler zurueck.
public string *QueryTipObjects(mixed player) {
  
  if (extern_call() && !allowed())
      return 0;
  if (objectp(player) && query_once_interactive(player))
      player=getuid(player);
  if (!stringp(player))
    return 0;

  string tipstr = ({string})master()->query_ektips(player);
  // jetzt EK-Tips ausfiltern, die erledigt sind. Dazu EK-Liste holen...
  string eks = ({string})master()->query_ek(player);
  // als Tips kommen alle in Frage, die er nicht hat, vor dem Invertieren muss
  // aber sichergestellt werden, dass eks min. so lang ist wie tipstr, da
  // die Invertierung ja z.B. nur EKs 0-1700 beruecksichtigt, wenn 1700 der
  // hoechste EK im Spieler ist und dann alle Tips ueber
  // 1700 verlorengingen.
  // hier wird das letzte Bit von tipstr ermittelt und das darauf folgende
  // Bit im Spieler-EK-String gesetzt und wieder geloescht, woraufhin der
  // EK-String min. so lang wie der Tipstring ist. (es ist egal, wenn er
  // laenger ist, auch egal, wenn man ein Bit ueberschreibt, das faellt alles
  // gleich beim and_bits() raus.
  int lb = last_bit(tipstr) + 1;
  eks = clear_bit(set_bit(eks, lb), lb);
  // jetzt invertieren
  string non_eks = invert_bits(eks);
  // jetzt verunden und man hat die Tips, die noch nicht gehauen wurden.
  tipstr = and_bits(tipstr, non_eks);
  // noch inaktive EKs ausfiltern...
  tipstr = and_bits(tipstr, active_eks);

  return makeTiplistFromBitString(tipstr);
}

public string allTipsForPlayer(object player)
{

  if(!player || !this_interactive() || 
      (this_interactive()!=player && !IS_ARCH(this_interactive())) )
    return "";    
 
  string *tips = QueryTipObjects(player);

  tips = map(tips, #'_getTip);
  tips -= ({0,""});

  return implode(tips, "\n");
}

public status playerMayGetTip(object player)
{
  int numElegible;
  int numReceived;
  int lvl;
  int i;
  string tips;
  
  if(!ektipAllowed() || !player || !query_once_interactive(player))      
      return 0;

  if(!player || !query_once_interactive(player))    
      return 0;
  
  lvl = ({int})player->QueryProp(P_LEVEL);
  numElegible=0;
  i=sizeof(EKTIPS_LEVEL_LIMITS)-1;

  if(lvl>EKTIPS_LEVEL_LIMITS[i])    
      numElegible+=(lvl-EKTIPS_LEVEL_LIMITS[i]);

  for(i;i>=0;i--){
      if(lvl>=EKTIPS_LEVEL_LIMITS[i]) numElegible++;
  }

  tips = ({string})MASTER->query_ektips(getuid(player)) || "";
  // inaktive EKs ausfiltern.
  tips = and_bits(tips, active_eks);
  // und Gesamtzahl an Tips zaehlen. Hier werden erledigte Tips explizit nicht
  // ausgefiltert!
  numReceived=count_bits(tips);

  return numElegible>numReceived;
}

public string giveTipForPlayer(object player)
{
  string* tmp;
  mapping free;
  string tip,pl,ektip;
  int index;
  
  if(!ektipAllowed() || !player || 
      !query_once_interactive(player) || !playerMayGetTip(player))  
    return "";
  
  pl=getuid(player);
  free=getFreeEKsForPlayer(player);

  if(!mappingp(free) || sizeof(free)==0)
    return "";

  tmp=m_indices(free);

  ektip = ({string})MASTER->query_ektips(pl) || "";
 
  foreach(int i: EKTIPS_MAX_RETRY) {
      index=random(sizeof(tmp));
      tip=getTip(tmp[index]);
      if (stringp(tip) && sizeof(tip)) {
    ektip=set_bit(ektip,npcs[tmp[index],NPC_NUMBER]);
    MASTER->update_ektips(pl,ektip);
    break; //fertig
      }
  }

  return tip;  
}

// checkt NPCs auf Existenz und Ladbarkeit
public void CheckNPCs(int num) {
  string fn;
  object ekob;
  if (!num) rm(SCORECHECKFILE);
  while (num <= lastNum && get_eval_cost() > 1480000) {
    if (!by_num[num,1] || !by_num[num,0]) {
      num++;
      continue;
    }
    fn = by_num[num,0] + ".c";
    if (file_size(fn) <= 0) {
      // File nicht existent
      write_file(SCORECHECKFILE, sprintf(
    "EK %.4d ist nicht existent (%s)\n",num,fn));
    }
    else if (catch(ekob=load_object(fn)) || !objectp(ekob) ) {
      // NPC offenbar nicht ladbar.
      write_file(SCORECHECKFILE, sprintf(
    "EK %.4d ist nicht ladbar (%s)\n",num,fn));
    }
    num++;
  }
  ZDEBUG(sprintf("%d NPC checked",num));
  if (num <= lastNum)
    call_out(#'CheckNPCs,4,num);
  else
    ZDEBUG("Finished!");
}

// liquidiert einen EK endgueltig. An diesem Punkt wird davon augegangen, dass
// kein Spieler den EK mehr gesetzt hat!
private void LiquidateEK(int bit) {

  if (!intp(bit) || bit < 0) return;

  string obname = by_num[bit, BYNUM_KEY];
  int score = by_num[bit, BYNUM_SCORE];

  if (member(npcs, obname) && (npcs[obname, NPC_NUMBER] == bit)) {
    m_delete(by_num, bit);
    m_delete(npcs, obname);
    if (member(unconfirmed_scores,bit))
      m_delete(unconfirmed_scores,bit);
    active_eks = clear_bit(active_eks,bit);
    removeTip(obname);
    free_num += ({bit});
    write_file(SCOREAUTOLOG,sprintf(
    "LIQUIDATEEK: %s %5d Score %3d %s\n",
    strftime("%d%m%Y-%T",time()), bit, score, obname));
  }
}

private void check_player(string pl) {
  int changed, changed2; 
  
  // EKs pruefen
  string eks = ({string})master()->query_ek(pl) || "";
  string *opfer=allocate( (sizeof(eks)*6)+1, "");
  int p=-1;
  while ((p=next_bit(eks,p)) != -1) {
    if (!member(by_num, p)) {
  write_file(SCORECHECKFILE, sprintf(
   "UNKNOWNEK %s %5d in %s gefunden.\n", 
    strftime("%d%m%Y-%T",time()), p, pl));
    }
    // wenn das aktuelle Bit geloescht werden soll, also in to_be_removed
    // steht...
    if (member(to_be_removed,p) != -1) {
  eks = clear_bit(eks,p);
  changed=1;
  write_file(EKCLEANLOG,sprintf(
        "CLEARBIT: %s %O %5d %s\n",
        strftime("%d%m%Y-%T",time()), pl, p, 
        by_num[p,BYNUM_KEY] || "NoName"));
    }
    else {
      // sonst statistikpflege
      npcs[by_num[p,BYNUM_KEY],NPC_COUNT]++;
      // loggen, welche NPC der Spieler hat
      opfer[p]=to_string(p);
    }
  }
  // und noch die Ek-Tips...
  string ektips = ({string})master()->query_ektips(pl) || "";
  p = -1;
  while ((p=next_bit(ektips,p)) != -1) {
    if (!member(by_num, p)) {
  write_file(EKCLEANLOG, sprintf(
    "UNKNOWNEK %s %5d in %s (EKTips) gefunden - clearing.\n", 
    strftime("%d%m%Y-%T",time()), p, pl));
  ektips = clear_bit(ektips, p); // hier direkt loeschen.
  changed2 = 1;
    }
    // wenn das aktuelle Bit geloescht werden soll, also in to_be_removed
    // steht...
    else if (member(to_be_removed,p) != -1) {
  ektips = clear_bit(ektips,p);
  changed2=1;
  write_file(EKCLEANLOG,sprintf(
        "CLEAREKTIP: %s %O %5d %s\n",
        strftime("%d%m%Y-%T",time()), pl, p, 
        by_num[p,BYNUM_KEY] || "NoName"));
    }
  }

  if (changed) {
      master()->update_ek(pl, eks);
  }
  if (changed2) {
      master()->update_ektips(pl, ektips);
  }
  opfer-=({""});
  write_file(WERKILLTWEN,sprintf("%s\n%=-78s\n\n",pl,CountUp(opfer)||""));
}

public void check_all_player(mapping allplayer) {
 
  if (extern_call() && !allowed())
      return;

  if (!mappingp(allplayer)) {
      foreach(string key: npcs) {
        npcs[key,NPC_COUNT]=0;
      }
      allplayer = ({mapping})master()->get_all_players();
      rm(WERKILLTWEN);
      call_out(#'check_all_player,2,allplayer);
      return;
  }

  // offenbar fertig mit allen Spielern, jetzt noch den Rest erledigen.
  if (!sizeof(allplayer)) {
    foreach(int bit: to_be_removed) {
      LiquidateEK(bit);
    }
    to_be_removed=({});
    save_object(SCORESAVEFILE); 
    ZDEBUG("Spielerchecks und EK-Liquidation fertig.\n");
    return;
  }

  string dir=m_indices(allplayer)[0];
  string *pls=allplayer[dir];
  foreach(string pl: pls) {
    if (get_eval_cost() < 1250000)
      break; // spaeter weitermachen.
    catch(check_player(pl) ; publish);
    pls-=({pl});
  }
  allplayer[dir] = pls; 
 
  if (!sizeof(allplayer[dir]))
    m_delete(allplayer,dir);
 
  call_out(#'check_all_player,2,allplayer);
}

