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

